{
  "$schema": "./jsontronRulesSchema.json",
  "schema": {
    "title": "Merged Input Rules",
    "id": "mergedInputRules",
    "schemaVersion": "1.0",
    "queryBinding": "jsonpath",
    "defaultPhase": "default",
    "phase": [
      {
        "id": "default",
        "active": [
          "UniqueIdCheck",
          "IdReferenceCheck"
        ]
      }
    ],
    "pattern": [
      {
        "id": "UniqueIdCheck",
        "title": "Unique Id Check",
        "abstract": false,
        "rule": [
          {
            "id": "UniqueIdCheck_R1",
            "context": "$",
            "assert": [
              {
                "id": "UniqueIdCheck_R1_A1",
                "test": "jp.query(contextNode, '$..sets.*.id').length == new Set(jp.query(contextNode, '$..sets.*.id')).size",
                "message": "Global: The id of a set must be unique."
              },
              {
                "id": "UniqueIdCheck_R1_A2",
                "test": "jp.query(contextNode, '$..globalVariables.*.id').length == new Set(jp.query(contextNode, '$..globalVariables.*.id')).size",
                "message": "Global: The id of a global variable must be unique."
              },
              {
                "id": "UniqueIdCheck_R1_A3",
                "test": "jp.query(contextNode, '$..interventions.*.id').length == new Set(jp.query(contextNode, '$..interventions.*.id')).size",
                "message": "Global: The id of an intervention must be unique."
              },
              {
                "id": "UniqueIdCheck_R1_A1",
                "test": "jp.query(contextNode, '$..traits.*.id').length == new Set(jp.query(contextNode, '$..traits.*.id')).size",
                "message": "Global: The id of a trait must be unique."
              }
            ]
          },
          {
            "id": "UniqueIdCheck_R2",
            "context": "$..traits.*",
            "assert": [
              {
                "id": "UniqueIdCheck_R2_A1",
                "test": "jp.query(contextNode, '$..features.*.id').length == new Set(jp.query(contextNode, '$..features.*.id')).size",
                "message": "'Trait [' + jp.query(contextNode, '$.*.id') + ']: The id of a feature must be unique.'"
              }
            ]
          },
          {
            "id": "UniqueIdCheck_R3",
            "context": "$..features.*",
            "assert": [
              {
                "id": "UniqueIdCheck_R3_A1",
                "test": "jp.query(contextNode, '$..enums.*.id').length == new Set(jp.query(contextNode, '$..enums.*.id')).size",
                "message": "'Feature [' + jp.query(contextNode, '$.*.id') + ']: The id of an enum must be unique.'"
              }
            ]
          },
          {
            "id": "UniqueIdCheck_R4",
            "context": "$..diseaseModel",
            "assert": [
              {
                "id": "UniqueIdCheck_R4_A1",
                "test": "jp.query(contextNode, '$..states.*.id').length == new Set(jp.query(contextNode, '$..states.*.id')).size",
                "message": "Disease Model: The id of a state must be unique."
              },
              {
                "id": "UniqueIdCheck_R4_A2",
                "test": "jp.query(contextNode, '$..transmissions.*.id').length == new Set(jp.query(contextNode, '$..transmissions.*.id')).size",
                "message": "Disease Model: The id of a transmission must be unique."
              },
              {
                "id": "UniqueIdCheck_R4_A3",
                "test": "jp.query(contextNode, '$..transitions.*.id').length == new Set(jp.query(contextNode, '$..transitions.*.id')).size",
                "message": "Disease Model: The id of a transition must be unique."
              }
            ]
          }
        ]
      },
      {
        "id": "IdReferenceCheck",
        "title": "Check whether all referenced id are defined.",
        "abstract": false,
        "rule": [
          {
            "id": "IdReferenceCheck_R1",
            "context": "$..features.*",
            "assert": [
              {
                "id": "IdReferenceCheck_R1_A1",
                "test": "jp.query(contextNode, '$..enums.*.id').includes(jp.query(contextNode, '$.*.default')[0])",
                "message": "'Feature [' + jp.query(contextNode, '$.*.id') + ']: The default ' + jp.query(contextNode, '$.*.default')[0] + ' is not defined.'"
              }
            ]
          },
          {
            "id": "IdReferenceCheck_R2",
            "context": "$..diseaseModel",
            "assert": [
              {
                "id": "IdReferenceCheck_R2_A1",
                "test": "jp.query(contextNode, '$..states.*.id').includes(jp.query(contextNode, '$.*.initialState')[0])",
                "message": "'Initial State: The state id ' + jp.query(contextNode, '$.*.initialState') + ' is not defined.'"
              }
            ]
          },
          {
            "id": "IdReferenceCheck_R3",
            "context": "$..diseaseModel.transmissions.*",
            "assert": [
              {
                "id": "IdReferenceCheck_R3_A1",
                "test": "jp.query(documentRoot, '$..diseaseModel.states.*.id').includes(jp.query(contextNode, '$.*.entryState')[0])",
                "message": "'Infection[' + jp.query(contextNode, '$.*.id') + ']: The entry state id ' + jp.query(contextNode, '$.*.entryState')[0] + ' is not defined.'"
              },
              {
                "id": "IdReferenceCheck_R3_A2",
                "test": "jp.query(documentRoot, '$..diseaseModel.states.*.id').includes(jp.query(contextNode, '$.*.exitState')[0])",
                "message": "'Infection[' + jp.query(contextNode, '$.*.id') + ']: The exit state id ' + jp.query(contextNode, '$.*.exitState')[0] + ' is not defined.'"
              },
              {
                "id": "IdReferenceCheck_R3_A3",
                "test": "jp.query(documentRoot, '$..diseaseModel.states.*.id').includes(jp.query(contextNode, '$.*.contactState')[0])",
                "message": "'Infection[' + jp.query(contextNode, '$.*.id') + ']: The contact state id ' + jp.query(contextNode, '$.*.contactState')[0] + ' is not defined.'"
              }
            ]
          },
          {
            "id": "IdReferenceCheck_R4",
            "context": "$..diseaseModel.transitions.*",
            "assert": [
              {
                "id": "IdReferenceCheck_R4_A1",
                "test": "jp.query(documentRoot, '$..diseaseModel.states.*.id').includes(jp.query(contextNode, '$.*.entryState')[0])",
                "message": "'Transition[' + jp.query(contextNode, '$.*.id') + ']: The entry state id ' + jp.query(contextNode, '$.*.entryState')[0] + ' is not defined.'"
              },
              {
                "id": "IdReferenceCheck_R4_A2",
                "test": "jp.query(documentRoot, '$..diseaseModel.states.*.id').includes(jp.query(contextNode, '$.*.exitState')[0])",
                "message": "'Transition[' + jp.query(contextNode, '$.*.id') + ']: The exit state id ' + jp.query(contextNode, '$.*.exitState')[0] + ' is not defined.'"
              }
            ]
          },
          {
            "id": "IdReferenceCheck_R5",
            "context": "$..triggers.*.interventionIds.*",
            "assert": [
              {
                "id": "IdReferenceCheck_R5_A1",
                "test": "jp.query(documentRoot, '$..interventions.*.id').includes(contextNode[0])",
                "message": "'Trigger interventionId: The intervention id ' + contextNode[0] + ' is not defined.'"
              }
            ]
          }
        ]
      }
    ]
  }
}