OWL Intersection on class level - type-inference

I have a class hierarchy like this:
Thing
- ClassA
-ClassC
-ClassD
- ClassB
-ClassC
-ClassE
Class C is a subclass of both, ClassA and ClassB while ClassD and ClassE are only subclasses of either ClassA or ClassB
Now I would like to specify a class which is equivalent to the Intersection of subclasses of ClassA and ClassB. The following doesn't work:
NamedClass a owl:Class
NamedClass owl:equivalentClass (ClassA and ClassB)
The reason is that this sort of rule would be used by the reasoner to classify individuals, i.e. is I had an individual Ind1 which is of type ClassA and ClassB, it would be classified to be also of type NamedClass. This is not (only) what I want. I want ClassC itself to be a subclass of NamedClass.
I know this is achievable using rules (e.g. SPIN) but can it be done without rules?

Let's start with the initial hierarchy, including F, but before we've declared that F is equivalent to the intersection of A and B:
Then we add (A and B) as a class equivalent to F. Protégé is smart enough to render things that are equivalent or subclasses of intersections under each of the intersected classes, so we see F appear in two places here.
A reasoner can confirm the relation, too. Here I've turned on Pellet, entered F into the DL query, and asked for subclasses. Sure enough, C is a subclass of F:
Here's the ontology that you can copy and paste:
#prefix : <http://stackoverflow.com/q/22221549/1281433/> .
#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#> .
:ontology a owl:Ontology .
:A a owl:Class .
:B a owl:Class .
:C a owl:Class ; rdfs:subClassOf :A , :B .
:D a owl:Class ; rdfs:subClassOf :A .
:E a owl:Class ; rdfs:subClassOf :B .
:F a owl:Class ;
owl:equivalentClass [ a owl:Class ;
owl:intersectionOf ( :A :B ) ] .

Yes, you can define that a class is defined as intersection of two other classes using OWL.
Check the OWL 2 Primer.
Hope I helped!
PS If you want to apply more advanced rules to your model, I would suggest using SWRL which is a w3c recommendation.

Related

How to create a Class as equivalent of a Class with defined type of RDF Statements?

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 .

Reasoner to inference rdf:type in JENA API

Hello I am using Jena API to load RDF/XML file from local directory. Below is the RDF/XML file:
#prefix : <http://www.semanticweb.org/sample#> .
#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://www.semanticweb.org/sample> .
<http://www.semanticweb.org/sample> rdf:type owl:Ontology .
#################################################################
#
# Classes
#
#################################################################
### http://www.semanticweb.org/sample#Child1
:Child1 rdf:type owl:Class ;
rdfs:subClassOf :SubClass2 .
### http://www.semanticweb.org/sample#Child2
:Child2 rdf:type owl:Class ;
rdfs:subClassOf :SubClass2 .
### http://www.semanticweb.org/sample#SubClass1
:SubClass1 rdf:type owl:Class .
### http://www.semanticweb.org/sample#SubClass2
:SubClass2 rdf:type owl:Class,
:SubClass1 .
object and property relations of the above RDF/XML is as follows:
There are two classes under thing: SubClass1 and SubClass2.
SubClass2 further has two children classes: Class1 and Class2
Additionally SubClass2 is of type (i.e., rdf:type) SubClass1
So by inference, even Child1 & Child2 should be of type SubClass1. Right? Please let me know if I am wrong.
And I used several Reasoners with Jena API to extract all the classes of type "SubClass1", but everytime the output is only one entity (i.e., SubClass1)
I am using the sample code mentioned in this link (Section 2): http://opentox.org/data/documents/development/RDF%20files/JavaOnly/query-reasoning-with-jena-and-sparql
Please someone let me know what is the best reasoner to use for this use case? Appreciate your help.

Removing unwanted superclass answers in SPARQL

I have an OWL file that includes a taxonomic hierarchy that I want to write a query where the answer includes each individual and its immediate taxonomic parent. Here's an example (the full query is rather messier).
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix : <urn:ex:> .
:fido rdf:type :Dog .
:Dog rdfs:subClassOf :Mammal .
:Mammal rdfs:subClassOf :Vertebrate .
:Vertebrate rdfs:subClassOf :Animal .
:fido :hasToy :bone
:kitty rdf:type :Cat .
:Cat rdfs:subClassOf :Mammal .
:kitty :hasToy :catnipMouse .
And this query does what I want.
prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
prefix : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual rdf:type ?type .
}
The problem is that I'd rather use a reasoned-over version of the OWL file, which unsurprisingly includes additional statements:
:fido rdf:type :Mammal .
:fido rdf:type :Vertebrate .
:fido rdf:type :Animal .
:kitty rdf:type :Mammal .
:kitty rdf:type :Vertebrate .
:kitty rdf:type :Animal .
And now the query results in additional answers about Fido being a Mammal, etc. I could just give up on using the reasoned version of the file, or, since the SPARQL queries are called from java, I could do a bunch of additional queries to find the least inclusive type that appears. My question is whether there is a reasonable pure SPARQL solution to only returning the Dog solution.
A generic solution is that you make sure you ask for the direct type only. A class C is the direct type of an instance X if:
X is of type C
there is no C' such that:
X is of type C'
C' is a subclass of C
C' is not equal to C
(that last condition is necessary, by the way, because in RDF/OWL, the subclass-relation is reflexive: every class is a subclass of itself)
In SPARQL, this becomes something like this:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual a ?type .
FILTER NOT EXISTS { ?individual a ?other .
?other rdfs:subClassOf ?type .
FILTER(?other != ?type)
}
}
Depending on which API/triplestore/library you use to execute these queries, there may also be other, tool-specific solutions. For example, the Sesame API (disclosure: I am on the Sesame dev team) has the option to disable reasoning for the purpose of a single query:
TupleQuery query = conn.prepareTupleQuery(SPARQL, "SELECT ...");
query.setIncludeInferred(false);
TupleQueryResult result = query.evaluate();
Sesame also offers an optional additional inferencer (called the 'direct type inferencer') which introduces additional 'virtual' properties you can query, such as sesame:directType, sesame:directSubClassOf, etc. Other tools will undoubtedly have similar options.

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:

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: