fhircat / fhir-rdf-playground

JSON for Linked Data
https://json-ld.org/
Other
0 stars 4 forks source link

rdf:Collection of value set constraint b0rked #7

Closed ericprud closed 2 years ago

ericprud commented 2 years ago

Works with max card of 1 (i.e. not an rdf:Collection), e.g. Observation.status:

Name Flags Card. Type Description & Constraints
Observation N   DomainResource Measurements and simple assertions
... status ?!Σ 1..1 code registered | preliminary | final | amended +
ObservationStatus (Required)
... category 0..* CodeableConcept Classification of type of observation
Observation Category Codes (Preferred)

ShEx-ified as:

  { "type": "Shape",
    "id": "http://hl7.org/fhir/shape/Observation",
    "closed": true,
    "expression": {
      "type": "EachOf",
      "expressions": [
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/status",
          "valueExpr": {
            "type": "ShapeAnd",
            "shapeExprs": [
              "http://hl7.org/fhir/shape/code", # conforms to code shape
              { "type": "Shape",
                "expression": {
                  "type": "TripleConstraint",   # and code's value is in observation-status
                  "predicate": "http://hl7.org/fhir/value",
                  "valueExpr": "http://hl7.org/fhir/ValueSet/observation-status"
              } }
            ]
        } },
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/category",
          "min": 0, "max": -1, # Collection of CodeableConcepts with no value set
          "valueExpr": "http://hl7.org/fhir/shape/OneOrMore_CodeableConcept",
        }
      ]
  } },
  { "type": "Shape", # formulaic Collection shape typed for CodeableConcepts.
    "id": "http://hl7.org/fhir/shape/OneOrMore_CodeableConcept",
    "closed": true,
    "expression": {
      "type": "EachOf",
      "expressions": [
        { "type": "TripleConstraint",
          "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#first",
          "valueExpr": "http://hl7.org/fhir/shape/CodeableConcept"
        },
        { "type": "TripleConstraint",
          "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest",
          "valueExpr": {
            "type": "ShapeOr",
            "shapeExprs": [
              { "type": "NodeConstraint",
                "values": [ "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil" ]
              },
              "http://hl7.org/fhir/shape/OneOrMore_CodeableConcept"
            ]
        } }
      ]
  } }

(Note that 0..* is expressed as a an optional property with a value of a non-empty list. I don't know if "category" [] is allowed in JSON-land or its analog in XML-land.)

CodeSystem.filter.operator has both a value constraint and a max card > 0:

Name Flags Card. Type Description & Constraints
CodeSystem N   CanonicalResource Declares the existence of and describes a code system or code system supplement
... filter Σ 0..* BackboneElement Filter that can be used in a value set
.... operator Σ 1..* code = | is-a | descendent-of | is-not-a | regex | in | not-in | generalizes | child-of | descendent-leaf | exists
FilterOperator (Required)
  { "type": "Shape",
    "id": "http://hl7.org/fhir/shape/CodeSystem.filter",
    "closed": true,
    "expression": {
      "type": "EachOf",
      "expressions": [
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/extension", "min": 0, "max": -1,
          "valueExpr": "http://hl7.org/fhir/shape/OneOrMore_Extension"
        },
        …
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/operator", "min": 1, "max": -1,
          "valueExpr": {
            "type": "ShapeAnd",
            "shapeExprs": [
              "http://hl7.org/fhir/shape/OneOrMore_code", # Bug: constrains Collection structure, not contained rdf:firsts
              { "type": "Shape",
                "expression": {
                  "type": "TripleConstraint",
                  "predicate": "http://hl7.org/fhir/value",
                  "valueExpr": "http://hl7.org/fhir/ValueSet/filter-operator"
              } }
            ]
        } },
        …
      ]
  } }
ericprud commented 2 years ago

Goal structure moves AND filter-operator into rdf:first:

  { "type": "Shape",
    "id": "http://hl7.org/fhir/shape/CodeSystem.filter",
    "closed": true,
    "expression": {
      "type": "EachOf",
      "expressions": [
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/extension", "min": 0, "max": -1,
          "valueExpr": "http://hl7.org/fhir/shape/OneOrMore_Extension"
        },
        …
        { "type": "TripleConstraint",
          "predicate": "http://hl7.org/fhir/operator", "min": 1, "max": -1,
          "valueExpr": "http://hl7.org/fhir/shape/OneOrMore_code_filter-operator"
        },
        …
      ]
  } },
  { "type": "Shape", # formulaic Collection shape typed for codes in filter-operator.
    "id": "http://hl7.org/fhir/shape/OneOrMore_code_filter-operator",
    "closed": true,
    "expression": {
      "type": "EachOf",
      "expressions": [
        { "type": "TripleConstraint",
          "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#first",
          "valueExpr": {
            "type": "ShapeAnd",
            "shapeExprs": [
              "http://hl7.org/fhir/shape/code", # conforms to code shape
              { "type": "Shape",
                "expression": { # and code's value is in observation-status
                  "type": "TripleConstraint",
                  "predicate": "http://hl7.org/fhir/value",
                  "valueExpr": "http://hl7.org/fhir/ValueSet/filter-operator"
              } }
            ]
          }
        },
        { "type": "TripleConstraint",
          "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest",
          "valueExpr": {
            "type": "ShapeOr",
            "shapeExprs": [
              { "type": "NodeConstraint",
                "values": [ "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil" ]
              },
              "http://hl7.org/fhir/shape/OneOrMore_code_filter-operator"
            ]
        } }
      ]
  } } 
ericprud commented 2 years ago

relevant structureDefs:

per

                  if (elt.max !== "1" && elt.binding && elt.binding.strength === 'required')
                    console.log(elt.id);
ericprud commented 2 years ago

fixed with https://github.com/fhircat/fhir-rdf-playground/commit/f721f38509649d3e9f7a3b1720cb71b08d6d2a23