OWL type inference with a restriction - type-inference

I am studying the notion of OWL restrictions with Protege 4 using FaCT++ and a trivial ontology. Suppose I have an individual foo of class Something:
:Something a owl:Class.
:foo a :Something, owl:NamedIndividual.
and another class defined from a restriction on the hasBar property:
:hasBar a owl:ObjectProperty.
:SomethingElse owl:equivalentClass [a owl:Restriction;
owl:onProperty :hasBar;
owl:allValuesFrom :Something].
If I assert that:
:x :hasBar :foo.
why can't I infer from it that x is a SomethingElse (via the fact that foo is a Something)? The only way I can make it work is if the range of hasBar is defined:
:hasBar a owl:ObjectProperty;
rdfs:range :Something.
But I'd like to avoid that, because it puts a constraint on what can be the subject of hasBar (which causes me further trouble).

I think it is simpler to reason over real examples, let's consider the following knowledge base:
:eats rdf:type owl:ObjectProperty .
:Vegetable rdf:type owl:Class ;
rdfs:subClassOf owl:Thing .
:Vegetarian rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :eats ;
owl:allValuesFrom :Vegetable
] .
:Carrot rdf:type :Vegetable ,
owl:NamedIndividual .
:John rdf:type owl:NamedIndividual , owl:Thing ;
:eats :carrot .
You have some equivalences with your example: hasBar is eats, Vegetarian is SomethingElse, Vegetable is Something, foo is carrot and finally x is John.
Now you would like to infer that John is a Vegetarian (= x is SomethingElse).
It makes sense that it doesn't work with an owl:allValuesFrom. What you are saying here is that all instances of vegetarian, if they have a property, they must have Vegetable in range. So from that you could deduce that carrot is a vegetable for example, assuming you would know that John is a vegetarian in the first place.
It makes sense in natural language too: In your ontology you only know that John eats a carrot, this doesn't automatically make him a vegetarian (non-vegetarian people eat also carrots).
You could use a owl:someValuesFrom instead of a owl:allValuesFrom. This way, you would define every vegetarian has someone that eats some vegetable. In this case if we know that John eats a carrot, therefore he would be classified as vegetarian by the reasoner, based on your definition of the concept vegetarian.
Universal (allValuesFrom) and existential (someValuesFrom) restrictions are complicated to understand, there is often no right or wrong solution, it mostly depends to what you want to achieve.

Related

SPARQL code missing individuals from classes that are not subclasses

I am currently working on a sparql query that computes every individual and the class that the individual exists in. Here is an (awful) example of what my ontology looks like:
Owl:Thing
-Lion
-Elephant
-Pets
-Dog
-Cat
Where Lion and Elephant are classes with no subclasses and Dog and Cat are subclasses of the class Pet. When I run my code, I got the individuals from Dog and Cat, but no individuals from Lion or Elephant.
SELECT ?indiv ?class
WHERE {
?class rdf:type owl:Class .
?indiv rdf:type owl:NamedIndividual .
?indiv rdf:type ?class
} ORDER BY ?class ?indiv
So basically, the result of my code are the individuals that come from only classes that are subclasses, when I am expecting to have the individuals from all classes. Could anyone please help?

OWL: Is it possible to predefine relations between an individual and a range of individuals?

Let's say we have the owl:Class Person and the owl:Class Fruit. Besides that we have the owl:ObjectProperty loves (Domain: Person, Range: Fruit). There are several instances of both classes.
Is it possible to express in OWL that one particular instance of the class Person likes all fruits except apples (instance of Fruit) without having to manually define all of the loves-relations between that person and all the other Fruit instances (except apple)?
On a more abstract level: Is it possible to define relations between an instance and a range of instances (either on a class-level or for the instance itself)?
OneOf restrictions are used for what you're describing. To exclude one instance from a class (for the first part of your question) you can intersect the fruit class and the negation of OneOf(Apple), and use it to declare your apple hater as having as type a range assertion for your love property.
The solution to your problem depends whether "apple" is an instance of "fruit" or "apple" is a subclass of "fruit". It would make more sense to say that "apple" is a class, because there are many instances of apples. But since Ignazio presented a solution where "apple" is an instance, and that his answer was accepted, I will start with assuming that "apple" is an instance. Then you can achieve what you want with:
:Fruit a owl:Class .
:apple a :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf [a owl:Class; owl:oneOf (:apple)] ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .
This is saying that everything that is a :Fruit and is not :apple is necessary loved by :bob (assuming :bob is the identifier of the person who does not like apples. Note that this is different from Ignazio's solution, which does not exactly model what the OP wants.
Now, if there is a class of apples, then the solution would be:
:Fruit a owl:Class .
:Apple rdfs:subClassOf :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf :Apple ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .

OWL reasoning: Necessary and sufficient conditions for inferring a property

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?
: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:

Reasoner does not check cardinalities and/or restrictions?

I tried to create the perhaps simplest ontology, consisting of two classes (A, B) and a relation (R) between the two classes. I also want to state that every individual of A must have a relation R with some other individual.
:R rdf:type owl:ObjectProperty ;
rdfs:domain :A ;
rdfs:range :B .
:A rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ,
[ rdf:type owl:Restriction ;
owl:onProperty :R ;
owl:someValuesFrom :B
] ;
owl:disjointWith :B .
:B rdf:type owl:Class ;
rdfs:subClassOf owl:Thing .
Now some individuals:
:a1 rdf:type :A , owl:NamedIndividual ; :R :b1 .
:a2 rdf:type :A , owl:NamedIndividual .
:b1 rdf:type :B , owl:NamedIndividual .
But the reasoner does not complain about a2 not having a relation R. Why?
(Note: I created ontology in Protégé; I tried FacT++ and HermiT reasoners)
I also want to state that every individual of A must have a relation R with some other individual.
You have done this correctly. When you go on to assert that
:a1 rdf:type :A , owl:NamedIndividual ; :R :b1 .
:a2 rdf:type :A , owl:NamedIndividual .
:b1 rdf:type :B , owl:NamedIndividual .
the reasoner will correctly infer there is some value, let's call it X, such that :a2 :R X and that X rdf:type :B. OWL reasoning uses the open world assumption. This means that if something is not explicitly stated to be true or false, it is not assumed to be false or true, but rather unknown. E.g., you could correctly assert that
Human &sqsubseteq; ∃ hasMother.Human
that is, that every Human has some Human as a mother. If I say that
DanielWebster &in; Human
and that's all that I say; I haven't made an inconsistency. There are just things that are true that we don't know yet. We know that DanielWebster has a mother, but we don't know who she is.
If you want to close the world, you could do a few things, but the results may not be what you want. First, you could make B an enumerated class. That is, you could explicitly list the individuals of B:
B ≡ {b1}
That actually won't lead to an inconsistency, though. In fact, the reasoner will infer that since a2 must be related to some B, and the only B is b1, that a2 is related by R to b1.
You can use an equivalent also.
:A owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :R ;
owl:someValuesFrom owl:Thing
] ;
You don't need to write domain constraint for R. The equivalent will take care of it. You still have to write range constraint.
But the reasoner does not complain about a2 not having a relation R. Why?
To answer this question. You need to understand Open world assumption. Semantic web is open world assumption. There are some research paper, which I have said in the comments below, makes some concepts or roles as Closed world assumption. For example, in your example, if you make R as a closed predicate. you will get the error you asked. This is entirely a theoretical idea.

