Using Classes As Property Values (version 2)

General issue

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?

Use case example

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.

Other use case scenarios

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).


Approach 1: using classes directly as values

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"/>

where the class Lion is defined in the following way:

 <owl:Class rdf:ID="Lion">
<owl:Class rdf:about="#Mammal"/>

Considerations when choosing approach 1:

OWL code for approach 1

[RDF/XML abbrev] [N3] [Abstract syntax]

Summary for approach 1

This approach is a good one to use if you care about simplicity, do not have to be in OWL DL, and either do not need to limit the range of the 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.

Approach 2: Creating a hierarchy of subjects and a parallel set of subject individuals

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"/>

Considerations when choosing approach 2:

OWL code for approach 2

[RDF/XML abbrev] [N3] [Abstract syntax]

Summary of approach 2

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.

Approach 3: using a property other than rdfs:subclassOf to organize the subject hierarchy

We 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=""/>
<rdfs:domain rdf:resource="#Subject"/>
<Subject rdf:ID="LionSubject">
<parentSubject rdf:resource="#MammalSubject"/>

Considerations when choosing Approach 3

OWL code for approach 3

[RDF/XML abbrev] [N3] [Abstract syntax]

Summary of Approach 3

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."

Approach 4: using classes as values for annotation properties

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"/>

Considerations when choosing Approach 4

OWL code for approach 4

[RDF/XML abbrev] [N3] [Abstract syntax]

Summary of Approach 4

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.