When and how to use classes as values for properties? What are advantages and drawbacks? What are different approachs and workarounds? Which solutions are in OWL DL (and hence OWL Lite) and which solutions are in OWL Full?
Suppose we want to annotate animal images with the classes
describing the animal
species. We want to be able to say that an image of a
Lion
is also
an image of a Mammal
(For example, when retrieving all images of
mammals from a repository, we want images of lions to be included
in the results).
We consider animals to be subjects of the images and would like to
use the Dublin Core property dc:subject
for this annotation.
This issue arises in general when we have a hierarchy of concepts and would like to use it as a terminology to annotate other classes or individuals. Consider using a hierarchy of book subjects to annotate books or linking classes or individuals in an ontology to the corresponding concepts in a standard reference terminology (e.g., UMLS is such standard reference terminology for many medical applications).
In the first approach, we can simply use classes from the subject hierarchy
as values for properties (in our example, as values for the
dc:subject
property). We can define a class AnimalImage
of all
images of animals.
Here is a definition of an individual that is an instance of the
AnimalImage
class with the corresponding subject:
<AnimalImage rdf:ID="LionImage">
<dc:subject rdf:resource="#Lion"/>
</Image>
where the class Lion
is defined in the following way:
<owl:Class rdf:ID="Lion">
<rdfs:subClassOf>
<owl:Class rdf:about="#Mammal"/>
</rdfs:subClassOf>
</owl:Class>
Considerations when choosing approach 1:
Lion
(the subject of the
LionImage
individual) is a subclass of Mammal
.dc:subject
property for the AnimalImage
class to the class
Animal
and its subclasses, we will need to create another class (a metaclass) that
will have the class Animal
and its subclasses as instances:
AnimalClass
is a class, which is a subclass of
owl:Class
(Any class that has other classes as instances
must be a subclass of owl:Class
)<owl:Class rdf:ID="AnimalClass">
<rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
</owl:Class>
Lion
(and other subclasses of the
Animal
class) have AnimalClass
as its type:<AnimalClass rdf:ID="Lion">
<rdfs:subClassOf>
<AnimalClass rdf:about="#Mammal"/>
</rdfs:subClassOf>
</AnimalClass>
AnimalImage
has AnimalClass
as a
range restriction for the dc:subject
property:<owl:Class rdf:ID="AnimalImage">
<rdfs:subClassOf>
<owl:Restriction>
<owl:allValuesFrom rdf:resource="#AnimalClass"/>
<owl:onProperty>
<owl:ObjectProperty rdf:about="dc:subject"/>
</owl:onProperty>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
dc:subject
values or do not care that you need to have subjects as instances of a subclass
of owl:Class
to implement this restriction.
One of the ways to avoid having the resulting ontology in OWL Full, is to create a set of individuals to represent the subjects. There are a couple of possible options.
dc:subject
property. Thus, we will have, for example, an individual
LionSubject
that will be an instance of the Lion
class. We can
then use the
LionSubject
as the value of the property dc:subject
for the LionImage
individual:<Lion rdf:ID="LionSubject"/>
Subject
and make
all the subjects to be individuals that are instances of this
class Concept
:<Concept rdf:ID="LionSubject"/>We can link these subjects to the classes in the hierarchy of
Animal
classes using rdf:isDefinedBy
property:<Subject rdf:ID="LionSubject">
<rdfs:isDefinedBy rdf:resource="#Lion"/>
</Subject>
In both cases, the definition of the LionImage
refers
to the LionSubject
individual (which will have a different rdf:type
depending on which
option of the two above you choose)
<AnimalImage rdf:ID="LionImage">
<dc:subject rdf:resource="#LionSubject"/>
</AnimalImage>
LionSubject
individual defined above and, for example, a
MammalSubject
individual,
which is an instance of Mammal
:<Mammal rdf:ID="MammalSubject"/>(or
rdfs:isDefinedBy
Mammal
:<Subject rdf:ID="MammalSubject">)
<rdfs:isDefinedBy rdf:resource="#Mammal"/>
</Subject>
rdfs:isDefinedBy
definitions. A general-purpose reasoner will not be able to use
this information
directly. Note however that with option 1, the individual
LionSubject
is also an instance of the Mammal
class. Therefore, if we ask
for all images where dc:subject
is an instance of
the Mammal
class we will get the images that are annotated with
LionSubject
.Lion
has an
instance that
is the subject lion. Creating an instance of the Lion
class to represent a specific Lion at the zoo would be
inconsistent with this
interpretation. Therefore, we will need to have a different class to serve
as type for lions at the zoo. Similarly, even with the second
option, creating
an individual LionIndividual
representing a specific lion at
the zoo as an instance of the Lion
class, will be inconsistent
with most interpretations of rdfs:isDefinedBy
.dc:subject
property for the class AnimalImage
is straightforward. For the
first option, we define a restriction that states that all values
of the dc:subject
property are instances of the class Animal
:<owl:Class rdf:ID="AnimalImage">For the second option, we restrict the values of the
<rdfs:subClassOf>
<owl:Restriction>
<owl:allValuesFrom rdf:resource="#Animal"/>
<owl:onProperty>
<owl:ObjectProperty rdf:about="dc:subject"/>
</owl:onProperty>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
dc:subject
property to the instances of the class Subject
:
<owl:Class rdf:ID="AnimalImage">
<rdfs:subClassOf>
<owl:Restriction>
<owl:allValuesFrom rdf:resource="#Subject"/>
<owl:onProperty>
<owl:ObjectProperty rdf:about="dc:subject"/>
</owl:onProperty>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
Both options for this approach are in OWL DL and may be good ones to use if staying in OWL DL is important. The approach has a potential disadvantage of having actual subject values be unrelated to one another and hence not allowing a general-purpose reasoner to relate images of mammals to images of lions, for example. You need to maintain consistency between the set of classes representing subjects and the set of corresponding individuals.
rdfs:subclassOf
to organize the subject hierarchyWe can take the second option in Approach 2, and take it one step further, creating explicit relations between different subjects, which will re-create the hierarchy for animals that we have in mind:
<owl:TransitiveProperty rdf:ID="parentSubject">
<rdfs:range rdf:resource="#Subject"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
<rdfs:domain rdf:resource="#Subject"/>
</owl:TransitiveProperty>
<Subject rdf:ID="LionSubject">
<parentSubject rdf:resource="#MammalSubject"/>
</Subject>
AnimalSubject
is a
parentSubject
of LionSubject
parentSubject
property—are consistent
with each otherThis approach may be a good one to use if staying within OWL DL is important. It also allows you to use a DL reasoner to infer transitive relationships between subjects. It does carry the penalty of having two parallel "hierarchies."
Another way to stay in OWL DL is to use classes as values for annotation properties:
<owl:AnnotationProperty rdf:about="&dc;subject"/> <AnimalImage rdf:ID="LionImage">
<dc:subject rdf:resource="#Lion"/>
</AnimalImage>
dc:subject
(or another property you want to use) is defined elsewhere as an
object property
or a datatype property, it cannot be used as an annotation property.AnimalImage
must all
be subclasses of the Animal
class.This approach allows you to use classes directly as property values while staying in OWL DL. However, the properties that will have classes as values will have to be defined as annotations and therefore cannot have any additional restrictions defined on them (and should not be declared as object or datatype properties elsewhere). DL reasoners will not use values of annotation properties.