3

We are trying to get a reasoner (e.g. HermiT in Protege) to infer that a more specific sub-property can be used instead of the asserted general property.

Classes:

- Patient
- Finding
    - Dyspnea
- ObservationStatus
     - Inclusion
     - Exclusion

Properties:

- has_finding (domain: Patient, range: Finding) 
    - has_positive_finding (domain: Patient, range: Finding, Inclusion)
    - has_negative_finding (domain: Patient, range: Finding, Exclusion)

If we assert the following triples:

:Patient1 a :Patient .
:Patient1 :has_negative_finding :Dyspnea1 .

A reasoner can infer (among other things) that:

:Dyspnea1 a :Finding .
:Dyspnea1 a :Exclusion.

But when we look at it the other way around and assert:

:Patient1 a :Patient .
:Dyspnea1 a :Dyspnea .
:Dyspnea1 a :Exclusion .
:Patient1 :has_finding :Dyspnea1. 

We would like the reasoner to infer that:

:Patient1 :has_negative_finding :Dyspnea1 .

We cannot seem to get Protege and HermiT to draw that conclusion and infer the triples.

What are we missing? Are the conditions not necessary and sufficient for it to infer that knowledge?

Wolfgang
  • 211
  • 1
  • 2
  • 10

1 Answers1

2
:Patient1 a :Patient .
:Dyspnea1 a :Dyspnea .
:Dyspnea1 a :Exclusion .
:Patient1 :has_finding :Dyspnea1. 

We would like the reasoner to infer that:

:Patient1 :has_negative_finding :Dyspnea1 .

… What are we missing? Are the conditions not necessary and sufficient for it to infer that knowledge?

There are a few issues here.

First, you haven't said that every has_finding actually corresponds to one of the subproperties. That is, just because something has as finding, you don't know that it also has a negative or a positive finding. The finding could just be a general finding, without being one of the more specific ones.

Second, the more specific type of the object doesn't mean that you have to use the more specific property.

Third, even if you state that the finding is an exclusion, if you don't know that exclusions are disjoint from inclusions, you could still have the finding be both a positive and negative finding.

Now, what it'd be really nice to do would be to state that has_finding is the union of has_negative_finding and has_positive_finding, and then declare inclusion and exclusion disjoint. Then every instance of a finding would have to be one or the other, and you could make your inference.

Since you can't do that, you'll need some sort of alternative. If you're using individuals as per-person diagnoses, then you could say that every finding is either a negative finding or a positive finding with an axiom like

        (inverse(hasFinding) some Patient) subClass ((inverse(hasNegativeFinding) some Patient) or (inverse(hasPositiveFinding) some Patient))

along with making hasFinding inverse functional, so that each finding is associated with at most one patient. Then you'd have an ontology like this:

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

a:Exclusion  a           owl:Class ;
        rdfs:subClassOf  a:Finding .

a:hasNegativeFinding  a     owl:ObjectProperty ;
        rdfs:range          a:Exclusion ;
        rdfs:subPropertyOf  a:hasFinding .

_:b0    a                   owl:Restriction ;
        owl:onProperty      a:hasPositiveFinding ;
        owl:someValuesFrom  a:Inclusion .

a:      a       owl:Ontology .

[ a                   owl:Restriction ;
  rdfs:subClassOf     [ a            owl:Class ;
                        owl:unionOf  ( _:b1 _:b0 )
                      ] ;
  owl:onProperty      a:hasFinding ;
  owl:someValuesFrom  a:Finding
] .

a:Finding  a                 owl:Class ;
        owl:disjointUnionOf  ( a:Finding a:Inclusion ) .

a:patient1  a         owl:Thing , owl:NamedIndividual ;
        a:hasFinding  a:dyspnea1 .

_:b1    a                   owl:Restriction ;
        owl:onProperty      a:hasNegativeFinding ;
        owl:someValuesFrom  a:Exclusion .

a:hasFinding  a  owl:ObjectProperty .

a:Inclusion  a           owl:Class ;
        rdfs:subClassOf  a:Finding .

a:hasPositiveFinding  a     owl:ObjectProperty ;
        rdfs:range          a:Inclusion ;
        rdfs:subPropertyOf  a:hasFinding .

a:dyspnea1  a   owl:NamedIndividual , a:Exclusion .

and you can get results like this:

findings inference

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • This looks very promising, but we are having difficulties reproducing your screenshot. Is the turtle snippet a dump from Protege? We copy/pasted it into a file and loaded it into Protege. But we cannot get the inferred statement your are showing in your screenshot. Could you also explain why you made Exclusion/Inclusion a subclass of Finding? Dyspnea would be a subclass of Finding in our scenario. – Wolfgang Jun 17 '15 at 23:38
  • In your scenario, you had the domains of hasNegative and hasPositive be Exclusion and Inclusion. but hasNegative and hasPositive are subproperties of hasFinding. So whenever you had "x hasNegative y", you'd infer that "x hasFinding y". From those you can infer that "y a Exclusion" and "y a Finding". So it seemed like most of your instances of Exclusion and Inclusion would end up being findings. By making Finding the disjoint union of Exclusion and Inclusion, the reasoner can infer that any finding must be either an Inclusion or Exclusion. – Joshua Taylor Jun 17 '15 at 23:52
  • @Wolfgang the only reasoner configuration I did was under Reasoner > Configure. There you can configure Protege to show more of the reasoner's conclusions, but I don't *think* that that was relevant in this case (but you could try anyhow). – Joshua Taylor Jun 17 '15 at 23:53
  • Just to make sure: You are saying that the turtle snippet in your post is the direct dump from Protege? Sorry for asking that again, but we cannot reproduce the screenshot. Also in the screenshot, there are no individuals in the members list. – Wolfgang Jun 18 '15 at 00:14
  • @Wolfgang I ran the output from Protege through Jena's rdfcat, just to make the Turtle text a bit shorter, but it's the same ontology. Looking at the screenshot again, it may be a little misleading. Open the individuals tab, then click on "Thing", since patient1 is an instance of Thing. That's where you should see the declared and inferred property assertions. I'm not sure why "Inclusion" is highlighted in the screenshot. – Joshua Taylor Jun 18 '15 at 00:40