in turtle or RDF can I add a predicate/object on all subjects that match a criteria?

I am doing some experiments with importing triples formulated in the turtle language
within the openrdf-workbench webapp in Tomcat, which has incorporated a SPARQL endpoint.
I wonder if with turtle, or, generally, in RDF / RDFS is it possible to add a certain predicate/object declaration on all (implicit) subjects conditionally to the existence of another predicate/object.
For example, if I have the following triples defined:
foo:a foo:b foo:c
foo:d foo:b foo:c
foo:e foo:b foo:c
foo:f foo:b foo:c
I would like to automatically add the following predicate/subject to all subjects that match predicate=foo:b and object=foo:c:
(implicit subject) foo:g foo:h
in order to automatically produce the following triples:
foo:a foo:g foo:h
foo:d foo:g foo:h
foo:e foo:g foo:h
foo:f foo:g foo:h
Is this possible?
Alternatively: is there any way to define some triples in order to enable SPARQL to find foo:a/d/e/f when queried for subjects that have foo:g foo:h as predicate/object?
Part 1 - Creating additional information
The first part of your question can be solved in one of two ways:
Using Inference
Using SPARQL Update
Inferencing
Inference is a technique whereby you define rules that infer additional triple based on your existing triples. You typically either use a pre-defined set of rules or use your own custom rules. I think Sesame only supports pre-defined rule sets out of the box so you may want to take a look at OWLIM which is an alternative back end that can be used with Sesame and has much more customisable rules AFAIK.
Inferencing can typically be applied in two ways, one where you only store the rules and you compute the additional information every time a rule fires and another where you pre-compute all the additional information and add it to your database. Which you will want to use depends on how you intend to use your system and there are performance trade offs involved. I'm not going into detail because that's really a whole other question - see Forward vs Backward Chaining for some discussion
SPARQL Update
Alternatively if your rules are relatively simple and you are OK with pre-computing the extra information and adding it to your database you can write SPARQL Updates to do this e.g.
PREFIX foo: <http://example.org/foo#>
INSERT
{
?x foo:g foo:h .
}
WHERE
{
?x foo:b foo:c .
}
Part 2 - Querying the Data
I am guessing you are fairly new to SPARQL because from what you've described this sounds trivial to me.
If I wanted to find all subjects which had the predicate foo:g and the object foo:h I would simply write the following:
PREFIX foo: <http://example.org/foo#>
SELECT ?x
WHERE
{
?x foo:g foo:h .
}
You can do this type of inference using OWL with an axiom of the form
p value a &sqsubseteq; q value b
which says that if something has a as a value for property p, then it also has b as a value for property q. As an example, here's an ontology with four individuals (a, b, c, d), two object properties (p, q), and the axiom (p value c &sqsubseteq; q value d).
#prefix : <http://example.org/add-predicate-object#> .
#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#> .
<http://example.org/add-predicate-object> a owl:Ontology .
:p a owl:ObjectProperty .
:q a owl:ObjectProperty .
[ a owl:Restriction ;
owl:onProperty :p ;
owl:hasValue :c ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty :q ;
owl:hasValue :d ] . ] .
:a a owl:Thing, owl:NamedIndividual ; :p :c .
:b a owl:Thing, owl:NamedIndividual ; :p :c .
:c a owl:Thing, owl:NamedIndividual .
:d a owl:Thing, owl:NamedIndividual .
In Protégé, the axiom looks like this:
You can enable a reasoner and query for instances of q value d and see:
or you can browse to individuals and see the results: