diff --git a/ontology/owl/owl.ttl b/ontology/owl/owl.ttl index dd464601..4b4a0426 100644 --- a/ontology/owl/owl.ttl +++ b/ontology/owl/owl.ttl @@ -179,25 +179,14 @@ uco-owl:Disjointedness-DP-OP-shape . uco-owl:List-shape - a sh:NodeShape ; - sh:property [ - a sh:PropertyShape ; - sh:maxCount "1"^^xsd:integer ; - sh:path rdf:first ; - ] ; - sh:sparql [ - a sh:SPARQLConstraint ; - rdfs:comment "This requirement is determined from review of the canonical parsing process in Section 3 of the OWL 2 mapping to RDF. Table 5 removes any triple matching the pattern 'x a rdf:List`. All other references throughout Section 3 to rdf:first are identified as blank nodes. Therefore, any non-blank node that is an rdf:List will not be mapped and consumed by the mapping process, making the graph non-conformant with OWL 2 DL."@en ; - rdfs:seeAlso ; - sh:message "The subject of a triple with rdf:first as predicate must be a blank node."@en ; - sh:select """ - SELECT $this - WHERE { - FILTER isIRI($this) - } - """ ; - ] ; - sh:targetSubjectsOf rdf:first ; + a sh:Shape ; + rdfs:comment "This shape's functionality has been exported"@en ; + rdfs:seeAlso + uco-owl:Sequence-shape , + uco-owl:rdf-first-subjects-shape , + uco-owl:rdf-rest-subjects-shape + ; + sh:deactivated "true"^^xsd:boolean ; . uco-owl:ObjectProperty-shacl-constraints-shape @@ -250,6 +239,75 @@ uco-owl:ObjectProperty-shacl-constraints-shape sh:targetClass owl:ObjectProperty ; . +uco-owl:Sequence-shape + a sh:NodeShape ; + rdfs:comment "This shape intentionally has no target declaration. It is instead intended to be incorporated using 'sh:node'."@en ; + rdfs:seeAlso ; + sh:description "This shape is determined from review of the canonical parsing process in Section 3 of the OWL 2 mapping to RDF, particularly Tables 3 and 5. Table 5 removes any triple matching the pattern 'x a rdf:List`. All other references throughout Section 3 to rdf:first are in the context of mapping a Sequence in OWL structure translation, and are denoted as blank nodes, starting with Table 3. A non-blank node that is an rdf:List and used with a sequence-valued property IRI in the OWL namespace will not be mapped and consumed by the mapping process, making the graph non-conformant with OWL 2 DL. But a non-blank node that is an rdf:List can be used if not directly attached to a sequence-valued property IRI in the OWL namespace."@en ; + sh:xone ( + [ + a sh:NodeShape ; + sh:hasValue rdf:nil ; + ] + [ + a sh:NodeShape ; + sh:nodeKind sh:BlankNode ; + sh:property [ + a sh:PropertyShape ; + sh:path [ + sh:oneOrMorePath rdf:rest ; + ] ; + sh:xone ( + [ + a sh:NodeShape ; + sh:hasValue rdf:nil ; + ] + [ + a sh:NodeShape ; + sh:nodeKind sh:BlankNode ; + sh:property [ + a sh:PropertyShape ; + sh:maxCount "1"^^xsd:integer ; + sh:minCount "1"^^xsd:integer ; + sh:path rdf:first ; + ] ; + ] + ) ; + ] ; + ] + ) ; + . + +uco-owl:disjointUnionOf-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:disjointUnionOf ; + ] ; + sh:targetSubjectsOf owl:disjointUnionOf ; + . + +uco-owl:distinctMembers-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:distinctMembers ; + ] ; + sh:targetSubjectsOf owl:distinctMembers ; + . + +uco-owl:hasKey-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:hasKey ; + ] ; + sh:targetSubjectsOf owl:hasKey ; + . + uco-owl:incompatibleWith-direct-import-shape a sh:PropertyShape ; rdfs:seeAlso ; @@ -285,6 +343,46 @@ uco-owl:incompatibleWith-imported-version-iri-shape sh:targetObjectsOf owl:incompatibleWith ; . +uco-owl:intersectionOf-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:intersectionOf ; + ] ; + sh:targetSubjectsOf owl:intersectionOf ; + . + +uco-owl:members-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:members ; + ] ; + sh:targetSubjectsOf owl:members ; + . + +uco-owl:onProperties-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:onProperties ; + ] ; + sh:targetSubjectsOf owl:onProperties ; + . + +uco-owl:oneOf-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:oneOf ; + ] ; + sh:targetSubjectsOf owl:oneOf ; + . + uco-owl:ontologyIRI-versionIRI-prerequisite-shape a sh:NodeShape ; rdfs:seeAlso ; @@ -293,6 +391,60 @@ uco-owl:ontologyIRI-versionIRI-prerequisite-shape sh:targetSubjectsOf owl:versionIRI ; . +uco-owl:propertyChainAxiom-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:propertyChainAxiom ; + ] ; + sh:targetSubjectsOf owl:propertyChainAxiom ; + . + +uco-owl:rdf-first-subjects-shape + a sh:NodeShape ; + sh:property + [ + a sh:PropertyShape ; + sh:maxCount "1"^^xsd:integer ; + sh:path rdf:first ; + ] , + [ + a sh:PropertyShape ; + sh:minCount "1"^^xsd:integer ; + sh:path rdf:rest ; + ] + ; + sh:targetSubjectsOf rdf:first ; + . + +uco-owl:rdf-rest-subjects-shape + a sh:NodeShape ; + sh:property + [ + a sh:PropertyShape ; + sh:maxCount "1"^^xsd:integer ; + sh:path rdf:rest ; + ] , + [ + a sh:PropertyShape ; + sh:minCount "1"^^xsd:integer ; + sh:path rdf:first ; + ] + ; + sh:targetSubjectsOf rdf:rest ; + . + +uco-owl:unionOf-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:unionOf ; + ] ; + sh:targetSubjectsOf owl:unionOf ; + . + uco-owl:versionIRI-multiversion-shape a sh:PropertyShape ; rdfs:seeAlso ; @@ -310,3 +462,13 @@ uco-owl:versionIRI-nodeKind-shape sh:targetSubjectsOf owl:versionIRI ; . +uco-owl:withRestrictions-subjects-shape + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:withRestrictions ; + ] ; + sh:targetSubjectsOf owl:withRestrictions ; + . + diff --git a/tests/examples/rdf_list_PASS.json b/tests/examples/rdf_list_PASS.json index febdaa31..7462e256 100644 --- a/tests/examples/rdf_list_PASS.json +++ b/tests/examples/rdf_list_PASS.json @@ -1,10 +1,14 @@ { "@context": { + "dash": "http://datashapes.org/dash#", + "ex": "http://example.org/ontology/", "kb": "http://example.org/kb/", "owl": "http://www.w3.org/2002/07/owl#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", - "skos": "http://www.w3.org/2004/02/skos/core#" + "sh": "http://www.w3.org/ns/shacl#", + "skos": "http://www.w3.org/2004/02/skos/core#", + "xsd": "http://www.w3.org/2001/XMLSchema#" }, "@graph": [ { @@ -15,6 +19,14 @@ "@id": "kb:concept-2", "@type": "skos:Concept" }, + { + "@id": "kb:concept-3", + "@type": "skos:Concept" + }, + { + "@id": "kb:concept-4", + "@type": "skos:Concept" + }, { "@id": "kb:ordered-collection-1", "@type": "skos:OrderedCollection", @@ -50,6 +62,130 @@ } } } + }, + { + "@id": "kb:ordered-collection-3", + "@type": "skos:OrderedCollection", + "skos:memberList": { + "@id": "kb:list-1", + "@type": "rdf:List", + "rdf:first": { + "@id": "kb:concept-3" + }, + "rdf:rest": { + "@type": "rdf:List", + "rdf:first": { + "@id": "kb:concept-4" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + } + } + }, + { + "@id": "kb:ordered-collection-4", + "@type": "skos:OrderedCollection", + "skos:memberList": { + "rdf:first": { + "@id": "kb:concept-3" + }, + "rdf:rest": { + "@id": "kb:list-2", + "rdf:first": { + "@id": "kb:concept-4" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + } + } + }, + { + "@type": "owl:AllDifferent", + "owl:distinctMembers": { + "@type": "rdf:List", + "rdf:first": { + "@id": "kb:ordered-collection-1" + }, + "rdf:rest": { + "@type": "rdf:List", + "rdf:first": { + "@id": "kb:ordered-collection-2" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + } + } + }, + { + "@id": "ex:hasGrandparent", + "@type": "owl:ObjectProperty", + "rdfs:isDefinedBy": { + "@id": "https://www.w3.org/TR/2012/REC-owl2-primer-20121211/#Property_Chains" + }, + "owl:propertyChainAxiom": { + "rdf:first": { + "@id": "ex:hasParent" + }, + "rdf:rest": { + "rdf:first": { + "@id": "ex:hasParent" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + } + } + }, + { + "@id": "ex:hasParent", + "@type": "owl:ObjectProperty" + }, + { + "@id": "ex:Person", + "@type": "owl:Class", + "rdfs:comment": "NOTE: This example is excerpted from the OWL 2 Primer only for syntactic reference.", + "rdfs:isDefinedBy": { + "@id": "https://www.w3.org/TR/2012/REC-owl2-primer-20121211/#Keys" + }, + "owl:hasKey": { + "rdf:first": { + "@id": "ex:hasSSN" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + } + }, + { + "@id": "ex:hasSSN", + "@type": "owl:DatatypeProperty", + "rdfs:comment": "NOTE: This example is excerpted from the OWL 2 Primer only for syntactic reference.", + "rdfs:isDefinedBy": { + "@id": "https://www.w3.org/TR/2012/REC-owl2-primer-20121211/#Keys" + } + }, + { + "@id": "dash:DateOrDateTime", + "@type": "rdf:List", + "rdf:first": { + "sh:datatype": "xsd:date" + }, + "rdf:rest": { + "rdf:first": { + "sh:datatype": "xsd:dateTime" + }, + "rdf:rest": { + "@id": "rdf:nil" + } + }, + "rdfs:comment": "An rdf:List that can be used in property constraints as value for sh:or to indicate that all values of a property must be either xsd:date or xsd:dateTime.", + "rdfs:isDefinedBy": { + "@id": "http://datashapes.org/dash" + }, + "rdfs:label": "Date or date time" } ] } diff --git a/tests/examples/rdf_list_XFAIL.json b/tests/examples/rdf_list_XFAIL.json index da81471a..9e188cfe 100644 --- a/tests/examples/rdf_list_XFAIL.json +++ b/tests/examples/rdf_list_XFAIL.json @@ -1,5 +1,6 @@ { "@context": { + "ex": "http://example.org/ontology/", "kb": "http://example.org/kb/", "owl": "http://www.w3.org/2002/07/owl#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", @@ -8,52 +9,75 @@ }, "@graph": [ { - "@id": "kb:concept-3", + "@id": "kb:concept-5", "@type": "skos:Concept" }, { - "@id": "kb:concept-4", + "@id": "kb:concept-6", "@type": "skos:Concept" }, { - "@id": "kb:ordered-collection-3", - "@type": "skos:OrderedCollection", - "skos:memberList": { - "@id": "kb:list-1", + "@id": "kb:concept-7", + "@type": "skos:Concept" + }, + { + "@id": "kb:concept-8", + "@type": "skos:Concept" + }, + { + "@id": "kb:list-1", + "@type": "rdf:List", + "rdfs:comment": "This will trigger a violation error. An OWL Sequence must be a blank node.", + "rdf:first": { + "@id": "kb:concept-5" + }, + "rdf:rest": { "@type": "rdf:List", - "rdf:comment": "This will trigger a violation error. An rdf:first's subject must be a blank node.", "rdf:first": { - "@id": "kb:concept-3" + "@id": "kb:concept-6" }, "rdf:rest": { - "@type": "rdf:List", - "rdf:first": { - "@id": "kb:concept-4" - }, - "rdf:rest": { - "@id": "rdf:nil" - } + "@id": "rdf:nil" } } }, { - "@id": "kb:ordered-collection-4", - "@type": "skos:OrderedCollection", - "skos:memberList": { + "@type": "owl:AllDifferent", + "owl:distinctMembers": { + "@id": "kb:list-1" + } + }, + { + "@type": "owl:AllDifferent", + "owl:distinctMembers": { + "@type": "rdf:List", "rdf:first": { - "@id": "kb:concept-3" + "@id": "kb:concept-7" }, "rdf:rest": { - "@id": "kb:list-2", - "rdf:comment": "This will trigger a violation error. An rdf:first's subject must be a blank node.", + "@id": "kb:list-4", + "rdfs:comment": "This will trigger a violation error. An OWL Sequence must be a blank node.", + "@type": "rdf:List", "rdf:first": { - "@id": "kb:concept-4" + "@id": "kb:concept-8" }, "rdf:rest": { "@id": "rdf:nil" } } } + }, + { + "@id": "ex:someDatatypeProperty", + "@type": "owl:DatatypeProperty" + }, + { + "@id": "ex:IncorrectlyKeyedThing", + "@type": "owl:Class", + "rdfs:comment": "This will trigger a violation error. owl:hasKey has OWL Sequences as its range.", + "owl:hasKey": { + "@id": "ex:someDatatypeProperty" + } } ] } diff --git a/tests/examples/rdf_list_XFAIL_validation.ttl b/tests/examples/rdf_list_XFAIL_validation.ttl index 7784b385..65ab509a 100644 --- a/tests/examples/rdf_list_XFAIL_validation.ttl +++ b/tests/examples/rdf_list_XFAIL_validation.ttl @@ -11,45 +11,90 @@ sh:result [ a sh:ValidationResult ; - sh:focusNode ; - sh:resultMessage "The subject of a triple with rdf:first as predicate must be a blank node." ; + sh:detail [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage 'Node kb:list-1 does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:XoneConstraintComponent ; + sh:sourceShape uco-owl:Sequence-shape ; + sh:value ; + ] ; + sh:focusNode [ + a owl:AllDifferent ; + owl:distinctMembers ; + ] ; + sh:resultMessage "Value does not conform to Shape uco-owl:Sequence-shape. See details for more information." ; + sh:resultPath owl:distinctMembers ; sh:resultSeverity sh:Violation ; - sh:sourceConstraint [ - a sh:SPARQLConstraint ; - rdfs:comment "This requirement is determined from review of the canonical parsing process in Section 3 of the OWL 2 mapping to RDF. Table 5 removes any triple matching the pattern 'x a rdf:List`. All other references throughout Section 3 to rdf:first are identified as blank nodes. Therefore, any non-blank node that is an rdf:List will not be mapped and consumed by the mapping process, making the graph non-conformant with OWL 2 DL."@en ; - rdfs:seeAlso ; - sh:message "The subject of a triple with rdf:first as predicate must be a blank node."@en ; - sh:select """ - SELECT $this - WHERE { - FILTER isIRI($this) - } - """ ; - ] ; - sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; - sh:sourceShape uco-owl:List-shape ; + sh:sourceConstraintComponent sh:NodeConstraintComponent ; + sh:sourceShape [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:distinctMembers ; + ] ; sh:value ; ] , [ a sh:ValidationResult ; - sh:focusNode ; - sh:resultMessage "The subject of a triple with rdf:first as predicate must be a blank node." ; + sh:detail [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage 'Node ex:someDatatypeProperty does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:XoneConstraintComponent ; + sh:sourceShape uco-owl:Sequence-shape ; + sh:value ; + ] ; + sh:focusNode ; + sh:resultMessage "Value does not conform to Shape uco-owl:Sequence-shape. See details for more information." ; + sh:resultPath owl:hasKey ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:NodeConstraintComponent ; + sh:sourceShape [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:hasKey ; + ] ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:detail [ + a sh:ValidationResult ; + sh:focusNode ( + + + ) ; + sh:resultMessage 'Node ( kb:concept-7 kb:concept-8 ) does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:XoneConstraintComponent ; + sh:sourceShape uco-owl:Sequence-shape ; + sh:value ( + + + ) ; + ] ; + sh:focusNode [ + a owl:AllDifferent ; + owl:distinctMembers ( + + + ) ; + ] ; + sh:resultMessage "Value does not conform to Shape uco-owl:Sequence-shape. See details for more information." ; + sh:resultPath owl:distinctMembers ; sh:resultSeverity sh:Violation ; - sh:sourceConstraint [ - a sh:SPARQLConstraint ; - rdfs:comment "This requirement is determined from review of the canonical parsing process in Section 3 of the OWL 2 mapping to RDF. Table 5 removes any triple matching the pattern 'x a rdf:List`. All other references throughout Section 3 to rdf:first are identified as blank nodes. Therefore, any non-blank node that is an rdf:List will not be mapped and consumed by the mapping process, making the graph non-conformant with OWL 2 DL."@en ; - rdfs:seeAlso ; - sh:message "The subject of a triple with rdf:first as predicate must be a blank node."@en ; - sh:select """ - SELECT $this - WHERE { - FILTER isIRI($this) - } - """ ; - ] ; - sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; - sh:sourceShape uco-owl:List-shape ; - sh:value ; + sh:sourceConstraintComponent sh:NodeConstraintComponent ; + sh:sourceShape [ + a sh:PropertyShape ; + sh:node uco-owl:Sequence-shape ; + sh:path owl:distinctMembers ; + ] ; + sh:value ( + + + ) ; ] ; .