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 ⊑ ∃ hasMother.Human
that is, that every Human has some Human as a mother. If I say that
DanielWebster ∈ 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.
Related
I'm trying to create SPARQL query that returns individuals which are an instance of an equivalent class expression (thus imitating some of the reasoning skills of protégé on Semantic Web). Can anyone help me figure out how to do this? I have a class named 'violation' which contains an equivalent class restriction. Now I want to find the individuals that meet the conditions of this restriction.
This is my query so far:
SELECT distinct ?Carmovement ?person ?restriction ?message
WHERE {?Carmovement carmovement:has_driver ?person .
?Carmovement rdf:type ?restriction . #rdf:type is no succes for getting instances
?object owl:equivalentClass ?restriction .
?object violin:message ?message}`
The query does not give any results because I have used "rdf:type", I wonder in which way I can evaluate whether an instance meets the condition of a class restriction.
Sample class restriction:
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf (
<http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#Car_Movement>
[ rdf:type owl:Restriction ;
owl:onProperty <http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#has_driver> ;
owl:allValuesFrom <http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#BarredPerson>
]
)
] ;
I expect to get individuals who have a property "has_driver" of type "BarredPerson".
I have three classes, let's call them :A, :B and :C and a property :p.
Every statement X: :p :Y should become a member of :A, when :X a :B and :Y a :C
Currently I'd prefer a solution with OWL, but could be also with SPARQL and/or SHACL.
Your question is rather ambiguous and quite impossible to parse without intuitive assumptions about what you are trying to express. This may be either due to your choice of being informal in order to avoid complicated precision, or a confusion about the meaning of the RDF and OWL concepts.
The way I interpreted at first the sentence:
Every statement X: :p :Y should become a member of :A
was that:
Every RDF triple of the form ?x :p ?y (where ?x and ?y are any subject and object respectively) can be inferred as a member of class :A.
It is easy to answer the question in this case: it cannot be expressed in any of RDF, RDFS, OWL, SWRL, RIF, SPARQL, SPIN, SHACL. The reason is that it is never possible to constrain any class to contain RDF triples in any of these formalisms and languages. To do so, it would be necessary to have RDF triples as first class citizens in the language.
The confusion, if there is, could be that the class rdf:Statement is often incorrectly considered to be the class of RDF triples. rdf:Statement, although being described as a way to express statements about statements, is not constrained in any way to contain RDF triples, no matter how you write your data, ontology, query, shape, rule, etc. The class rdf:Statement is just, formally, an arbitrary class of resources.
However, looking at the comments and answers, it may very well be possible that my interpretation of your use of "statement" and "become a member" is inappropriate for what you are trying to achieve.
Obvious SPARQL solution for free-standing triples:
PREFIX : <http://example.com/ontology#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
CONSTRUCT {
[] a :A, rdf:Statement ;
rdf:subject ?X ;
rdf:predicate :p ;
rdf:object ?Y
}
WHERE {
?X a :B .
?X :p ?Y .
?Y a :C .
}
With Jena rules, you could probably use makeSkolem(...).
Revised... this might not meet your needs, because it's making an inference about an rdf:Statement, not a free-standing triple. I can't figure how to do this without reificiation. Maybe something with named graphs, although that's generally not compatible with OWL implementations. Maybe you'd like Blazegraph's "Reification Done Right"
Also, maybe you already know how to do this.
It is asserted that lemonTest is an rdf:Statement. With Hermit reasoning on, it is inferred that lemonTest is a flavorStatement.
#prefix : <http://example.com/ontology#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://www.w3.org/2002/07/owl#> .
[ rdf:type owl:Ontology ;
owl:imports rdf: ,
rdfs:
] .
:flavor rdf:type owl:ObjectProperty .
:flavorStatement rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty rdf:object ;
owl:someValuesFrom :flavor
] ,
[ rdf:type owl:Restriction ;
owl:onProperty rdf:subject ;
owl:someValuesFrom :fruit
] ;
rdfs:subClassOf rdf:Statement .
:fruit rdf:type owl:Class .
:lemon a :fruit .
:lemonTest rdf:type owl:NamedIndividual ,
rdf:Statement ;
rdf:object :flavor ;
rdf:predicate :result ;
rdf:subject :lemon .
:sour a :flavor .
First attempt:
I'm not an OWL expert either, but the Hermit reasoner in Protégé doesn’t complain about this:
#prefix : <http://example.com/ontology#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:root a owl:Class .
:A a rdf:Statement ;
rdf:subject :X ;
rdf:predicate :p ;
rdf:object :Y ;
rdfs:subClassOf :root .
:B rdfs:subClassOf :root .
:C rdfs:subClassOf :root .
:X a :B .
:p a owl:ObjectProperty .
:Y a :C .
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
] .
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:
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.