1

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 .
hexapod
  • 13
  • 5

1 Answers1

1

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
Community
  • 1
  • 1
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Wow, that was quick, so first of, thank you very much :) You are absolutely correct, the data is serialized in RDF and everything (even in the "real" dataset) shows up as annotation properties. I had read about that before and fixed it, but forgot about that just now since i wrote up the example "by hand". I believe, my fix was merging the data with the schema it's based on, running the reasoner and then exporting the inferred axioms as ontology. Since this process takes very long, could I do a quick and dirty fix by including only the "required" classes and properties in my data manually? Or – hexapod Jun 07 '16 at 13:16
  • is there a better way, since I'd need to do that with every dataset? And while you did figure out the problem perfectly, I'll append a quick edit on my question to create a better example. And why is `SubClassOf` used? I had figured since it's `rdf:type`, I'd need to express equivalence, not `rdfs:subClassOf` (not necessarily important, just curious). – hexapod Jun 07 '16 at 13:26
  • 1
    @hexapod I used SubClassOf because I was encoding the axiom "**IF** an A has the following properties, **THEN** it is a Goal". Using a subclass axiom captures the single direction of the if-then. If every Goal is an A with those properties, so that the axiom is actually "an A has the following properties **IF AND ONLY IF** it is a Goal", then you can use an equivalent class axiom. I don't know enough about your intended use case to know which is more appropriate. I can say that "if something quacks like a duck, then it is a duck", but I wouldn't want – Joshua Taylor Jun 07 '16 at 14:42
  • @hexapod to say that "something quacks like a duck **if and only if** it is a duck", because there might be a mute duck somewhere in the world that can't quack like a duck, but it *is* still a duck. – Joshua Taylor Jun 07 '16 at 14:44
  • I see, thanks for the explanation. Unfortunately I haven't figured out my annotation property problem quite yet, but since your answer took care of what I was trying to do, I will mark it as accepted. Thank you for your help. – hexapod Jun 07 '16 at 15:09
  • @hexapod Generally, if you want to keep your instance data (ABox) separate from your schema/terminology (TBox), you define both of them as OWL ontologies, and then have the one with the instance data *import* the one with the the schema/terminology. E.g., classes.owl would define the classes, axioms, etc., and then instances.owl would import classes.owl and also have the instance data. – Joshua Taylor Jun 07 '16 at 16:32
  • I figured as much, but there seem to be some inconsistencies in what I am working with. Unfortunately both schema and data are provided to me and the data is created by a converter that serializes as RDF. I will continue tomorrow and report back with my findings. Again, thank you for your help. – hexapod Jun 07 '16 at 17:22
  • As I feared the ontology produced by importing the schema into the data is inconsistent. The problems seem to lie much deeper, as Protégé gets stuck trying to find explanations. I've contacted the necessary parties as this unfortunately is beyond my control. Thank you again for the solution to my original problem, I've successfully applied it to a small scale example that will have to suffice for now. – hexapod Jun 08 '16 at 12:57