{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Fuzzy Cognitive Map",
  "description": "Source-faithful profile of a deterministic fuzzy cognitive map as serialised by FuzzyCognitiveMapTools.jl: a signed weighted digraph of concepts together with the activation specification that governs its iterative update. The activation specification is part of the map, not of the run that consumes it, so a map is a self-contained digital-twin input.\nTwo interchangeable representations of the same map are accepted, and exactly one must be present. `graph` is the upstream edge-list form. `matrix` is the n x n adjacency form used by the wider FCM tool ecosystem (FCMpy, Mental Modeler, FCMapper); it is lossless against the edge list only because the node ordering is declared explicitly rather than implied.\n",
  "type": "object",
  "required": [
    "activation_spec"
  ],
  "oneOf": [
    {
      "required": [
        "graph"
      ],
      "not": {
        "required": [
          "matrix"
        ]
      }
    },
    {
      "required": [
        "matrix"
      ],
      "not": {
        "required": [
          "graph"
        ]
      }
    }
  ],
  "properties": {
    "graph": {
      "$ref": "#/$defs/ConceptGraph",
      "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/hasGraph"
    },
    "matrix": {
      "$ref": "#/$defs/WeightMatrix"
    },
    "activation_spec": {
      "$ref": "#/$defs/ActivationSpec",
      "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/hasActivationSpec",
      "x-jsonld-extra-terms": {
        "label": {
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/activationFunction",
          "x-jsonld-type": "@vocab"
        },
        "logistic": "https://w3id.org/ogc/hosted/seadots/fcm/activation/logistic",
        "gaussian": "https://w3id.org/ogc/hosted/seadots/fcm/activation/logistic-of-square",
        "other": "https://w3id.org/ogc/hosted/seadots/fcm/activation/offset",
        "tanh": "https://w3id.org/ogc/hosted/seadots/fcm/activation/hyperbolic-tangent",
        "bivalent": "https://w3id.org/ogc/hosted/seadots/fcm/activation/bivalent",
        "trivalent": "https://w3id.org/ogc/hosted/seadots/fcm/activation/trivalent"
      }
    },
    "metadata": {
      "$ref": "#/$defs/MapMetadata",
      "x-jsonld-id": "@nest"
    }
  },
  "additionalProperties": false,
  "$defs": {
    "MapMetadata": {
      "type": "object",
      "description": "Map-level metadata. A placeholder upstream, where only `description` is defined; discovery metadata belongs in the accompanying catalog record, not here.\n",
      "properties": {
        "description": {
          "type": "string",
          "x-jsonld-id": "http://purl.org/dc/terms/description"
        }
      },
      "additionalProperties": true
    },
    "VertexMetadata": {
      "type": "object",
      "description": "Vertex-level metadata.",
      "properties": {
        "description": {
          "type": "string",
          "description": "Human-readable name of the concept, conventionally prefixed with the node key in square brackets, e.g. \"[C2] Stress Level\". Despite the field name this is a label rather than a description, and is mapped to skos:prefLabel.\n",
          "x-jsonld-id": "http://purl.org/dc/terms/description"
        }
      },
      "additionalProperties": true
    },
    "EdgeMetadata": {
      "type": "object",
      "description": "Edge-level metadata.",
      "properties": {
        "description": {
          "type": "string",
          "description": "Free-text statement of the causal claim the edge encodes.",
          "x-jsonld-id": "http://purl.org/dc/terms/description"
        },
        "provenance": {
          "type": "string",
          "description": "Free-text statement of where the weight came from. Marked as temporary upstream; expected to become a structured reference to the elicitation record (see description.md).\n"
        }
      },
      "additionalProperties": true
    },
    "GraphMetadata": {
      "type": "object",
      "description": "Graph-level metadata.",
      "properties": {
        "description": {
          "type": "string",
          "x-jsonld-id": "http://purl.org/dc/terms/description"
        }
      },
      "additionalProperties": true
    },
    "Vertex": {
      "type": "object",
      "description": "One concept of the map.",
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "description": "Graph-local key of the concept, unique within the map, e.g. \"C1\" or \"Nd\". Referenced by the `src` and `dst` fields of edges. Not an IRI; the concept IRI, when known, belongs in the catalog record or in a future `concept` field (see description.md).\n",
          "x-jsonld-id": "@id"
        },
        "metadata": {
          "$ref": "#/$defs/VertexMetadata",
          "x-jsonld-id": "@nest"
        }
      },
      "additionalProperties": false
    },
    "Edge": {
      "type": "object",
      "description": "One directed, weighted causal influence between two concepts.",
      "required": [
        "src",
        "dst",
        "weight"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Optional graph-local key of the edge, conventionally \"SRC->DST\".",
          "x-jsonld-id": "@id"
        },
        "src": {
          "type": "string",
          "minLength": 1,
          "description": "Key of the driving concept. Must equal the `id` of a vertex of the same map."
        },
        "dst": {
          "type": "string",
          "minLength": 1,
          "description": "Key of the influenced concept. Must equal the `id` of a vertex of the same map."
        },
        "weight": {
          "type": "number",
          "description": "Signed strength of the influence. Conventionally dimensionless in [-1, 1]; the convention is documented but NOT enforced upstream, and is not enforced here either. See description.md.\n"
        },
        "metadata": {
          "$ref": "#/$defs/EdgeMetadata",
          "x-jsonld-id": "@nest"
        }
      },
      "additionalProperties": false
    },
    "ConceptGraph": {
      "type": "object",
      "description": "Edge-list representation. The upstream validator additionally requires that every `src`/`dst` resolves to a vertex of the same graph and that no vertex is left unconnected; neither is expressible in JSON Schema across sibling arrays and both are carried as SHACL constraints by ogc.hosted.seadots.fcm-ontology.\n",
      "required": [
        "vertices",
        "edges"
      ],
      "properties": {
        "vertices": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/$defs/Vertex"
          },
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/hasNode",
          "x-jsonld-container": "@set"
        },
        "edges": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/Edge"
          },
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/hasEdge",
          "x-jsonld-container": "@set"
        },
        "metadata": {
          "$ref": "#/$defs/GraphMetadata",
          "x-jsonld-id": "@nest"
        }
      },
      "additionalProperties": false
    },
    "WeightMatrix": {
      "type": "object",
      "description": "Adjacency representation. `nodes` declares the ordering that both axes of `weights` follow, so the matrix is self-describing rather than depending on the order of an external vertex list.\n",
      "required": [
        "nodes",
        "weights",
        "orientation"
      ],
      "properties": {
        "nodes": {
          "type": "array",
          "minItems": 2,
          "description": "Node keys, in the order used by both axes of `weights`.",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "nodeLabels": {
          "type": "object",
          "description": "Optional map from node key to human-readable label.",
          "additionalProperties": {
            "type": "string"
          }
        },
        "orientation": {
          "const": "source-major",
          "description": "Declares that weights[i][j] is the influence of nodes[i] ON nodes[j]. Stated as a required constant rather than assumed, because the opposite convention is equally common and silently transposes the entire model. The solver applies the transpose at iteration time, computing f(W' x).\n"
        },
        "weights": {
          "type": "array",
          "minItems": 2,
          "description": "Square matrix of signed weights; absent influences are 0.",
          "items": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "number"
            }
          }
        }
      },
      "additionalProperties": false
    },
    "ActivationFunctionSpec": {
      "type": "object",
      "description": "One activation (transfer) function together with its numeric parameters. `label` is the discriminator.\n",
      "required": [
        "label",
        "params"
      ],
      "properties": {
        "label": {
          "type": "string",
          "description": "Function name as serialised upstream. Values are resolved to concepts of ogc.hosted.seadots.fcm-activation-scheme by context.jsonld. Note that the upstream label \"gaussian\" resolves to fcmact:logistic-of-square, which is what the implementation computes; see that block's description.\n",
          "examples": [
            "logistic",
            "gaussian",
            "other"
          ]
        },
        "params": {
          "type": "object",
          "description": "Numeric parameters keyed by name. Which names are meaningful depends on `label` and is declared by fcmact:hasParameterName on the corresponding concept (`a`, `b`, `lambda` for the implemented functions).\n",
          "additionalProperties": {
            "type": "number"
          }
        }
      },
      "additionalProperties": false
    },
    "ActivationSpec": {
      "type": "object",
      "description": "Whether one activation function governs the whole map or one per concept. In heterogeneous mode the array is positional: element k applies to vertex k of `graph.vertices`, or to `matrix.nodes[k]`.\n",
      "required": [
        "mode"
      ],
      "properties": {
        "mode": {
          "enum": [
            "homogeneous",
            "heterogeneous"
          ],
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/activationMode",
          "x-jsonld-type": "@vocab"
        },
        "homogeneous": {
          "$ref": "#/$defs/ActivationFunctionSpec",
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/homogeneousActivation"
        },
        "heterogeneous": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/ActivationFunctionSpec"
          },
          "x-jsonld-id": "https://w3id.org/ogc/hosted/seadots/fcm/heterogeneousActivation",
          "x-jsonld-container": "@list"
        }
      },
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "mode": {
                "const": "homogeneous"
              }
            },
            "required": [
              "mode"
            ]
          },
          "then": {
            "required": [
              "homogeneous"
            ],
            "not": {
              "required": [
                "heterogeneous"
              ]
            }
          }
        },
        {
          "if": {
            "properties": {
              "mode": {
                "const": "heterogeneous"
              }
            },
            "required": [
              "mode"
            ]
          },
          "then": {
            "required": [
              "heterogeneous"
            ],
            "not": {
              "required": [
                "homogeneous"
              ]
            }
          }
        }
      ]
    }
  },
  "x-jsonld-extra-terms": {
    "id": "@id",
    "type": "@type"
  },
  "x-jsonld-prefixes": {
    "fcm": "https://w3id.org/ogc/hosted/seadots/fcm/",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "qudt": "http://qudt.org/schema/qudt/",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "prov": "http://www.w3.org/ns/prov#",
    "dct": "http://purl.org/dc/terms/",
    "fcmact": "https://w3id.org/ogc/hosted/seadots/fcm/activation/",
    "prop-rel": "https://w3id.org/ogc/hosted/seadots/prop-rel/"
  }
}