Search code examples
owlontologyprotegereasoning

Unable to infer instances using axioms


I want to gather data via ontology matching and reasoning. To do that, I'd like to first identify relevant Individuals for later use if they fulfill certain criteria (using general class axioms).
Currently however, I am unable to achieve the necessary inferences using Protégé. The data consisting of various individuals looks like this:

# Data
# Common Prefixes omitted for readability
@prefix ns: <http://example.org/underlyingSchema#> .
@prefix data: <http://example.org/data#> .

data:A1 a ns:A .
data:A2 a ns:A .

data:R1 a ns:R .
 ns:defines data:A1 ;
 ns:definedBy data:P1 .

data:R2 a ns:R .
 ns:defines data:A2 ;
 ns:definedBy data:P2 .

data:P1 a ns:P ;
 ns:hasS data:S1.

data:P2 a ns:P ;
 ns:hasS data:S2.

data:S1 a ns:S ;
 ns:hasI data:I1 ;
 ns:hasV data:B1 .

data:S2 a ns:S ;
 ns:hasI data:I1 ;
 ns:hasV data:B2 .

data:I1 a ns:I ;
 expr:hasString "relevant" .

data:B1 a ns:B ;
 expr:hasBoolean "true"^^xsd:boolean .

data:B2 a ns:B ;
 expr:hasBoolean "false"^^xsd:boolean .

I want to infer that every instance of A for which the relevant attribute is true is also an instance of my example-class, defined in my own ontology as eg:Example a owl:class.
Unfortunately, since the underlying schema for the data is very cumbersome, I have to do that via A -> R -> P -> S -> I and B. As R however isn't a straightforward definition (A <- R -> P -> S -> I and B is probably a more accurate representation), I can't just do a someValuesFrom chain and (I assume) this is where I fail.
Using Protégé, I loaded the schema which defines the properties and classes (Namespace ns) to be able to use the suggestions/auto-complete in the class expression editor. In my own ontology (containing only the example-class) following a previous suggestion I tried using the axiom:

A and (inverse defines some) and definedBy some (hasS some (hasI some(hasString value "relevant")) and (hasV some(hasBoolean value "true"^^xsd:boolean))) EquivalentTo: Example

I then merged my ontology with the data and ran the reasoner, expecting to see A1 (but not A2) as an instance of my example-class, but didn't get any results. I also tried using just "true" and true as well as "relevant"^^xsd:string to see if datatypes were causing the problem, yet it is only inferred that Example is a subclass of A.
I believe that my understanding of what inverse does is incorrect (I thought it's used since A1 is the object in the triple R1 defines A1; so I also tried inverse defines self), but I cannot figure it out. Any help is greatly appreciated.

Edit:

As Joshua correctly pointed out, my example lacks declarations. In my case, these are made in a different schema ontology, so I forgot about them here. Will add for the sake of completeness:

# Might as well include prefixes
@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 expr:  <http://purl.org/voc/express#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .

# Classes
ns:A a owl:Class .
ns:R a owl:Class .
ns:P a owl:Class .
ns:S a owl:Class .
ns:I a owl:Class .
ns:B a owl:Class .

# Object Properties
ns:defines a owl:ObjectProperty .
ns:definedBy a owl:ObjectProperty .
ns:hasS a owl:ObjectProperty .
ns:hasI a owl:ObjectProperty .
ns:hasV a owl:ObjectProperty .

# Data Properties
expr:hasString a owlDatatypeProperty .
expr:hasBoolean a owlDatatypeProperty .

Solution

  • It doesn't look like that data was generated by Protege. When I copy that content and load it into Protege, everything shows up as annotation properties, which aren't generally handled under OWL reasoning. They show up as annotation properties because there are no property declarations making them object properties or datatype properties. That might be part of your problem. That axiom doesn't look quite right, either. E.g., (inverse defines some) doesn't make sense; that would have to be (inverse defines) some class expression, etc. In general, it helps a lot if you can provide complete working examples that we can work with. See How to create a Minimal, Complete, and Verifiable example.

    All that said, I think we can recreate enough of the problem to figure out how to fix it. It sounds like you want to recognize a pattern like

    A  <--rdf:type--  ?a  <--p--  ?b  --q-->  ?c  --r--> 42
    

    and then infer the triple

    ?a  --rdf:type-->  Goal 
    

    That is achievable in OWL. It requires an axiom of the form:

        A and ((inverse p) some (q some (r value 42))) SubClassOf Goal

    That says that if something is an A and is the p value of something that has a q value that has an r value of 42, then that first something is also a Goal.

    Here's what it looks like in an actual ontology:

    protege screenshot

    Once a reasoner has been started, it correctly infers that a is an instance of Goal:

    reasoner result

    Here's the actual ontology:

    @prefix : <http://example.org/gca#> .
    @prefix owl: <http://www.w3.org/2002/07/owl#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix xml: <http://www.w3.org/XML/1998/namespace> .
    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @base <http://example.org/gca> .
    
    <http://example.org/gca> rdf:type owl:Ontology .
    
    #################################################################
    #    Object Properties
    #################################################################
    
    ###  http://example.org/gca#p
    :p rdf:type owl:ObjectProperty .
    
    
    ###  http://example.org/gca#q
    :q rdf:type owl:ObjectProperty .
    
    
    #################################################################
    #    Data properties
    #################################################################
    
    ###  http://example.org/gca#r
    :r rdf:type owl:DatatypeProperty .
    
    
    #################################################################
    #    Classes
    #################################################################
    
    ###  http://example.org/gca#A
    :A rdf:type owl:Class .
    
    
    ###  http://example.org/gca#Goal
    :Goal rdf:type owl:Class .
    
    
    #################################################################
    #    Individuals
    #################################################################
    
    ###  http://example.org/gca#a
    :a rdf:type owl:NamedIndividual ,
                :A .
    
    
    ###  http://example.org/gca#b
    :b rdf:type owl:NamedIndividual ;
       :p :a ;
       :q :c .
    
    
    ###  http://example.org/gca#c
    :c rdf:type owl:NamedIndividual ;
       :r 42 .
    
    
    #################################################################
    #    General axioms
    #################################################################
    
    [ owl:intersectionOf ( :A
                           [ rdf:type owl:Restriction ;
                             owl:onProperty [ owl:inverseOf :p
                                            ] ;
                             owl:someValuesFrom [ rdf:type owl:Restriction ;
                                                  owl:onProperty :q ;
                                                  owl:someValuesFrom [ rdf:type owl:Restriction ;
                                                                       owl:onProperty :r ;
                                                                       owl:hasValue 42
                                                                     ]
                                                ]
                           ]
                         ) ;
      rdf:type owl:Class ;
      rdfs:subClassOf :Goal
    ] .
    
    
    ###  Generated by the OWL API (version 4.2.5.20160517-0735) https://github.com/owlcs/owlapi