When and how to use classes as values for properties? What are advantages and drawbacks? What are different approaches and workarounds? Which solutions are in OWL DL (and hence OWL Lite) and which solutions are in OWL Full but not in OWL DL?
Suppose we have a set of books about animals and want to annotate each book
with its subject, which a particular animal (or animals) that it talks about.
Further, we want to be able to say that a book about lions is also a book about
mammals (For example, when retrieving all books about mammals from a repository,
we want books about lions to be included in the results). We consider animals
to be subjects of the books 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 different genre to annotate music CDs, 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 AnimalBook
of all books about
animals.
Here is a definition of an individual (a specific book that we are annotating)
that is an instance of the AnimalBook
class with the corresponding
subject (for simplicity, we assume that each book discusses only one class of
animals):
<AnimalBook rdf:ID="LionBook">
<dc:subject rdf:resource="#Lion"/>
</AnimalBook>
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>
Lion
(the subject of the LionBook
individual) is a subclass of Mammal
.dc:subject
property for the AnimalBook
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>
AnimalBook
has AnimalClass
as an
allValuesFrom
1 range restriction
for the dc:subject
property:<owl:Class rdf:ID="AnimalBook">
<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>
[RDF/XML abbrev] [N3] [Abstract syntax]
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.
We can treat the hierarchy of animal species as a hierarchy of subjects, create
individuals corresponding to all the subjects and use these individuals as values
for the 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 LionBook
individual:
<Lion rdf:ID="LionSubject"/>
In this case, the definition of the LionBook
refers to the LionSubject
individual
<AnimalBook rdf:ID="LionBook">
<dc:subject rdf:resource="#LionSubject"/>
</AnimalBook>
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.
LionSubject
individual defined above and, for example, a MammalSubject
individual,
which is an instance of Mammal
:<Mammal rdf:ID="MammalSubject"/>An application trying to utilize this relation (for example, to extract all books about lions when asked for books about mammals), will need to be aware of this specific approach and know to trace back to the corresponding classes, their subclasses, and respective individuals. A general-purpose reasoner will not be able to use this information directly. Note however that the individual
LionSubject
is also an instance of the Mammal
class.
Therefore, if we ask for all books where dc:subject
is an instance
of the Mammal
class we will get the books that are annotated
with LionSubject
.dc:subject
property for the class AnimalBook
is straightforward. We define
an allValuesFrom
1 restriction that
states that all values of the dc:subject
property are instances
of the class Animal
:<owl:Class rdf:ID="AnimalBook">
<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>
[RDF/XML abbrev] [N3] [Abstract syntax]
This approach results in an OWL DL ontology and may be a good one 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 books with a subject mammal to books with a subject lions, for example. You need to maintain consistency between the set of classes representing subjects and the set of corresponding individuals. If the subject hierarchy is not solely a terminology (e.g., you need to represent specific animals), you will need to create a separate class hierarchy for that.
rdfs:subclassOf
to organize the subject hierarchyWe can create a single class Subject
and make all the subjects
to be individuals that are instances of this class Subject
:
<Subject rdf:ID="LionSubject"/>
We can then create 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
dc:subject
property for the class AnimalBook
is straightforward. We restrict
the values of the dc:subject
property to the instances of the
class Subject
:
<owl:Class rdf:ID="AnimalBook">
<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>
parentSubject
property—are consistent
with each other[RDF/XML abbrev] [N3] [Abstract syntax]
This 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"/>
<AnimalBook rdf:ID="LionBook">
<dc:subject rdf:resource="#Lion"/>
</AnimalBook>
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.AnimalBook
must all
be subclasses of the Animal
class.[RDF/XML abbrev] [N3] [Abstract syntax]
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.
[1] Using allValuesFrom
restriction for the
book's subject implies that instances of the class AnimalBook
can
have only animals as values for the dc:subject
property. If we
want to allow other terms to be listed as subjects, a someValuesFrom
restriction will be appropriate.