ShEx/Obsolete/ShEx vs OWL

From Semantic Web Standards

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