diff --git a/generate_interactive_doc.py b/generate_interactive_doc.py index 7f24d87..f59bacf 100644 --- a/generate_interactive_doc.py +++ b/generate_interactive_doc.py @@ -12,6 +12,7 @@ def simplify_node(node): if isinstance(node, BNode): return stable_id(node) + return g.namespace_manager.qname(node) for prefix, namespace in g.namespace_manager.namespaces(): if str(node).startswith(namespace): return prefix + ":" + str(node)[len(namespace):] @@ -142,6 +143,38 @@ def get_all_constraints(g): seen = set() +# add all nodeshapes that are not classes +for node_shape in set(g.subjects(predicate=RDF["type"], object=SH.NodeShape)): + # check it's not a class + if (node_shape, RDF["type"], S223["Class"]) in g: + continue + + if isinstance(node_shape, BNode): + node_name = stable_id(node_shape) + else: + node_name = simplify_node(node_shape) + # avoid duplicates + if node_name in seen: + continue + seen.add(node_name) + + immediate_subgraph = g.cbd(node_shape) + bind_namespaces(immediate_subgraph) + subgraph = get_subgraph(g, node_shape) + bind_namespaces(subgraph) + + name_or_label = g.value(node_shape, SH["name"]) or g.value(node_shape, RDFS["label"]) + message_or_comment = g.value(node_shape, SH["message"]) or g.value(node_shape, RDFS.comment) + label = name_or_label or message_or_comment or "Node Shape" + prop_defns.append({ + "class": None if isinstance(node_shape, BNode) else node_shape, + "name": node_name, + "label": label, + "immediate_subgraph": immediate_subgraph, + "subgraph": subgraph, + "see_alsos": [], + }) + # TODO: do this for property shapes! for property_shape in set(g.objects(predicate=SH["property"])): if isinstance(property_shape, BNode): diff --git a/index.html b/index.html index 5681742..923b1c3 100644 --- a/index.html +++ b/index.html @@ -1319,29 +1319,7 @@
URI: http://data.ashrae.org/standard223#ConnectionPoint
-
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix s223: <http://data.ashrae.org/standard223#> .
-@prefix sh: <http://www.w3.org/ns/shacl#> .
-@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
-
-s223:ConnectionPoint a s223:Class,
- sh:NodeShape ;
- rdfs:label "ConnectionPoint" ;
- s223:abstract true ;
- rdfs:comment """
-A ConnectionPoint is an abstract modeling construct used to represent the fact that one connectable thing can be connected to another connectable thing using a Connection. It is the abstract representation of the flange, wire terminal, or other physical feature where a connection is made. Equipment and DomainSpaces can have one or more ConnectionPoints (see `s223:Connectable` and `s223:Connection`).
-
-A ConnectionPoint is constrained to relate to a specific medium such as air, water, or electricity which determines what other things can be connected to it. For example, constraining a ConnectionPoint to be for air means it cannot be used for an electrical connection.
-
-A ConnectionPoint belongs to exactly one connectable thing.
-
-ConnectionPoints are represented graphically in this standard by a triangle with the point indicating a direction of flow, or a diamond in the case of a bidirectional connection as shown in Figure 6-1.
-
-![Graphical Representation of a ConnectionPoint.](figures/Figure_5-2_Graphical_Depiciton_of_Connection_Points.svg)
-
- """ ;
- rdfs:subClassOf s223:Concept ;
- sh:property [ rdfs:comment "A ConnectionPoint must be associated with at most one Connectable using the cnx relation." ;
+""" ] ],
+ [ 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 ;
@@ -2469,10 +2396,9 @@ ConnectionPointConnectionPoint
+
+ URI: http://data.ashrae.org/standard223#ConnectionPoint
+
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+s223:ConnectionPoint a s223:Class,
+ sh:NodeShape ;
+ rdfs:label "ConnectionPoint" ;
+ s223:abstract true ;
+ rdfs:comment """
+A ConnectionPoint is an abstract modeling construct used to represent the fact that one connectable thing can be connected to another connectable thing using a Connection. It is the abstract representation of the flange, wire terminal, or other physical feature where a connection is made. Equipment and DomainSpaces can have one or more ConnectionPoints (see `s223:Connectable` and `s223:Connection`).
+
+A ConnectionPoint is constrained to relate to a specific medium such as air, water, or electricity which determines what other things can be connected to it. For example, constraining a ConnectionPoint to be for air means it cannot be used for an electrical connection.
+
+A ConnectionPoint belongs to exactly one connectable thing.
+
+ConnectionPoints are represented graphically in this standard by a triangle with the point indicating a direction of flow, or a diamond in the case of a bidirectional connection as shown in Figure 6-1.
+
+![Graphical Representation of a ConnectionPoint.](figures/Figure_5-2_Graphical_Depiciton_of_Connection_Points.svg)
+
+ """ ;
+ rdfs:subClassOf s223:Concept ;
+ 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 ;
@@ -2581,7 +2539,49 @@ ConnectionPoint
@@ -2631,12 +2631,7 @@ URI: http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
+ +
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+rdf:Property a sh:NodeShape ;
+ sh:property [ rdfs:comment "This Property must have a label" ;
+ sh:path rdfs:label ;
+ sh:sparql [ a sh:SPARQLConstraint ;
+ sh:message "{$this} must have an rdfs:label" ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/schema> ;
+ sh:select """
+SELECT $this
+WHERE {
+BIND(REPLACE(STR($this), "^(.*)(/|#)([^#/]*)$", "$1") AS ?prop) .
+FILTER (?prop = "http://data.ashrae.org/standard223") .
+FILTER (NOT EXISTS {$this rdfs:label ?something}) .
+}
+""" ] ],
+ [ rdfs:comment "This Property must have a comment" ;
+ sh:path rdfs:comment ;
+ sh:sparql [ a sh:SPARQLConstraint ;
+ sh:message "{$this} must have an rdfs:comment" ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/schema> ;
+ sh:select """
+SELECT $this
+WHERE {
+BIND(REPLACE(STR($this), "^(.*)(/|#)([^#/]*)$", "$1") AS ?prop) .
+FILTER (?prop = "http://data.ashrae.org/standard223") .
+FILTER (NOT EXISTS {$this rdfs:comment ?something}) .
+}
+""" ] ] .
+
+
+
+ URI: http://data.ashrae.org/standard223#Class
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:Class a rdfs:Class,
+ sh:NodeShape ;
+ rdfs:label "Class" ;
+ rdfs:comment "This is a modeling construct. All classes defined in the 223 standard are instances of s223:Class rather than owl:Class." ;
+ rdfs:subClassOf rdfs:Class .
+
+
+
+ URI: http://data.ashrae.org/standard223#ClosedWorldShape
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:ClosedWorldShape a sh:NodeShape ;
+ sh:severity sh:Info ;
+ sh:sparql [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that all instances of a class use only the properties defined for that class." ;
+ sh:message "Predicate {?p} is not defined for instance {$this}." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this ?p ?o
+WHERE {
+$this a/rdfs:subClassOf* s223:Concept .
+$this ?p ?o .
+FILTER(STRSTARTS (str(?p), "http://data.ashrae.org/standard223") || STRSTARTS (str(?p), "http://qudt.org/schema/qudt"))
+FILTER NOT EXISTS {$this a sh:NodeShape}
+FILTER NOT EXISTS {$this a/rdfs:subClassOf* ?class .
+ ?class sh:property/sh:path ?p .
+}
+FILTER NOT EXISTS {$this a/rdfs:subClassOf* ?class .
+?class sh:xone/rdf:rest*/rdf:first/sh:property/sh:path ?p .
+}
+FILTER NOT EXISTS {$this a/rdfs:subClassOf* ?class .
+?class sh:or/rdf:rest*/rdf:first/sh:property/sh:path ?p .
+}
+}
+""" ] ;
+ sh:targetClass s223:Concept .
+
+
+
+ URI: http://data.ashrae.org/standard223#ControllerRoleShape
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+s223:ControllerRoleShape a sh:NodeShape ;
+ rdfs:comment "Equipment that executes a FunctionBlock must have a s223:hasRole relation to s223:Role-Controller." ;
+ sh:property [ a sh:PropertyShape ;
+ sh:hasValue s223:Role-Controller ;
+ sh:message "Equipment that executes a FunctionBlock must have a s223:hasRole relation to s223:Role-Controller." ;
+ sh:minCount 1 ;
+ sh:path s223:hasRole ] ;
+ sh:targetSubjectsOf s223:executes .
+
+
+
+ URI: http://data.ashrae.org/standard223#InversePropertyShape
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:InversePropertyShape a sh:NodeShape ;
+ sh:rule [ a sh:SPARQLRule ;
+ rdfs:comment "Declare the inverse triples for relations that have defined inverse relations" ;
+ sh:construct """
+CONSTRUCT {
+?o ?invP $this .
+}
+WHERE {
+ $this ?p ?o .
+ ?p s223:inverseOf ?invP .
+}
+ """ ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/inference/owl-subset> ] ;
+ sh:targetClass s223:Concept .
+
+
+
+ URI: http://data.ashrae.org/standard223#MeasuredPropertyRule
+ +
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:MeasuredPropertyRule a sh:NodeShape ;
+ rdfs:comment "Associate the object of hasObservationLocation directly with the observed Property." ;
+ sh:rule [ a sh:TripleRule ;
+ rdfs:comment "Associate the object of hasObservationLocation directly with the observed Property." ;
+ sh:object [ sh:path ( [ sh:inversePath s223:hasObservationLocation ] s223:observes ) ] ;
+ sh:predicate s223:hasProperty ;
+ sh:subject sh:this ] ;
+ sh:targetClass s223:Concept .
+
+
+
+ URI: http://data.ashrae.org/standard223#RequiredCommentsShape
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:RequiredCommentsShape a sh:NodeShape ;
+ sh:severity sh:Info ;
+ sh:sparql [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that any instance of s223:Class is also a rdfs:subClassOf* s223:Concept." ;
+ sh:message "Class {$this} must be within the rdfs:subClassOf hierarchy under s223:Concept." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this
+WHERE {
+FILTER NOT EXISTS {$this rdfs:subClassOf* rdf:Property} .
+FILTER NOT EXISTS {$this rdfs:subClassOf* s223:Concept} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that any instance of s223:Class is also an instance of sh:NodeShape." ;
+ sh:message "Class {$this} must be declared as an instance of sh:NodeShape." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this
+WHERE {
+FILTER NOT EXISTS {$this a sh:NodeShape} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that any instance of s223:Class must have an rdfs:comment." ;
+ sh:message "Class {$this} must have an rdfs:comment." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this
+WHERE {
+FILTER NOT EXISTS {$this rdfs:comment ?comment} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that any property shape must have an rdfs:comment." ;
+ sh:message "The SPARQLConstraint for path {?path} for Class {$this} must have an rdfs:comment." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this ?path
+WHERE {
+$this sh:property ?propshape .
+?propshape sh:sparql ?sparqlconstraint .
+?propshape sh:path ?path .
+FILTER NOT EXISTS {?sparqlconstraint rdfs:comment ?comment} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that any property shape must have an rdfs:comment." ;
+ sh:message "The property shape with path {?path} for Class {$this} must have an rdfs:comment." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/model> ;
+ sh:select """
+SELECT $this ?path
+WHERE {
+$this sh:property ?propshape .
+?propshape sh:path ?path .
+FILTER NOT EXISTS {?propshape rdfs:comment ?comment} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Every Class must have a label." ;
+ sh:message "{$this} must have an rdfs:label" ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/schema> ;
+ sh:select """
+SELECT $this
+WHERE {
+FILTER (NOT EXISTS {$this rdfs:label ?something}) .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that every TripleRule must have an rdfs:comment." ;
+ sh:message "The TripleRule inferring {?pred} for Class {$this} must have an rdfs:comment." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/schema> ;
+ sh:select """
+SELECT $this ?pred
+WHERE {
+$this sh:rule ?rule .
+?rule a sh:TripleRule .
+?rule sh:predicate ?pred .
+FILTER NOT EXISTS {?rule rdfs:comment ?comment} .
+}
+""" ],
+ [ a sh:SPARQLConstraint ;
+ rdfs:comment "Ensure that every SPARQLRule must have an rdfs:comment." ;
+ sh:message "Every SPARQLRule for Class {$this} must have an rdfs:comment." ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/validation/schema> ;
+ sh:select """
+SELECT $this
+WHERE {
+$this sh:rule ?rule .
+?rule a sh:SPARQLRule .
+FILTER NOT EXISTS {?rule rdfs:comment ?comment} .
+}
+""" ] ;
+ sh:targetClass s223:Class .
+
+
+
+ URI: http://data.ashrae.org/standard223#SymmetricProperty
+ +
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:SymmetricProperty a rdfs:Class,
+ sh:NodeShape ;
+ rdfs:label "Symmetric property" ;
+ rdfs:comment "A SymmetricProperty is modeling construct used to define symmetric behavior for certain properties in the standard such as cnx and connected." ;
+ rdfs:subClassOf rdf:Property .
+
+
+
+ URI: http://data.ashrae.org/standard223#SymmetricPropertyShape
+ +
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix s223: <http://data.ashrae.org/standard223#> .
+@prefix sh: <http://www.w3.org/ns/shacl#> .
+
+s223:SymmetricPropertyShape a sh:NodeShape ;
+ sh:rule [ a sh:SPARQLRule ;
+ rdfs:comment "Declare the inverse triples for symmetric relations" ;
+ sh:construct """
+CONSTRUCT {
+?o ?p $this .
+}
+WHERE {
+ $this ?p ?o .
+ ?p a s223:SymmetricProperty .
+}
+ """ ;
+ sh:prefixes <http://data.ashrae.org/standard223/1.0/inference/owl-subset> ] ;
+ sh:targetClass s223:Concept .
+
+
+
+