5

This DL-Query is not returning any individuals:

  • Query (Protégé syntax) : hasPet exactly 1 DomesticAnimal

Here's part of the ontology:

:hasPet a           owl:ObjectProperty;
        rdfs:domain :Human;
        rdfs:range  :DomesticAnimal;
        owl:inverseOf : petOf;


:Joe    a           :Human;
        hasPet      :Lassy.

:Bob    a           :Human;
        hasPet      :Sparkey, Lucky.

Queries:

  • petOf value Bob returns Sparkey and Lucky
  • petOf value Joe returns Lassy
  • hasPet exactly 1 returns nothing.

Why isn't the last query returning Joe? I have tried it with in Protégé with Pellet, HermiT, and FaCT++, and it didn't work.

Anthony
  • 644
  • 7
  • 23
  • 3
    In addition to the answer below, also take a look at the answers to [this question](http://stackoverflow.com/q/842801/1281433). – Joshua Taylor May 30 '13 at 20:26

1 Answers1

7

The class expression hasPet exactly 1 DomesticAnimal has as instances exactly those individuals which are related by the property hasPet to exactly one DomesticAnimal. Exactly one means at least one and no more than one. Based on the triples

:Joe :hasPet :Lassy .
:Bob :hasPet :Sparkey ;
     :hasPet :Lucky .

we know that Joe and Bob each have at least one pet, but we do not know anything about how many they might have. Joe might have pets other than Lassy, so we don't know that Joe has exactly one pet. It is possible that Sparkey and Lucky happen to be the same individual, so Bob has at least one pet, but we do not have an upper bound on the number of pets that Bob has.

OWL, as well as RDF, makes the open world assumption, which means that OWL does not assume that the data provided is an exhaustive enumeration of everything in the world that is true. If it did, there would be no point in inference. The absence of an assertion of s p o does not imply that NOT( s p o ), but rather just that there is no judgment yet on s p o.

You can add some more knowledge to your data to get the conclusions that you want, though. You describe Joe with the following:

Joe a Human ;
    hasPet Lassy ;
    hasPet only { Lassy } .

Lassy a DomesticAnimal .

From this you will be able to infer that

Joe a (hasPet exactly 1 DomesticAnimal) .

For Bob, it looks like you expect that Sparkey and Lucky are different animals, so you'll need owl:differentFrom:

Bob a Human ;
    hasPet Sparkey, Lucky .

Sparkey a DomesticAnimal .

Lucky a DomesticAnimal ; 
      owl:differentFrom Sparkey .

I did not include Bob hasPet only { Sparkey, Lucky } in these axioms, because they are not necessary to infer that Bob has more than one pet, but you could include it. I also included just one of the owl:differentFrom assertions that could have been made. Now Bob is known to have two distinct pets, and thus known to not be a hasPet exactly 1 DomesticAnimal. With this data loaded into Protégé, the DL query hasPet exactly 1 DomesticAnimal works as expected:

enter image description here

Example Ontology

In case you want to be able to quickly load this structure into Protégé, here's an ontology with individuals, property, and axioms as described above. I did not define the petOf property, but you can still run your first two queries as inverse hasPet value Joe and inverse hasPet value Bob and get the expected results.

@prefix :        <http://www.example.com/owa#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owa:     <http://www.example.com/owa#> .

owa:Bob
      a       owl:NamedIndividual , owa:Human ;
      owa:hasPet owa:Sparkey , owa:Lucky .

owa:Sparkey
      a       owl:NamedIndividual , owa:DomesticAnimal .

owa:Lassy
      a       owl:NamedIndividual , owa:DomesticAnimal .

[]    a       owl:AllDifferent ;
      owl:distinctMembers (owa:Lucky owa:Sparkey) .

owa:Joe
      a       owl:NamedIndividual , owa:Human ;
      a       [ a       owl:Restriction ;
                owl:allValuesFrom
                        [ a       owl:Class ;
                          owl:oneOf (owa:Lassy)
                        ] ;
                owl:onProperty owa:hasPet
              ] ;
      owa:hasPet owa:Lassy .

<http://www.example.com/owa>
      a       owl:Ontology .

owa:Lucky
      a       owl:NamedIndividual , owa:DomesticAnimal .

owa:Human
      a       owl:Class .

owa:hasPet
      a       owl:ObjectProperty .

owa:DomesticAnimal
      a       owl:Class .
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Great answer! I was struggling to find the solution too - silly open world assumption! – loopasam May 30 '13 at 20:57
  • Thanks a lot for the answer. Protege allows you to make all declared individuals distinct with just one click. Is there a feature that allows you to automatically create restrictions on the asserted properties of each individual to assert that there are no other possible values (i.e simulate a closed world assumption)? How do you develop your ontologies? Do your write them all in Turtle? – Anthony May 30 '13 at 21:47
  • @Anthony For anything OWL-based, I used Protégé, as I did in this case. I posted the ontology in N3 format because I find it a bit easier to read in plain text than RDF/XML. I don't know of any quick ways to “close the world,” so to speak, but it's also very rare that I _want_ to. Part of the appeal of OWL, linked data, and the Semantic Web, is that it is possible to get _more information_ from other sources. If you try to “close the world” you can very easily make other information inconsistent with yours, or have other problems. For instance, say someone tells you that… – Joshua Taylor May 30 '13 at 21:58
  • @Anthony …`Joe hasPet RinTinTin` and that `RinTinTin owl:differentFrom Lassy`, but doesn't say anything about whether `RinTinTin a DomesticAnimal` because they didn't know about that class. Now, since Joe has _exactly_ one DomesticAnimal as a pet, it means that RinTinTin must not be a DomesticAnimal. Is this what was expected? Maybe? Maybe not? If your ontology doesn't become inconsistent, it at least has some unexpected contents. – Joshua Taylor May 30 '13 at 22:01
  • @loopasam While the open world assumption does make things inconvenient once in a while, it is much more in line with traditional formal logic, and it is hard to get around it in the Semantic Web & Linked Data context. With the open world assumption we can have: "I have data _D_. Does _X_ follow? **I don't know.** Does _not X_ follow? **I don't know.** OK, I also have data _D'_. Does _X_ follow from _D_ and _D'_? **Yes!**" With the closed world assumption (and negation as failure), we have have "… Does _X_ follow? **No.** Does _not X_ follow? **Yes!** Does _X_ follow from _D_ and _D'_? … – Joshua Taylor May 30 '13 at 22:11
  • 1
    @loopasam … **Yes!** Does _not X_ follow from _D_ and _D'_? **No.**" In logical systems, it is often much easier to be [_monotonic_](http://en.wikipedia.org/wiki/Monotonic_logic), which means, roughly, that _adding_ information never makes you _retract_ previous conclusions. If you have an enormous dataset, e.g., DBpedia, and can prove _P_ from a very small subset of it, you _really_ don't want to have to search the entire rest of the data to make sure that no other data in the dataset would make you retract that. – Joshua Taylor May 30 '13 at 22:14
  • @Joshua how do you create these restrictions (manually) in protege? I can't seem to find it in Proptege 4.2.0 for Mac. – Anthony May 31 '13 at 13:43
  • 1
    @Anthony That's one of the reasons that I provided the entire ontology. You can save that and open it up in Protégé and see how things are represented. The syntax I used in answer is actually pretty close. For instance, once you have defined the individual _Joe_, go to the **Individuals** tab, select _Joe_, click the "+" button next to **Types**, go to the **Class expression editor** tab, and enter, e.g., `hasPet only { Lassy }`. (This depends on the property `hasPet` and the individual `Lassy` already being defined.) Similarly, you could type `hasPet exactly 1 DomesticAnimal`. – Joshua Taylor May 31 '13 at 14:54
  • 1
    @Anthony Protege input syntax is roughly the [OWL2 Manchester Syntax](http://www.w3.org/TR/2012/NOTE-owl2-manchester-syntax-20121211/#Quick_Reference), although you'll only be using the class expressions. The [CO-ODE page](http://www.co-ode.org/resources/reference/manchester_syntax/) is probably more useful. The [OWL Primer](http://www.w3.org/TR/2012/REC-owl2-primer-20121211/#Complex_Classes) also has code examples (but you'll need to enable the Manchester syntax with the "Show Manchester Syntax" button in [1.2 OWL Syntaxes](http://www.w3.org/TR/2012/REC-owl2-primer-20121211/#OWL_Syntaxes). – Joshua Taylor May 31 '13 at 15:04
  • @JoshuaTaylor: Great answer! As I saw several nice answers from you here around Semantic Web topics, I wonder if you might be interested in a [proposal for a Semantic Web Stack Exchange site](http://area51.stackexchange.com/proposals/53218/semantic-web?referrer=GMMTsbTUwV511mI2mO2k0g2). – unor May 31 '13 at 17:59
  • @unor I'd seen discussions on the answers.semanticweb.com about joining or not joining the Stack Exchange network, but wasn't aware of that proposal. I'm following it now. Thanks for the heads up! – Joshua Taylor May 31 '13 at 18:50