From d2bfc6409da03d024cfa0de727e532fb3737730e Mon Sep 17 00:00:00 2001 From: Gabe Fierro Date: Sun, 21 Jan 2024 15:24:26 -0700 Subject: [PATCH] update 223p.ttl --- ontologies/223p.ttl | 578 ++++++++++++++++++++++---------------------- 1 file changed, 288 insertions(+), 290 deletions(-) diff --git a/ontologies/223p.ttl b/ontologies/223p.ttl index b464743..565e0a7 100644 --- a/ontologies/223p.ttl +++ b/ontologies/223p.ttl @@ -311,11 +311,7 @@ s223:DifferentialSensor a s223:Class, rdfs:label "Differential sensor" ; rdfs:comment "A sensor that measures the difference of a quantity between any two points in the system." ; rdfs:subClassOf s223:AbstractSensor ; - sh:property [ rdfs:comment "A Differential Sensor must be defined in terms of the QuantityKind that is being measured." ; - sh:class qudt:QuantityKind ; - sh:minCount 1 ; - sh:path ( s223:observes qudt:hasQuantityKind ) ], - [ rdfs:comment "A Differential Sensor must have different values for hasObservationLocationHigh and hasObservationLocationLow." ; + sh:property [ rdfs:comment "A Differential Sensor must have different values for hasObservationLocationHigh and hasObservationLocationLow." ; sh:path s223:hasObservationLocationHigh ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "Ensure that the values of hasObservationLocationHigh and hasObservationLocationLow are distinct." ; @@ -328,7 +324,11 @@ WHERE { $this s223:hasObservationLocationLow ?low . FILTER (?high = ?low) . } -""" ] ] ; +""" ] ], + [ rdfs:comment "A Differential Sensor must be defined in terms of the QuantityKind that is being measured." ; + sh:class qudt:QuantityKind ; + sh:minCount 1 ; + sh:path ( s223:observes qudt:hasQuantityKind ) ] ; sh:xone ( [ sh:property [ rdfs:comment "A DifferentialSensor must be associated with exactly 1 of Connectable, Connection, or ConnectionPoint using the relation hasObservationLocationHigh." ; sh:class s223:Connectable ; sh:maxCount 1 ; @@ -546,17 +546,7 @@ s223:Filter a s223:Class, rdfs:label "Filter" ; rdfs:comment "A device that removes contaminants from gases or liquids." ; rdfs:subClassOf s223:Equipment ; - sh:property [ rdfs:comment "A Filter shall have at least one inlet." ; - sh:minCount 1 ; - sh:path s223:hasConnectionPoint ; - sh:qualifiedMinCount 1 ; - sh:qualifiedValueShape [ sh:class s223:InletConnectionPoint ] ], - [ rdfs:comment "A Filter shall have at least one outlet." ; - sh:minCount 1 ; - sh:path s223:hasConnectionPoint ; - sh:qualifiedMinCount 1 ; - sh:qualifiedValueShape [ sh:class s223:OutletConnectionPoint ] ], - [ rdfs:comment "A filter should have one common constituent between the inlet and outlet" ; + sh:property [ rdfs:comment "A filter should have one common constituent between the inlet and outlet" ; sh:path s223:hasConnectionPoint ; sh:severity sh:Warning ; sh:sparql [ a sh:SPARQLConstraint ; @@ -582,7 +572,17 @@ FILTER (NOT EXISTS { } } ) . } -""" ] ] . +""" ] ], + [ rdfs:comment "A Filter shall have at least one inlet." ; + sh:minCount 1 ; + sh:path s223:hasConnectionPoint ; + sh:qualifiedMinCount 1 ; + sh:qualifiedValueShape [ sh:class s223:InletConnectionPoint ] ], + [ rdfs:comment "A Filter shall have at least one outlet." ; + sh:minCount 1 ; + sh:path s223:hasConnectionPoint ; + sh:qualifiedMinCount 1 ; + sh:qualifiedValueShape [ sh:class s223:OutletConnectionPoint ] ] . s223:FlowSensor a s223:Class, sh:NodeShape ; @@ -890,25 +890,7 @@ s223:Pump a s223:Class, rdfs:label "Pump" ; rdfs:comment "A machine for imparting energy to a fluid, drawing a fluid into itself through an entrance port, and forcing the fluid out through an exhaust port." ; rdfs:subClassOf s223:Equipment ; - sh:property [ rdfs:comment "A Pump shall have at least one inlet using the medium Water, Oil or Refrigerant." ; - sh:minCount 1 ; - sh:path s223:hasConnectionPoint ; - sh:qualifiedMinCount 1 ; - sh:qualifiedValueShape [ sh:class s223:InletConnectionPoint ; - sh:node [ sh:or ( [ sh:property [ sh:class s223:Medium-Water ; - sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Refrigerant ; - sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Oil ; - sh:path s223:hasMedium ] ] ) ] ] ], - [ rdfs:comment "A Pump shall have at least one outlet using the medium Water, Oil or Refrigerant." ; - sh:minCount 1 ; - sh:path s223:hasConnectionPoint ; - sh:qualifiedMinCount 1 ; - sh:qualifiedValueShape [ sh:class s223:OutletConnectionPoint ; - sh:node [ sh:or ( [ sh:property [ sh:class s223:Medium-Water ; - sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Refrigerant ; - sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Oil ; - sh:path s223:hasMedium ] ] ) ] ] ], - [ rdfs:comment "The non-electrical ConnectionPoints of a Pump must have compatible Media." ; + sh:property [ rdfs:comment "The non-electrical ConnectionPoints of a Pump must have compatible Media." ; sh:path s223:hasConnectionPoint ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "The non-electrical ConnectionPoints of a Pump must have compatible Media." ; @@ -928,7 +910,25 @@ WHERE { FILTER (NOT EXISTS {?mediumb a/rdfs:subClassOf* ?mediuma}) . FILTER (NOT EXISTS {?mediuma a/rdfs:subClassOf* ?mediumb}) . } -""" ] ] . +""" ] ], + [ rdfs:comment "A Pump shall have at least one inlet using the medium Water, Oil or Refrigerant." ; + sh:minCount 1 ; + sh:path s223:hasConnectionPoint ; + sh:qualifiedMinCount 1 ; + sh:qualifiedValueShape [ sh:class s223:InletConnectionPoint ; + sh:node [ sh:or ( [ sh:property [ sh:class s223:Medium-Water ; + sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Refrigerant ; + sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Oil ; + sh:path s223:hasMedium ] ] ) ] ] ], + [ rdfs:comment "A Pump shall have at least one outlet using the medium Water, Oil or Refrigerant." ; + sh:minCount 1 ; + sh:path s223:hasConnectionPoint ; + sh:qualifiedMinCount 1 ; + sh:qualifiedValueShape [ sh:class s223:OutletConnectionPoint ; + sh:node [ sh:or ( [ sh:property [ sh:class s223:Medium-Water ; + sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Refrigerant ; + sh:path s223:hasMedium ] ] [ sh:property [ sh:class s223:Medium-Oil ; + sh:path s223:hasMedium ] ] ) ] ] ] . s223:QuantifiableActuatableProperty a s223:Class, sh:NodeShape ; @@ -1315,6 +1315,50 @@ s223:inverseOf a rdf:Property ; rdfs:label "inverse of" ; rdfs:comment "The relation inverseOf is a modeling construct to associate relations that are inverses of one another, such as connectedTo and connectedFrom." . + a owl:Ontology ; + sh:declare [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ], + [ sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#"^^xsd:anyURI ; + sh:prefix "rdf" ], + [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; + sh:prefix "rdfs" ], + [ sh:namespace "http://www.w3.org/ns/shacl#"^^xsd:anyURI ; + sh:prefix "sh" ], + [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; + sh:prefix "qudt" ], + [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; + sh:prefix "qudt" ], + [ sh:namespace "http://qudt.org/vocab/quantitykind/"^^xsd:anyURI ; + sh:prefix "quantitykind" ], + [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ], + [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; + sh:prefix "rdfs" ], + [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; + sh:prefix "rdfs" ], + [ sh:namespace "http://www.w3.org/ns/shacl#"^^xsd:anyURI ; + sh:prefix "sh" ], + [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ], + [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ], + [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; + sh:prefix "qudt" ], + [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ], + [ sh:namespace "http://data.ashrae.org/standard223/1.0/vocab/role#"^^xsd:anyURI ; + sh:prefix "role" ], + [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; + sh:prefix "qudt" ], + [ sh:namespace "http://qudt.org/vocab/quantitykind/"^^xsd:anyURI ; + sh:prefix "qudtqk" ], + [ sh:namespace "http://qudt.org/vocab/unit/"^^xsd:anyURI ; + sh:prefix "unit" ], + [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; + sh:prefix "rdfs" ], + [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; + sh:prefix "s223" ] . + bacnet:device-identifier a rdf:Property ; rdfs:label "Device Identifier" ; rdfs:comment "The Object_Identifier property of the device object within the BACnet device. See ASHRAE 135-2020 Clause 12.11.1." . @@ -2976,13 +3020,7 @@ s223:HeatExchanger a s223:Class, rdfs:label "Heat exchanger" ; rdfs:comment "A component intended to transfer heat from one medium to another while keeping the two media separate" ; rdfs:subClassOf s223:Equipment ; - sh:property [ rdfs:comment "A heat exchanger shall have at least 4 connection points." ; - sh:minCount 4 ; - sh:path s223:hasConnectionPoint ], - [ rdfs:comment "If the relation hasRole is present it must associate the HeatExchanger with a EnumerationKind-Role." ; - sh:class s223:EnumerationKind-Role ; - sh:path s223:hasRole ], - [ rdfs:comment "Heat Exchangers should have the same number of non-electrical inlet and outlet connection points." ; + sh:property [ rdfs:comment "Heat Exchangers should have the same number of non-electrical inlet and outlet connection points." ; sh:path s223:hasConnectionPoint ; sh:severity sh:Warning ; sh:sparql [ a sh:SPARQLConstraint ; @@ -3018,7 +3056,13 @@ GROUP BY $this } FILTER (?incount != ?outcount) } -""" ] ] . +""" ] ], + [ rdfs:comment "A heat exchanger shall have at least 4 connection points." ; + sh:minCount 4 ; + sh:path s223:hasConnectionPoint ], + [ rdfs:comment "If the relation hasRole is present it must associate the HeatExchanger with a EnumerationKind-Role." ; + sh:class s223:EnumerationKind-Role ; + sh:path s223:hasRole ] . s223:Junction a s223:Class, sh:NodeShape ; @@ -3042,12 +3086,7 @@ s223:Junction a s223:Class, sh:qualifiedMinCount 1 ; sh:qualifiedValueShape [ sh:class s223:BidirectionalConnectionPoint ] ; sh:qualifiedValueShapesDisjoint true ] ] ) ; - sh:property [ rdfs:comment "A Junction must be associated with exactly one EnumerationKind-Medium using the relation hasMedium." ; - sh:class s223:Substance-Medium ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:path s223:hasMedium ], - [ rdfs:comment "Ensure that the Medium identified by a ConnectionPoint via the s223:hasMedium relation is compatible with the Medium identified by the associated Junction." ; + sh:property [ rdfs:comment "Ensure that the Medium identified by a ConnectionPoint via the s223:hasMedium relation is compatible with the Medium identified by the associated Junction." ; sh:name "Test for compatible declared Medium" ; sh:path s223:hasMedium ; sh:sparql [ a sh:SPARQLConstraint ; @@ -3086,7 +3125,12 @@ FILTER (?m1 != ?m2 ) . FILTER (NOT EXISTS {?m2 a/rdfs:subClassOf* ?m1}) . FILTER (NOT EXISTS {?m1 a/rdfs:subClassOf* ?m2}) . } -""" ] ] . +""" ] ], + [ rdfs:comment "A Junction must be associated with exactly one EnumerationKind-Medium using the relation hasMedium." ; + sh:class s223:Substance-Medium ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:path s223:hasMedium ] . s223:Light-Infrared a s223:Class, s223:Light-Infrared, @@ -3563,16 +3607,7 @@ s223:Zone a s223:Class, rdfs:label "Zone" ; rdfs:comment "A Zone is a logical grouping (collection) of domain spaces for some functional or system reason, to identify a domain of control, such as a Lighting Zone, or a heating zone" ; rdfs:subClassOf s223:Concept ; - sh:property [ rdfs:comment "A Zone must be associated with exactly one EnumerationKind-Domain using the relation hasDomain." ; - sh:class s223:EnumerationKind-Domain ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:path s223:hasDomain ], - [ rdfs:comment "A Zone must be associated with at least one DomainSpace using the relation hasDomainSpace." ; - sh:class s223:DomainSpace ; - sh:minCount 1 ; - sh:path s223:hasDomainSpace ], - [ rdfs:comment "The associated Domain of a Zone and the Domain of the DomainSpaces it contains must be the same." ; + sh:property [ rdfs:comment "The associated Domain of a Zone and the Domain of the DomainSpaces it contains must be the same." ; sh:path s223:hasDomain ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "The associated Domain of a Zone and the Domain of the DomainSpaces it contains must be the same." ; @@ -3587,7 +3622,16 @@ $this s223:contains ?ds . ?ds s223:hasDomain ?dsdomain . FILTER (?domain != ?dsdomain) } -""" ] ] ; +""" ] ], + [ rdfs:comment "A Zone must be associated with exactly one EnumerationKind-Domain using the relation hasDomain." ; + sh:class s223:EnumerationKind-Domain ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:path s223:hasDomain ], + [ rdfs:comment "A Zone must be associated with at least one DomainSpace using the relation hasDomainSpace." ; + sh:class s223:DomainSpace ; + sh:minCount 1 ; + sh:path s223:hasDomainSpace ] ; sh:rule [ a sh:TripleRule ; rdfs:comment "Infer a hasDomain relation by checking any enclosed DomainSpaces to determine the domain." ; sh:object [ sh:path ( s223:hasDomainSpace s223:hasDomain ) ] ; @@ -3651,52 +3695,6 @@ s223:ofMedium a rdf:Property ; rdfs:label "of medium" ; rdfs:comment "The relation ofMedium is used to associate a Property with a specific Medium." . - a owl:Ontology ; - owl:imports , - ; - sh:declare [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; - sh:prefix "qudt" ], - [ sh:namespace "http://qudt.org/vocab/quantitykind/"^^xsd:anyURI ; - sh:prefix "quantitykind" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ], - [ sh:namespace "http://data.ashrae.org/standard223/1.0/vocab/role#"^^xsd:anyURI ; - sh:prefix "role" ], - [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; - sh:prefix "qudt" ], - [ sh:namespace "http://qudt.org/vocab/quantitykind/"^^xsd:anyURI ; - sh:prefix "qudtqk" ], - [ sh:namespace "http://qudt.org/vocab/unit/"^^xsd:anyURI ; - sh:prefix "unit" ], - [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; - sh:prefix "rdfs" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ], - [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; - sh:prefix "qudt" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ], - [ sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#"^^xsd:anyURI ; - sh:prefix "rdf" ], - [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; - sh:prefix "rdfs" ], - [ sh:namespace "http://www.w3.org/ns/shacl#"^^xsd:anyURI ; - sh:prefix "sh" ], - [ sh:namespace "http://qudt.org/schema/qudt/"^^xsd:anyURI ; - sh:prefix "qudt" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ], - [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; - sh:prefix "rdfs" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ], - [ sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ; - sh:prefix "rdfs" ], - [ sh:namespace "http://www.w3.org/ns/shacl#"^^xsd:anyURI ; - sh:prefix "sh" ], - [ sh:namespace "http://data.ashrae.org/standard223#"^^xsd:anyURI ; - sh:prefix "s223" ] . - s223:AbstractSensor a s223:Class, sh:NodeShape ; rdfs:label "Abstract sensor" ; @@ -3844,16 +3842,16 @@ s223:DomainSpace a s223:Class, rdfs:label "Domain Space" ; rdfs:comment "A DomainSpace is a member (or component) of a Zone and is associated with a Domain such as Lighting, HVAC, PhysicalSecurity, etc. Physical spaces enclose Domain spaces." ; rdfs:subClassOf s223:Connectable ; - sh:property [ rdfs:comment "A DomainSpace must be associated with exactly one EnumerationKind-Domain using the relation hasDomain." ; - sh:class s223:EnumerationKind-Domain ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:path s223:hasDomain ], - [ rdfs:comment "A DomainSpace must be enclosed by a PhysicalSpace." ; + sh:property [ rdfs:comment "A DomainSpace must be enclosed by a PhysicalSpace." ; sh:message "A DomainSpace must be enclosed by a PhysicalSpace." ; sh:minCount 1 ; sh:path [ sh:inversePath s223:encloses ] ; - sh:severity sh:Info ] ; + sh:severity sh:Info ], + [ rdfs:comment "A DomainSpace must be associated with exactly one EnumerationKind-Domain using the relation hasDomain." ; + sh:class s223:EnumerationKind-Domain ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:path s223:hasDomain ] ; sh:rule [ a sh:TripleRule ; rdfs:comment "Infer a hasDomain relation by checking any enclosing Zone to determine the domain." ; sh:object [ sh:path ( [ sh:inversePath s223:hasDomainSpace ] s223:hasDomain ) ] ; @@ -3865,12 +3863,7 @@ s223:EnumerableProperty a s223:Class, rdfs:label "Enumerable Property" ; rdfs:comment "An EnumerableProperty is a property with an enumerated (fixed) set of possible values." ; rdfs:subClassOf s223:Property ; - sh:property [ rdfs:comment "An EnumerableProperty must be associated with exactly one EnumerationKind using the relation hasEnumerationKind." ; - sh:class s223:EnumerationKind ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:path s223:hasEnumerationKind ], - [ rdfs:comment "Checks for valid enumeration value consistent with the stated EnumerationKind." ; + sh:property [ rdfs:comment "Checks for valid enumeration value consistent with the stated EnumerationKind." ; sh:path s223:hasValue ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "Checks for valid enumeration value consistent with the stated EnumerationKind." ; @@ -3883,7 +3876,12 @@ $this s223:hasValue ?value . $this s223:hasEnumerationKind ?kind . FILTER (NOT EXISTS {?value a/rdfs:subClassOf* ?kind}) . } -""" ] ] . +""" ] ], + [ rdfs:comment "An EnumerableProperty must be associated with exactly one EnumerationKind using the relation hasEnumerationKind." ; + sh:class s223:EnumerationKind ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:path s223:hasEnumerationKind ] . s223:ExternalReference a s223:Class, sh:NodeShape ; @@ -5260,10 +5258,7 @@ s223:EnumerationKind-Substance a s223:Class, rdfs:label "Substance" ; rdfs:comment "This class has enumerated subclasses of the substances that are consumed, produced, transported, sensed, controlled or otherwise interacted with (e.g. water, air, etc.)." ; rdfs:subClassOf s223:EnumerationKind ; - sh:property [ rdfs:comment "If the relation hasConstituent is present, it must associate an EnumerationKind-Substance with one or more Properties that identify and characterize those constituents." ; - sh:class s223:Property ; - sh:path s223:hasConstituent ], - [ rdfs:comment "A substance may only have atomic constituents, it may not have a constituent that also has constituents." ; + sh:property [ rdfs:comment "A substance may only have atomic constituents, it may not have a constituent that also has constituents." ; sh:path s223:hasConstituent ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "If a substance has a constituent, that constituent may not itself have constituents." ; @@ -5275,7 +5270,10 @@ WHERE { $this s223:hasConstituent ?constituent . ?constituent s223:ofSubstance/s223:hasConstituent ?nextConstituent . } -""" ] ] . +""" ] ], + [ rdfs:comment "If the relation hasConstituent is present, it must associate an EnumerationKind-Substance with one or more Properties that identify and characterize those constituents." ; + sh:class s223:Property ; + sh:path s223:hasConstituent ] . s223:LineNeutralVoltage-120V a s223:Class, s223:LineNeutralVoltage-120V, @@ -5384,37 +5382,7 @@ A Connection may contain branches or intersections. These may be modeled using J sh:qualifiedMinCount 1 ; sh:qualifiedValueShape [ sh:class s223:BidirectionalConnectionPoint ] ; sh:qualifiedValueShapesDisjoint true ] ] ) ; - sh:property [ rdfs:comment "If the relation connectsAt is present it must associate the Connection with a ConnectionPoint." ; - sh:class s223:ConnectionPoint ; - sh:path s223:connectsAt ], - [ rdfs:comment "If the relation connectsFrom is present it must associate the Connection with a Connectable." ; - sh:class s223:Connectable ; - sh:name "ConnectionToUpstreamConnectableShape" ; - sh:path s223:connectsFrom ], - [ rdfs:comment "If the relation connectsTo is present it must associate the Connection with a Connectable." ; - sh:class s223:Connectable ; - sh:name "ConnectionToDownstreamConnectableShape" ; - sh:path s223:connectsTo ], - [ rdfs:comment "A Connection must be associated with exactly one EnumerationKind-Medium using the relation hasMedium." ; - sh:class s223:Substance-Medium ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:name "Connection medium" ; - sh:path s223:hasMedium ], - [ rdfs:comment "If the relation hasRole is present it must associate the Connection with an EnumerationKind-Role." ; - sh:class s223:EnumerationKind-Role ; - sh:path s223:hasRole ], - [ rdfs:comment "If the relation hasThermodynamicPhase is present it must associate the Connection with an EnumerationKind-Phase." ; - sh:class s223:EnumerationKind-Phase ; - sh:maxCount 1 ; - sh:path s223:hasThermodynamicPhase ], - [ rdfs:comment "A Connection must have two or more cnx relations to ConnectionPoints" ; - sh:class s223:ConnectionPoint ; - sh:message "A Connection must have two or more cnx relations to ConnectionPoints" ; - sh:minCount 2 ; - sh:path s223:cnx ; - sh:severity sh:Info ], - [ rdfs:comment "A Connection must only have a cnx relation with a ConnectionPoint" ; + sh:property [ rdfs:comment "A Connection must only have a cnx relation with a ConnectionPoint" ; sh:path s223:cnx ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "A Connection must only have a cnx relation with a ConnectionPoint" ; @@ -5464,7 +5432,37 @@ FILTER (?m1 != ?m2 ) . FILTER (NOT EXISTS {?m2 a/rdfs:subClassOf* ?m1}) . FILTER (NOT EXISTS {?m1 a/rdfs:subClassOf* ?m2}) . } -""" ] ] ; +""" ] ], + [ rdfs:comment "If the relation connectsAt is present it must associate the Connection with a ConnectionPoint." ; + sh:class s223:ConnectionPoint ; + sh:path s223:connectsAt ], + [ rdfs:comment "If the relation connectsFrom is present it must associate the Connection with a Connectable." ; + sh:class s223:Connectable ; + sh:name "ConnectionToUpstreamConnectableShape" ; + sh:path s223:connectsFrom ], + [ rdfs:comment "If the relation connectsTo is present it must associate the Connection with a Connectable." ; + sh:class s223:Connectable ; + sh:name "ConnectionToDownstreamConnectableShape" ; + sh:path s223:connectsTo ], + [ rdfs:comment "A Connection must be associated with exactly one EnumerationKind-Medium using the relation hasMedium." ; + sh:class s223:Substance-Medium ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "Connection medium" ; + sh:path s223:hasMedium ], + [ rdfs:comment "If the relation hasRole is present it must associate the Connection with an EnumerationKind-Role." ; + sh:class s223:EnumerationKind-Role ; + sh:path s223:hasRole ], + [ rdfs:comment "If the relation hasThermodynamicPhase is present it must associate the Connection with an EnumerationKind-Phase." ; + sh:class s223:EnumerationKind-Phase ; + sh:maxCount 1 ; + sh:path s223:hasThermodynamicPhase ], + [ rdfs:comment "A Connection must have two or more cnx relations to ConnectionPoints" ; + sh:class s223:ConnectionPoint ; + sh:message "A Connection must have two or more cnx relations to ConnectionPoints" ; + sh:minCount 2 ; + sh:path s223:cnx ; + sh:severity sh:Info ] ; sh:rule [ a sh:SPARQLRule ; rdfs:comment "Infer the connectsFrom relation using connectsAt" ; sh:construct """ @@ -5578,7 +5576,20 @@ A QuantifiableProperty (or subClass thereof) must always be associated with a Un Enumerable properties must be associated with an EnumerationKind. """ ; rdfs:subClassOf s223:Concept ; - sh:property [ rdfs:comment "If the relation hasAspect is present, it must associate the Property with an EnumerationKind." ; + sh:property [ rdfs:comment "" ; + sh:path s223:ofSubstance ; + sh:sparql [ a sh:SPARQLConstraint ; + rdfs:comment "If an incoming relation hasConstituent exists, then the Property must have a declared substance using the relation ofSubstance." ; + sh:message "Property {$this} is referred to by {?something} with s223:hasConstituent, but the Property has no value for s223:ofSubstance." ; + sh:prefixes ; + sh:select """ +SELECT $this ?something +WHERE { +?something s223:hasConstituent $this . +FILTER NOT EXISTS {$this s223:ofSubstance ?someSubstance} . +} +""" ] ], + [ rdfs:comment "If the relation hasAspect is present, it must associate the Property with an EnumerationKind." ; sh:class s223:EnumerationKind ; sh:path s223:hasAspect ], [ rdfs:comment "If the relation hasExternalReference is present it must associate the Property with an ExternalReference." ; @@ -5599,20 +5610,7 @@ Enumerable properties must be associated with an EnumerationKind. sh:class s223:FunctionBlock ; sh:maxCount 1 ; sh:message "A Property can be associated with at most one FunctionBlock using the inverse relation hasOutput." ; - sh:path [ sh:inversePath s223:hasOutput ] ], - [ rdfs:comment "" ; - sh:path s223:ofSubstance ; - sh:sparql [ a sh:SPARQLConstraint ; - rdfs:comment "If an incoming relation hasConstituent exists, then the Property must have a declared substance using the relation ofSubstance." ; - sh:message "Property {$this} is referred to by {?something} with s223:hasConstituent, but the Property has no value for s223:ofSubstance." ; - sh:prefixes ; - sh:select """ -SELECT $this ?something -WHERE { -?something s223:hasConstituent $this . -FILTER NOT EXISTS {$this s223:ofSubstance ?someSubstance} . -} -""" ] ] ; + sh:path [ sh:inversePath s223:hasOutput ] ] ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "A Property instance cannot be declared an instance of both an ActuatableProperty and an ObservableProperty." ; sh:message "{$this} cannot be declared an instance of both an ActuatableProperty and an ObservableProperty." ; @@ -5641,29 +5639,7 @@ s223:Connectable a s223:Class, s223:abstract true ; rdfs:comment "Connectable is an abstract class representing a thing such as, Equipment (see `s223:Equipment`), DomainSpace (see `s223:DomainSpace`), or Junction (see `s223:Junction`) that can be connected via ConnectionPoints and Connections." ; rdfs:subClassOf s223:Concept ; - sh:property [ rdfs:comment "If the relation cnx is present it must associate the Connectable with a ConnectionPoint." ; - sh:class s223:ConnectionPoint ; - sh:path s223:cnx ], - [ rdfs:comment "If the relation connected is present it must associate the Connectable with a Connectable." ; - sh:class s223:Connectable ; - sh:name "SymmetricConnectableToConnectableShape" ; - sh:path s223:connected ], - [ rdfs:comment "If the relation connectedFrom is present it must associate the Connectable with a Connectable." ; - sh:class s223:Connectable ; - sh:path s223:connectedFrom ], - [ rdfs:comment "If the relation connectedThrough is present it must associate the Connectable with a Connection." ; - sh:class s223:Connection ; - sh:name "EquipmentToConnectionShape" ; - sh:path s223:connectedThrough ], - [ rdfs:comment "If the relation connectedTo is present it must associate the Connectable with a Connectable." ; - sh:class s223:Connectable ; - sh:name "ConnectableToConnectableShape" ; - sh:path s223:connectedTo ], - [ rdfs:comment "If the relation hasConnectionPoint is present it must associate the Connectable with a ConnectionPoint." ; - sh:class s223:ConnectionPoint ; - sh:name "EquipmentToConnectionPointShape" ; - sh:path s223:hasConnectionPoint ], - [ rdfs:comment "For a Connectable, cnx relation must associate the Connectable to a ConnectionPoint" ; + sh:property [ rdfs:comment "For a Connectable, cnx relation must associate the Connectable to a ConnectionPoint" ; sh:path s223:cnx ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "A Connectable should only have a s223:cnx relation with a ConnectionPoint" ; @@ -5687,7 +5663,29 @@ WHERE { $this s223:connected ?otherC . FILTER NOT EXISTS {$this s223:cnx+ ?otherC} } -""" ] ] ; +""" ] ], + [ rdfs:comment "If the relation cnx is present it must associate the Connectable with a ConnectionPoint." ; + sh:class s223:ConnectionPoint ; + sh:path s223:cnx ], + [ rdfs:comment "If the relation connected is present it must associate the Connectable with a Connectable." ; + sh:class s223:Connectable ; + sh:name "SymmetricConnectableToConnectableShape" ; + sh:path s223:connected ], + [ rdfs:comment "If the relation connectedFrom is present it must associate the Connectable with a Connectable." ; + sh:class s223:Connectable ; + sh:path s223:connectedFrom ], + [ rdfs:comment "If the relation connectedThrough is present it must associate the Connectable with a Connection." ; + sh:class s223:Connection ; + sh:name "EquipmentToConnectionShape" ; + sh:path s223:connectedThrough ], + [ rdfs:comment "If the relation connectedTo is present it must associate the Connectable with a Connectable." ; + sh:class s223:Connectable ; + sh:name "ConnectableToConnectableShape" ; + sh:path s223:connectedTo ], + [ rdfs:comment "If the relation hasConnectionPoint is present it must associate the Connectable with a ConnectionPoint." ; + sh:class s223:ConnectionPoint ; + sh:name "EquipmentToConnectionPointShape" ; + sh:path s223:hasConnectionPoint ] ; sh:rule [ a sh:SPARQLRule ; rdfs:comment "Infer the connected relation for BiDirectional connections" ; sh:construct """ @@ -5779,52 +5777,7 @@ ConnectionPoints are represented graphically in this standard by a triangle with """ ; rdfs:subClassOf s223:Concept ; - sh:property [ rdfs:comment "A ConnectionPoint must be associated with at most one Connectable using the cnx relation." ; - sh:message "A ConnectionPoint must be associated with at most one Connectable using the cnx relation." ; - sh:path s223:cnx ; - sh:qualifiedMaxCount 1 ; - sh:qualifiedValueShape [ sh:class s223:Connectable ] ; - sh:qualifiedValueShapesDisjoint true ], - [ rdfs:comment "A ConnectionPoint must be associated with at most one Connection using the cnx relation" ; - sh:message "A ConnectionPoint must be associated with at most one Connection using the cnx relation" ; - sh:path s223:cnx ; - sh:qualifiedMaxCount 1 ; - sh:qualifiedValueShape [ sh:class s223:Connection ] ; - sh:qualifiedValueShapesDisjoint true ], - [ rdfs:comment "A ConnectionPoint must be associated with at most one Connection using the relation connectsThrough." ; - sh:class s223:Connection ; - sh:maxCount 1 ; - sh:message "This ConnectionPoint must be associated with at most one Connection." ; - sh:name "ConnectionPointToConnectionShape" ; - sh:path s223:connectsThrough ; - sh:severity sh:Info ], - [ rdfs:comment "If the relation hasElectricalPhase is present it must associate the ConnectionPoint with an ElectricalPhaseIdentifier or ElectricalVoltagePhases." ; - sh:or ( [ sh:class s223:Aspect-ElectricalPhaseIdentifier ] [ sh:class s223:Aspect-ElectricalVoltagePhases ] ) ; - sh:path s223:hasElectricalPhase ], - [ rdfs:comment "A ConnectionPoint must be associated with exactly one Substance-Medium using the relation hasMedium." ; - sh:class s223:Substance-Medium ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:name "ConnectionPoint medium" ; - sh:path s223:hasMedium ], - [ rdfs:comment "If the relation hasRole is present it must associate the ConnectionPoint with an EnumerationKind-Role." ; - sh:class s223:EnumerationKind-Role ; - sh:path s223:hasRole ], - [ rdfs:comment "A ConnectionPoint must be associated with exactly one Connectable using the relation isConnectionPointOf." ; - sh:class s223:Connectable ; - sh:maxCount 1 ; - sh:minCount 1 ; - sh:name "ConnectionPointToEquipmentShape" ; - sh:path s223:isConnectionPointOf ], - [ rdfs:comment "A ConnectionPoint can be associated with at most one other ConnectionPoint using the relation mapsTo" ; - sh:class s223:ConnectionPoint ; - sh:maxCount 1 ; - sh:path s223:mapsTo ], - [ rdfs:comment "A ConnectionPoint can be associated with at most one other ConnectionPoint using the inverse of relation mapsTo" ; - sh:class s223:ConnectionPoint ; - sh:maxCount 1 ; - sh:path [ sh:inversePath s223:mapsTo ] ], - [ rdfs:comment "If a ConnectionPoint lacks a connectsThrough and mapsTo relation, and is not associated with a Junction or Equipment that is contained by an Equipment, then suggest that the ConnectionPoint probably needs an association with a Connection." ; + sh:property [ rdfs:comment "If a ConnectionPoint lacks a connectsThrough and mapsTo relation, and is not associated with a Junction or Equipment that is contained by an Equipment, then suggest that the ConnectionPoint probably needs an association with a Connection." ; sh:path s223:connectsThrough ; sh:severity sh:Info ; sh:sparql [ a sh:SPARQLConstraint ; @@ -5904,7 +5857,52 @@ $this s223:mapsTo ?otherCP . ?otherEquipment s223:hasConnectionPoint ?otherCP . FILTER NOT EXISTS {?otherEquipment s223:contains ?equipment} } -""" ] ] . +""" ] ], + [ rdfs:comment "A ConnectionPoint must be associated with at most one Connectable using the cnx relation." ; + sh:message "A ConnectionPoint must be associated with at most one Connectable using the cnx relation." ; + sh:path s223:cnx ; + sh:qualifiedMaxCount 1 ; + sh:qualifiedValueShape [ sh:class s223:Connectable ] ; + sh:qualifiedValueShapesDisjoint true ], + [ rdfs:comment "A ConnectionPoint must be associated with at most one Connection using the cnx relation" ; + sh:message "A ConnectionPoint must be associated with at most one Connection using the cnx relation" ; + sh:path s223:cnx ; + sh:qualifiedMaxCount 1 ; + sh:qualifiedValueShape [ sh:class s223:Connection ] ; + sh:qualifiedValueShapesDisjoint true ], + [ rdfs:comment "A ConnectionPoint must be associated with at most one Connection using the relation connectsThrough." ; + sh:class s223:Connection ; + sh:maxCount 1 ; + sh:message "This ConnectionPoint must be associated with at most one Connection." ; + sh:name "ConnectionPointToConnectionShape" ; + sh:path s223:connectsThrough ; + sh:severity sh:Info ], + [ rdfs:comment "If the relation hasElectricalPhase is present it must associate the ConnectionPoint with an ElectricalPhaseIdentifier or ElectricalVoltagePhases." ; + sh:or ( [ sh:class s223:Aspect-ElectricalPhaseIdentifier ] [ sh:class s223:Aspect-ElectricalVoltagePhases ] ) ; + sh:path s223:hasElectricalPhase ], + [ rdfs:comment "A ConnectionPoint must be associated with exactly one Substance-Medium using the relation hasMedium." ; + sh:class s223:Substance-Medium ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "ConnectionPoint medium" ; + sh:path s223:hasMedium ], + [ rdfs:comment "If the relation hasRole is present it must associate the ConnectionPoint with an EnumerationKind-Role." ; + sh:class s223:EnumerationKind-Role ; + sh:path s223:hasRole ], + [ rdfs:comment "A ConnectionPoint must be associated with exactly one Connectable using the relation isConnectionPointOf." ; + sh:class s223:Connectable ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "ConnectionPointToEquipmentShape" ; + sh:path s223:isConnectionPointOf ], + [ rdfs:comment "A ConnectionPoint can be associated with at most one other ConnectionPoint using the relation mapsTo" ; + sh:class s223:ConnectionPoint ; + sh:maxCount 1 ; + sh:path s223:mapsTo ], + [ rdfs:comment "A ConnectionPoint can be associated with at most one other ConnectionPoint using the inverse of relation mapsTo" ; + sh:class s223:ConnectionPoint ; + sh:maxCount 1 ; + sh:path [ sh:inversePath s223:mapsTo ] ] . s223:DCVoltage-DCZeroVoltage a s223:Class, s223:DCVoltage-DCZeroVoltage, @@ -6095,10 +6093,7 @@ s223:OutletConnectionPoint a s223:Class, rdfs:label "Outlet Connection Point" ; rdfs:comment "An OutletConnectionPoint indicates that a substance must flow out of a Connectable (see 's223:Connectable') at this connection point and cannot flow in the other direction. An OutletConnectionPoint is a predefined subclass of ConnectionPoint." ; rdfs:subClassOf s223:ConnectionPoint ; - sh:property [ rdfs:comment "If the relation mapsTo is present it must associate the OutletConnectionPoint with an OutletConnectionPoint." ; - sh:class s223:OutletConnectionPoint ; - sh:path s223:mapsTo ], - [ rdfs:comment "Ensure an OutletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; + sh:property [ rdfs:comment "Ensure an OutletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; sh:path s223:mapsTo ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "Ensure an OutletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; @@ -6113,17 +6108,17 @@ $this s223:connectsThrough/s223:connectsTo ?destinationEquipment . FILTER NOT EXISTS {?parentEquipment s223:contains ?destinationEquipment} . FILTER NOT EXISTS {$this s223:mapsTo ?anything} . } -""" ] ] . +""" ] ], + [ rdfs:comment "If the relation mapsTo is present it must associate the OutletConnectionPoint with an OutletConnectionPoint." ; + sh:class s223:OutletConnectionPoint ; + sh:path s223:mapsTo ] . s223:InletConnectionPoint a s223:Class, sh:NodeShape ; rdfs:label "Inlet Connection Point" ; rdfs:comment "An InletConnectionPoint indicates that a substance must flow into the equipment or domain space at this connection point and cannot flow the other direction. An IntletConnectionPoint is a subclass of ConnectionPoint." ; rdfs:subClassOf s223:ConnectionPoint ; - sh:property [ rdfs:comment "If the relation mapsTo is present it must associate the InletConnectionPoint with an InletConnectionPoint." ; - sh:class s223:InletConnectionPoint ; - sh:path s223:mapsTo ], - [ rdfs:comment "Ensure an InletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; + sh:property [ rdfs:comment "Ensure an InletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; sh:path s223:mapsTo ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "Ensure an InletConnectionPoint has a mapsTo relation to its containing Equipment if it has an external Connection" ; @@ -6138,7 +6133,10 @@ $this s223:connectsThrough/s223:connectsFrom ?sourceEquipment . FILTER NOT EXISTS {?parentEquipment s223:contains ?sourceEquipment} . FILTER NOT EXISTS {$this s223:mapsTo ?anything} . } -""" ] ] . +""" ] ], + [ rdfs:comment "If the relation mapsTo is present it must associate the InletConnectionPoint with an InletConnectionPoint." ; + sh:class s223:InletConnectionPoint ; + sh:path s223:mapsTo ] . s223:EnumerationKind-Aspect a s223:Class, s223:EnumerationKind-Aspect, @@ -6157,24 +6155,7 @@ s223:Equipment a s223:Class, The graphical depiction of Equipment used in this standard is a rounded cornered rectangle as show in Figure 5-1. ![Graphical Depiction of Equipment.](figures/Figure_5-1Graphical_Depiciton_of_Equipment.svg)""" ; rdfs:subClassOf s223:Connectable ; - sh:property [ a sh:PropertyShape ; - rdfs:comment "If the relation contains is present it must associate the Equipment with either Equipment or Junction." ; - sh:name "device contains shape" ; - sh:or ( [ sh:class s223:Equipment ] [ sh:class s223:Junction ] ) ; - sh:path s223:contains ], - [ rdfs:comment "If the relation commandedByProperty is present it must associate the Equipment with a ActuatableProperty." ; - sh:class s223:ActuatableProperty ; - sh:path s223:commandedByProperty ], - [ rdfs:comment "If the relation executes is present it must associate the Equipment with a FunctionBlock." ; - sh:class s223:FunctionBlock ; - sh:path s223:executes ], - [ rdfs:comment "If the relation hasPhysicalLocation is present it must associate the Equipment with a PhysicalSpace." ; - sh:class s223:PhysicalSpace ; - sh:path s223:hasPhysicalLocation ], - [ rdfs:comment "If the relation hasRole is present it must associate the Equipment with a EnumerationKind-Role." ; - sh:class s223:EnumerationKind-Role ; - sh:path s223:hasRole ], - [ rdfs:comment "Disallow contained equipment from having external incoming connections." ; + sh:property [ rdfs:comment "Disallow contained equipment from having external incoming connections." ; sh:path s223:connectedFrom ; sh:sparql [ a sh:SPARQLConstraint ; rdfs:comment "Disallow contained equipment from having external incoming connections." ; @@ -6227,7 +6208,24 @@ UNION ?type1 rdfs:subClassOf* ?type2 . } } -""" ] ] ; +""" ] ], + [ a sh:PropertyShape ; + rdfs:comment "If the relation contains is present it must associate the Equipment with either Equipment or Junction." ; + sh:name "device contains shape" ; + sh:or ( [ sh:class s223:Equipment ] [ sh:class s223:Junction ] ) ; + sh:path s223:contains ], + [ rdfs:comment "If the relation commandedByProperty is present it must associate the Equipment with a ActuatableProperty." ; + sh:class s223:ActuatableProperty ; + sh:path s223:commandedByProperty ], + [ rdfs:comment "If the relation executes is present it must associate the Equipment with a FunctionBlock." ; + sh:class s223:FunctionBlock ; + sh:path s223:executes ], + [ rdfs:comment "If the relation hasPhysicalLocation is present it must associate the Equipment with a PhysicalSpace." ; + sh:class s223:PhysicalSpace ; + sh:path s223:hasPhysicalLocation ], + [ rdfs:comment "If the relation hasRole is present it must associate the Equipment with a EnumerationKind-Role." ; + sh:class s223:EnumerationKind-Role ; + sh:path s223:hasRole ] ; sh:rule [ a sh:SPARQLRule ; rdfs:comment "For equipment contained within another piece of equipment use the mapsTo relation to infer a Medium from the containing equipment." ; sh:construct """ @@ -6280,19 +6278,7 @@ s223:QuantifiableProperty a s223:Class, rdfs:comment "This class is for quantifiable values that describe an object (System, Equipment, etc.) that are typically static (hasValue). That is, they are neither measured nor specified in the course of operations." ; rdfs:subClassOf s223:Property, qudt:Quantity ; - sh:property [ rdfs:comment "A QuantifiableProperty can be associated with a decimal value using the relation hasValue." ; - sh:datatype xsd:decimal ; - sh:path s223:hasValue ], - [ rdfs:comment "A QuantifiableProperty must be associated with at least one QuantityKind using the relation hasQuantityKind." ; - sh:class qudt:QuantityKind ; - sh:minCount 1 ; - sh:path qudt:hasQuantityKind ], - [ rdfs:comment "A QuantifiableProperty must be associated with at least one Unit using the relation hasUnit." ; - sh:class qudt:Unit ; - sh:minCount 1 ; - sh:path qudt:hasUnit ; - sh:severity sh:Info ], - [ rdfs:comment "This QuantifiableProperty uses a different Unit than the Setpoint associated with it." ; + sh:property [ rdfs:comment "This QuantifiableProperty uses a different Unit than the Setpoint associated with it." ; sh:path qudt:hasUnit ; sh:severity sh:Info ; sh:sparql [ a sh:SPARQLConstraint ; @@ -6346,7 +6332,19 @@ $this s223:hasSetpoint ?setpoint . FILTER (?punit != ?sunit) . FILTER (?pdv != ?sdv) . } -""" ] ] ; +""" ] ], + [ rdfs:comment "A QuantifiableProperty can be associated with a decimal value using the relation hasValue." ; + sh:datatype xsd:decimal ; + sh:path s223:hasValue ], + [ rdfs:comment "A QuantifiableProperty must be associated with at least one QuantityKind using the relation hasQuantityKind." ; + sh:class qudt:QuantityKind ; + sh:minCount 1 ; + sh:path qudt:hasQuantityKind ], + [ rdfs:comment "A QuantifiableProperty must be associated with at least one Unit using the relation hasUnit." ; + sh:class qudt:Unit ; + sh:minCount 1 ; + sh:path qudt:hasUnit ; + sh:severity sh:Info ] ; sh:rule [ a sh:SPARQLRule ; rdfs:comment "Infer the hasQuantityKind relation if it is unambiguous." ; sh:construct """