This article is the first in a short series of articles that expands the code example from Chapter 5 of Semantic Web Programming to include some of the features of OWL 2. The code can be downloaded from here (zip, 7z, tar.gz), including an Eclipse project and all dependencies. This article focuses on how the semantics of qualified cardinality restrictions are interpreted and applied in a reasoner that supports most of OWL 2 semantics (Pellet 2.0 RC6 – see the Pellet documentation for a full list of the semantics supported in each release candidate).
For a more in-depth exploration of OWL and Semantic Web, feel free to reference the book as needed or buy a copy so you can learn about the cool stuff in this article and more.
Recall from Chapter 4 in the book that cardinality restrictions are a way to specify the number of statements that describe an individual with a unique value that have a particular property as the predicate of each statement… e.g. a person has exactly one date of birth or a parent has at least one child. Qualified cardinality restrictions (QCRs) allow you to further describe that set of statements by specifying the number of those statements which should have an individual of a particular class or value of a particular data range as the object of the statement… e.g. a molecule of water has three atoms, exactly two of which are hydrogen atoms and one of which is an oxygen atom – or a person has exactly two parents, one of which is male and the other which is female. Qualified cardinality restrictions can be on both object and datatype properties; however, RC6 of Pellet 2.0 only currently supports them for object properties.
Qualified cardinality restrictions are convenient because they avoid the need to add extra properties to an ontology in order to make cardinality restrictions specific to the range of the statements to which they apply. Without QCRs, specifying that a person has a mother and a father would likely require gender-specific properties like hasMother and hasFather. These predicates may be useful, but they are not necessary – at least when we can use QCRs instead.
For this example, we are reusing the code from Chapter 5’s code project with only a few minor modifications (we changed the way we create the Pellet reasoner-enabled model). The major difference is that we are using the latest version of Pellet (2.0RC6), which supports most of the semantics of the OWL 2 vocabulary. So, let’s get started!
Our goal is to express (in our ontology) the fact that a mammal has two parents, one of which is male and one of which is female. For our purposes, the property hasParent is an object property and male and female are classes. We will extend the class mammal with the axioms for the QCR definition. The excerpt of turtle that expresses these concepts is below (taken from qcr_1.ttl):
The class definition for ex:Mammal now contains three restrictions, the first specifies that all mammals have exactlly two statements with ex:hasParent as the predicate and a unique individual as the object, the second specifies that one of the statements with ex:hasParent as the predicate must have an object that is an instance of the class ex:Female and the third is the same only for ex:Male. Now that we have the capacity to describe parents, let’s define a couple of instances of canine and associate them with our example pooch from before: Daisy.
We’ve described ex:Kujo and ex:Lady and stated that they are the parents of ex:Daisy. Run the program in the project (execute the main method with the parameters qcr_1.ttl TURTLE qcr_out.txt owl) and take a look at the results. You will notice that the inverse property as well as the subproperty and subclass semantics have been applied; however, no entailments have been made as a result of the QCR. You may expect that Pellet should infer that Lady is female because Kujo is a male, and the two of them are the parents of Daisy. This after all, is sort of the goal we are going for in defining this restriction in our ontology. But, we haven’t described the situation completely enough for the reasoner to assert this new fact. For all we (and the reasoner) know, Lady is the same individual as Kujo (recall the no unique names assumption from Chapter 4?), meaning that they could both be male. Also, we haven’t said anything about the relationship between the classes ex:Male and ex:Female. For all we know an individual could be both male and female. Because of these facts, the reasoner cannot make any correct conclusions about Lady despite our QCR on ex:Mammal.
To correct this situation and enable Pellet to make the expected conclusions, we must assert two facts: 1) ex:Kujo and ex:Lady are different individuals and 2) ex:Male and ex:Female are disjoint classes. These atoms are below (and are added in the file qcr_2.ttl):
Both owl:disjointWith and owl:differentFrom are symmetric properties, so they only need to be asserted in one direction. Run the program with the input file qcr_2.ttl and take a look at the results. Voila! Lady is now an instance of the class ex:Female:
This worked because we asserted that Lady and Kujo are different individuals, meaning that Lady has to be the other parent of Daisy. Also, we asserted that male and female are disjoint classes, meaning that Kujo cannot be female, and that the only individual who can be the female parent of Daisy is Lady. This latter point is tricky, if male and female were not disjoint, Kujo could be both the female parent as well as the male parent of Daisy, allowing Lady to be neither male nor female while still leaving the restriction satisfied (2 parents, one female parent, one male parent).
Now, let’s play around a bit. As we saw from the previous example, the semantics of our QCR plus the fact that male and female are disjoint classes and Lady and Kujo are different individuals is enough for the reasoner to entail that Lady is female (even though we didn’t explicity state that). So, what happens when there are more than two parents of Daisy? Let’s take a look at how the QCR semantics can be applied in this situation. The file qcr_3.ttl has the following modifications to it:
Notice that all we’ve done is described a new individual ex:KingKujo and stated that he is a parent of ex:Daisy. Run the program with the input qcr_3.ttl and take a look at the output file. This is really interesting stuff! The reasoner combined the inverse-of semantics of ex:isParentOf with the fact that there are two male parents of ex:Daisy to infer that ex:KingKujo has to be the same individual as ex:Kujo. Notice that because the owl:sameAs statement now exists between ex:Kujo and ex:KingKujo, both individuals are described by the union of the statements about each:
In this ontology, if ex:Kujo and ex:KingKujo are in fact not the same individual, the KB will have reached an inconsistent state. Two individuals who are different will also be the same. Just to drive this point home, lets see what happens if we explicity state that ex:Kujo and ex:KingKujo are different individuals by adding an owl:differentFrom statement between them (run the program with input file qcr_4.ttl). As you will see, Pellet generates a warning:
This is to be expected because we knowingly asserted something that is inconsistent with the axioms of our ontology. This warning is an indication that something in our knowledgebase violates the conditions of our ontology. Mike Smith (book tech editor/Clark and Parsia Pellet developer/all round awesome guy) tells me we can’t expect that specific warning will be generated in future release candidates as there are many situations in which an inconsistent ontology may be desirable and it is irritating to have ever instance logged by default. But, the good news is there are alternate ways to check the consistency of an ontology using Jena and Pellet. So, we will still be able to detect these inconsistencies when they occur (reading the documentation for Pellet and Jena to figure out the best way to do this is your homework assignment)
Hopefully this exploration has given you greater insight into the semantics of of qualified cardinality restrictions. We could go on for hours with other examples, but this should provide you with some more building blocks that you can apply to your own experimentation. Have fun, and stay consistent
Author’s note: Thanks to John Hebeler and Mike Dean for their inputs and Mike Smith for the feedback regarding Pellet.