(Capturing a few conclusions about RDF idioms from some recent experiments….)
In object orientation and especially UML, relationships are typed at both ends. So, in RDF, I used to identify with diligence the domain and range for most properties, as in:
ex:contains a owl:ObjectProperty ; rdfs:domain ex:Container ; rdfs:range ex:Contained .
Because an RDF processor can infer the class of the domain and range objects, I had to be quite precise. That tended to have rippling effects on the design. In particular, a herd of subproperties expressed the same semantic relation but took different domain and range classes. Of course, the domain and range classes of the subproperties had to inherit from the domain and range classes of the base property. The result was a dissatisfying explosion of names for syntactic rather than semantic reasons.
Semantic Web for the Working Ontologist (helpfully recommended by Bob DuCharme) devotes a sidebar (pages 101 to 102) to cautioning against this common tendency among object-oriented programmers. In essence, the recommendation is to use domain or range only when inference of the class will be useful.
Well, hush my puppies.
Still, it would seem like a step backward if the RDF model carried less information than a UML model. Fortunately (and rather obviously in retrospect (as usual)), the constraints can be expressed directly:
ex:Container a owl:Class ; rdfs:subClassOf [ owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty ex:contains ; owl:allValuesFrom ex:Contained ] ... cardinality or type restrictions on other properties ... ) ] . ex:contains a owl:ObjectProperty .
In this idiom, each class maintains the type and cardinality constraints on its properties. The same property can be constrained differently by different classes. The constraints on properties don’t license uninteresting inferences. The idiom is a bit verbose, but that’s a small price to pay for the benefits.
The other idiom that I’ve adopted recently is to prefer union to subclass assertions for abstract classes. After all, an abstract class is exactly equivalent to its list of subclasses. For instance, the alternative to:
ex:DocumentType a owl:Class ; rdfs:subClassOf ex:Container . ex:MarkupType a owl:Class ; rdfs:subClassOf ex:Container .
ex:Container a owl:Class ; owl:unionOf (ex:DocumentType ex:MarkupType) .
The idiom expresses the intent of the designer more precisely. The only concern would be if the union effectively closed the set of subclasses. That would be true if a new union assertion with a superset of members creates a self-contradictory model — something I haven’t investigated yet.
Anyway, other idioms? Or, better idioms for typing relations?