Rules
Preprocessing-CopyEquivalentIntersection
| rdfs:label |
Copy owl:intersectionOfs from owl:equivalentClass |
| rdfs:comment |
Copies any intersections within owl:equivalentClass into the host class itself so that subsequent rules convert them further. |
| sh:order |
-1 |
Preprocessing-FlattenIntersectionOf
| rdfs:label |
Flatten owl:intersectionOf |
| rdfs:comment |
Copies the members of an owl:intersectionOf list as superclasses into the host class itself. Subsequent rules then apply. |
| sh:order |
0 |
CreateNodeShapesAndPropertyShapesFromRestrictions
| rdfs:label |
owl:onProperty to sh:property |
| rdfs:comment |
Creates a NodeShape and a sh:property shape for each property that is mentioned in an owl:Restriction. |
| sh:order |
1 |
CreateNodeShapesAndPropertyShapesFromEquivalentClassHasValue
| rdfs:label |
owl:equivalentClass/owl:hasValue to sh:NodeShape with sh:hasValue |
| rdfs:comment |
Creates a sh:property shape for each property that is mentioned in an owl:Restriction. |
| sh:order |
1 |
CreateNodeShapesAndPropertyShapesFromMatchingDomains
| rdfs:label |
rdfs:domain to sh:property |
| rdfs:comment |
Creates a NodeShape and a sh:property shape for each property with matching rdfs:domain. |
| sh:order |
2 |
owlFunctionalProperty2shMaxCount1
| rdfs:label |
owl:FunctionalProperty to sh:maxCount 1 |
| rdfs:comment |
For each relevant property that is owl:FunctionalProperty, create sh:maxCount of 1 (unless there is an OWL cardinality restriction). |
| sh:order |
3 |
rdfsRange2shNode
| rdfs:label |
rdfs:range with IRI to sh:class or sh:datatype |
| rdfs:comment |
For each relevant property that has an rdfs:range, creates an sh:node if the range yielded a NodeShape that has an sh:hasValue constraint, instead of an sh:class |
| sh:order |
4 |
owlSomeValuesFrom2shMinCount1
| rdfs:label |
owl:someValuesFrom to sh:minCount 1 |
| rdfs:comment |
For each owl:someValuesFrom restriction, create a corresponding sh:minCount 1 constraint. |
| sh:order |
4 |
owlUnionOfIRIs2rdfsSubClassOf
| rdfs:label |
owl:unionOf IRIs to rdfs:subClassOf |
| rdfs:comment |
For each owl:unionOf that only consists of named classes, move these classes into "normal" rdfs:subClassOf triples. |
| sh:order |
4 |
owlSomeValuesFromIRI2dashHasValueWithClass
| rdfs:label |
owl:someValuesFrom with IRI to dash:hasValueWithClass |
| rdfs:comment |
For each owl:someValuesFrom restriction with an IRI, create a corresponding dash:hasValueWithClass constraint. |
| sh:order |
4 |
owlUnionOfIntersections2shOr
| rdfs:label |
owl:unionOf of class expressions to sh:or |
| rdfs:comment |
For each owl:unionOf whose members are ANONYMOUS class expressions, create a corresponding sh:or disjunction, with one member node shape per union member carrying that member's cardinality restrictions as property shapes.
owlUnionOfIRIs2rdfsSubClassOf handles the case where every member is a named class, by flattening them into rdfs:subClassOf. It deliberately does nothing when a member is anonymous, and nothing else did either, so a union of class expressions produced NO constraint at all: the disjunction was silently dropped and the resulting shape accepted anything.
That is the shape a UML <> takes when it is encoded by ISO 19150-2: one member per alternative, each asserting a cardinality on its own property and cardinality 0 on the others. Measured on ASAM OpenSCENARIO XML V1.4.0, 48 classes carry such a union - 177 members over 1017 restrictions - and the converted shapes contained zero sh:or, sh:xone, sh:not or sh:and.
sh:or, not sh:xone: owl:unionOf is inclusive disjunction, and SHACL's sh:or is its counterpart (SHACL Sec. 4.6.1; OWL 2 Mapping to RDF Graphs, Table 13). sh:xone would be wrong twice over - it is exclusive, and it rejects a valid document whenever the alternatives are all optional, which 9 of those 177 members are (they carry only owl:maxQualifiedCardinality, so choosing nothing is permitted). Verified with pyshacl over both shapes of group.
Every restriction in a member is emitted, including the cardinality 0 exclusions, because those are what make each member discriminating: without them every member is trivially satisfiable and the disjunction always holds.
Counts are cast with xsd:integer, as every other cardinality rule here does: sh:minCount and sh:maxCount must be xsd:integer literals (SHACL Sec. 4.2), and OWL writes these as xsd:nonNegativeInteger. Passing the value through unchanged produces shapes a conforming processor refuses to load.
The rule asserts one sh:or value per member and relies on the caller to gather them into the RDF list SHACL requires, exactly as sh:ignoredProperties does and for the same reason - a SHACL rule cannot CONSTRUCT a list of unknown length.
It deliberately does not fire for a class carrying more than one union, because that gathering is per subject and two unions would merge into a single disjunction, weakening both. Such a class is left unconstrained rather than wrongly constrained. |
| sh:order |
4 |
owlAllValuesFrom2shClassOrDatatype
| rdfs:label |
owl:allValuesFrom with IRI to sh:class or sh:datatype |
| rdfs:comment |
For each owl:allValuesFrom restriction, create a corresponding sh:class or sh:datatype constraint. |
| sh:order |
4 |
owlOneOf2shIn
| rdfs:label |
owl:oneOf on a datatype range to sh:in |
| rdfs:comment |
For each relevant property whose rdfs:range is a datatype enumerated by owl:oneOf, create an sh:in constraint listing the permitted values. Without this the enumeration is lost: the range is an rdfs:Datatype, so no sh:class or sh:datatype constraint can express which literals are allowed. |
| sh:order |
5 |
rdfsRangeLiteral2shNodeKind
| rdfs:label |
rdfs:range rdfs:Literal to sh:nodeKind sh:Literal |
| rdfs:comment |
For each relevant property that has an rdfs:range with value rdfs:Literal, create sh:nodeKind constraint. |
| sh:order |
5 |
rdfsRange2shClassOrDatatype
| rdfs:label |
rdfs:range with IRI to sh:class or sh:datatype |
| rdfs:comment |
For each relevant property that has an rdfs:range, create sh:class or sh:datatype constraint unless it already exists (from a restriction). A range counts as a datatype when it is declared as an rdfs:Datatype, when it is an XML Schema built-in, or when it is rdf:langString; testing the range itself rather than matching a fixed list of IRIs means any rdfs:Datatype - including one defined by owl:oneOf - yields sh:datatype. sh:class is never satisfied by a literal (SHACL Core, Sec. 4.1.1), so emitting it for a datatype range produces a constraint that can only fail. |
| sh:order |
5 |
owlQualifiedCardinalityOnClass2shQualifiedMinMaxCount
| rdfs:label |
owl:qualifiedCardinality with owl:onClass to sh:qualifiedMax/MinCount |
| rdfs:comment |
For each owl:qualifiedCardinality restriction on an IRI class, create a corresponding (new) sh:qualifiedMax/MinCount constraint, unless the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlMaxQualifiedCardinalityOnClass2shQualifiedMaxCount
| rdfs:label |
owl:maxQualifiedCardinality with owl:onClass to sh:qualifiedMaxCount |
| rdfs:comment |
For each owl:maxQualifiedCardinality restriction on an IRI class, create a corresponding (new) sh:qualifiedMaxCount constraint, unless the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlMinQualifiedCardinalityOnDataRange2shQualifiedMinCount
| rdfs:label |
owl:minQualifiedCardinality with owl:onDataRange to sh:qualifiedMinCount |
| rdfs:comment |
For each owl:minQualifiedCardinality restriction on an IRI datatype, create a corresponding (new) sh:qualifiedMinCount constraint. |
| sh:order |
6 |
owlMinQualifiedCardinalityOnClass2shQualifiedMinCount
| rdfs:label |
owl:minQualifiedCardinality with owl:onClass to sh:qualifiedMinCount |
| rdfs:comment |
For each owl:minQualifiedCardinality restriction on an IRI class, create a corresponding (new) sh:qualifiedMinCount constraint, unless the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlMaxQualifiedCardinalityOnClass2shMaxCount
| rdfs:label |
owl:maxQualifiedCardinality with owl:onClass to sh:maxCount |
| rdfs:comment |
For each owl:maxQualifiedCardinality restriction on an IRI class, create a corresponding sh:maxCount constraint, if the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlQualifiedCardinalityOnDataRange2shMinMaxCount
| rdfs:label |
owl:qualifiedCardinality with owl:onDataRange to sh:max/minCount |
| rdfs:comment |
Data-property counterpart of owlQualifiedCardinalityOnClass2shMinMaxCount. For each owl:qualifiedCardinality restriction whose owl:onDataRange is an IRI identical to the property's rdfs:range, create plain sh:minCount and sh:maxCount. In OWL 2 a data property cardinality restriction uses owl:onDataRange exactly as an object property restriction uses owl:onClass (OWL 2 Web Ontology Language Structural Specification, Sec. 8.5 'Data Property Cardinality Restrictions'; Mapping to RDF Graphs, Sec. 3.2). When the qualifying datatype equals the property's global range (already mapped to sh:datatype by rdfsRange2shClassOrDatatype), the qualification is redundant, so - symmetric to the owl:onClass handling - it collapses to plain sh:minCount/sh:maxCount rather than sh:qualifiedMinCount/sh:qualifiedMaxCount. |
| sh:order |
6 |
owlMinCardinality2shMinCount
| rdfs:label |
owl:minCardinality to sh:minCount |
| rdfs:comment |
For each owl:minCardinality restriction, create a corresponding sh:minCount constraint. |
| sh:order |
6 |
owlMaxQualifiedCardinalityOnDataRange2shMaxCount
| rdfs:label |
owl:maxQualifiedCardinality with owl:onDataRange to sh:maxCount |
| rdfs:comment |
Data-property counterpart of owlMaxQualifiedCardinalityOnClass2shMaxCount. For each owl:maxQualifiedCardinality restriction whose owl:onDataRange is an IRI identical to the property's rdfs:range, create a plain sh:maxCount. In OWL 2 a data property cardinality restriction uses owl:onDataRange exactly as an object property restriction uses owl:onClass (OWL 2 Web Ontology Language Structural Specification, Sec. 8.5 'Data Property Cardinality Restrictions'; Mapping to RDF Graphs, Sec. 3.2). When the qualifying datatype equals the property's global range (already mapped to sh:datatype by rdfsRange2shClassOrDatatype), the qualification is redundant, so - symmetric to the owl:onClass handling - it collapses to a plain sh:maxCount rather than sh:qualifiedMaxCount. |
| sh:order |
6 |
owlMinQualifiedCardinalityOnClass2shMinCount
| rdfs:label |
owl:minQualifiedCardinality with owl:onClass to sh:minCount |
| rdfs:comment |
For each owl:minQualifiedCardinality restriction on an IRI class, create a corresponding sh:minCount constraint, if the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlQualifiedCardinalityOnClass2shMinMaxCount
| rdfs:label |
owl:qualifiedCardinality with owl:onClass to sh:max/minCount |
| rdfs:comment |
For each owl:qualifiedCardinality restriction on an IRI class, create corresponding sh:max/minCount constraints, if the owl:onClass is identical to the rdfs:range of the property. |
| sh:order |
6 |
owlQualifiedCardinalityOnDataRange2shQualifiedMinMaxCount
| rdfs:label |
owl:qualifiedCardinality with owl:onDataRange to sh:qualifiedMax/MinCount |
| rdfs:comment |
For each owl:qualifiedCardinality restriction on an IRI datatype, create a corresponding (new) sh:qualifiedMax/MinCount constraint. |
| sh:order |
6 |
owlMaxCardinality2shMaxCount
| rdfs:label |
owl:maxCardinality to sh:maxCount |
| rdfs:comment |
For each owl:maxCardinality restriction, create a corresponding sh:maxCount constraint. |
| sh:order |
6 |
owlMinQualifiedCardinalityOnDataRange2shMinCount
| rdfs:label |
owl:minQualifiedCardinality with owl:onDataRange to sh:minCount |
| rdfs:comment |
Data-property counterpart of owlMinQualifiedCardinalityOnClass2shMinCount. For each owl:minQualifiedCardinality restriction whose owl:onDataRange is an IRI identical to the property's rdfs:range, create a plain sh:minCount. In OWL 2 a data property cardinality restriction uses owl:onDataRange exactly as an object property restriction uses owl:onClass (OWL 2 Web Ontology Language Structural Specification, Sec. 8.5 'Data Property Cardinality Restrictions'; Mapping to RDF Graphs, Sec. 3.2). When the qualifying datatype equals the property's global range (already mapped to sh:datatype by rdfsRange2shClassOrDatatype), the qualification is redundant, so - symmetric to the owl:onClass handling - it collapses to a plain sh:minCount rather than sh:qualifiedMinCount. |
| sh:order |
6 |
owlMaxQualifiedCardinalityOnDataRange2shQualifiedMaxCount
| rdfs:label |
owl:maxQualifiedCardinality with owl:onDataRange to sh:qualifiedMaxCount |
| rdfs:comment |
For each owl:maxQualifiedCardinality restriction on an IRI datatype, create a corresponding (new) sh:qualifiedMaxCount constraint. |
| sh:order |
6 |
owlSomeValuesFromAllValuesFrom2dashHasValueWithClass
| rdfs:label |
owl:someValuesFrom with IRI to dash:hasValueWithClass |
| rdfs:comment |
For each owl:someValuesFrom restriction combined with an owl:allValuesFrom on an IRI, create a corresponding dash:hasValueWithClass constraint using a path expression.
For example:
ex:ConstitutionalOwner
a owl:Class ;
rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty ex:isPlayedBy ;
owl:someValuesFrom [
a owl:Restriction ;
owl:allValuesFrom ex:StockholdersEquity ;
owl:onProperty ex:holdsEquityIn ;
] ;
] .
becomes
ex:ConstitutionalOwner
a sh:NodeShape ;
sh:property [
sh:path ( ex:isPlayedBy ex:holdsEquityIn ) ;
dash:hasValueWithClass ex:StockholdersEquity ;
] . |
| sh:order |
7 |
owlHasValue2shHasValue
| rdfs:label |
owl:hasValue to sh:hasValue |
| rdfs:comment |
For each owl:hasValue restriction, create a corresponding sh:hasValue constraint. |
| sh:order |
8 |
closeNodeShapes
| rdfs:label |
Close NodeShapes |
| rdfs:comment |
Make all sh:NodeShapes closed Shapes |
| sh:order |
10 |
addIgnoredPropertiesFromSubclassesAndSuperClasses
| rdfs:label |
Add sh:ignoredProperties with properties from subClasses and super classes. |
| rdfs:comment |
For every ancestor or descendant class of this class, fetch the paths of the associated property shape,
and add this property as an sh:ignoredProperty value of this class.
NOTE : SHACL-Play does a post-processing on this to convert the values of sh:ignoredProperties into an RDF List.
|
| sh:order |
10 |
shPropertyShapeCleanUp
| rdfs:label |
sh:property shape clean up |
| rdfs:comment |
For each value of sh:property, add a rdf:type sh:PropertyShape triple. |
| sh:order |
100 |