ShEx/Obsolete/ShEx vs OWL
Obsolete - please see ShEx Primer
ShEx vs OWL
The main difference is that OWL is tailored to describe a domain while Shape Expressions are tailored to describe RDF graphs. The domain of discourse of OWL is more related to the problem domain in which one is working like people, organizations, etc. while the domain of discourse of Shape Expressions is the RDF graph that one is trying to describe.
Apart from that, OWL is based on Open World Assumption and Non-Unique Name Assumption while Shape Expressions employ a Closed World and Unique Name assumption. This feature makes more difficult to use OWL as a constraint validation language as has been documented, for example, in this paper.
As a simple example, we can try to express the Shape:
:UserShape { foaf:name xsd:string | foaf:givenName xsd:string+, foaf:familyName xsd:string }
which means that a :UserShape
has either exactly one foaf:name
, or a combination
of one or more foaf:giveName
and exactly one foaf:fammilyName
If we have:
:mary foaf:name "Mary Smith" . :john foaf:givenName "john" ; foaf:givenName "johnny" ; foaf:familyName "Smith" .
A Shape Expressions processor infers that :mary
and :john
have shape :UserShape
.
But if we have:
:mary2 foaf:name "Mary1" , "Mary2" . :john2 foaf:givenName "john"; foaf:familyName 2 .
the system will not infer that mary2
or john2
have :UserShape
Try it.
In OWL we can express a class as the union of two other classes, so we could express UserShapeClass
:
:UserShapeClass owl:equivalentClass [ rdf:type owl:Class ; owl:unionOf ( :HasNameClass :HasGivenNameFamilyNameClass ) ] .
and then, we can express :HasNameClass
as:
:HasNameClass owl:equivalentClass [ a owl:Class ; owl:intersectionOf ( [ rdf:type owl:Restriction ; owl:onProperty foaf:name ; owl:someValuesFrom xsd:string ; ] [ rdf:type owl:Restriction ; owl:onProperty foaf:name ; owl:cardinality 1 ] ) ] .
In the previous definition we declare that :HasNameClass
has exactly one (cardinality = 1) foaf:name
with type xsd:string
.
In the same way, we can declare HasGivenNameFamilyNameClass
as:
:HasGivenNameFamilyNameClass owl:equivalentClass [ a owl:Class ; owl:intersectionOf ([ rdf:type owl:Restriction ; owl:onProperty foaf:givenName ; owl:someValuesFrom xsd:string ] [ rdf:type owl:Restriction ; owl:onProperty foaf:familyName ; owl:someValuesFrom xsd:string ] [ rdf:type owl:Restriction ; owl:onProperty foaf:familyName ; owl:cardinality 1 ] ) ] .
With the previous definitions, if we declare:
:mary foaf:name "Mary Smith" . :johnSmith foaf:givenName "john" ; foaf:familyName "Smith" .
the system does not infer that :mary
or :johnSmith
belong to :UserShapeClass
In this case, this can be solved if we add:
foaf:name a owl:FunctionalProperty . foaf:familyName a owl:FunctionalProperty .
which declares that one node does not have more than one value for propery foaf:name
and foaf:familyName
. Now, the declaration:
:mary2 foaf:name "Mary1" , "Mary2" .
is detected as an inconsistency. If we remove the inconsistencies, the system infers that :mary
and :john
have type :UserShapeClass