Retrieving all the ancestors of a rdf:Class
-
12-09-2019 - |
Question
Imagine the following Taxonomy (acyclic & directed graph):
<my:Eukaryota> <rdfs:subClassOf> <my:Organism>.
<my:Mammal> <rdfs:subClassOf> <my:Eukaryota>.
<my:Primate> <rdfs:subClassOf> <my:Mammal>.
<my:HomoSapiens> <rdfs:subClassOf> <my:Primate>.
<my:Bacteria> <rdfs:subClassOf> <my:Organism>.
<my:Escherichia> <rdfs:subClassOf> <my:Bacteria>.
1) Is it possible with the Jena OWL API to check if a given resource (e.g. HomoSapiens) is a subclass of 'Mammal' without recursively retrieving all the parents nodes ?
2) The same question with SPARQL.
Thanks
Solution
If you're already using Jena, you can use use Pellet's SPARQL-DL query engine, which should let you query individuals in an ontology-aware way.
Alternately, you can use Jena's InfModel
instead of Model
interface, attach a reasoner (and ontology) to it, and then run the query RobV mentions. You can use Pellet's reasoner for this if you wanted. You don't need to use the OntModel
if you just want to do reasoning.
OTHER TIPS
1) Haven't used Jena much, but its OntTools class seems to contain functions for lowest common ancestor. If the least common ancestor of HomoSapiens and Mammal is Mammal, then HomoSapiens is a Mammal. Under the hood it uses recursive subClassOf retrieval though.
2) In the generic case, no, SPARQL does not support arbitrary depth tree traversal. But if you know the maximum depth of the subClassOf tree, then you can construct a query like
ASK {
OPTIONAL {
:HomoSapiens rdfs:subClassOf :Mammal
}
OPTIONAL {
:HomoSapiens rdfs:subClassOf ?c .
?c rdfs:subClassOf :Mammal
}
OPTIONAL {
:HomoSapiens rdfs:subClassOf ?c1 .
?c1 rdfs:subClassOf ?c2 .
?c2 rdfs:subClassOf :Mammal
}
# ... add
}
laalto is right, pretty much any Semantic Web library is going to do it via recursive subClassOf retrieval. Only way you might get around this would be to have some inference/reasoning engine which would add additional Triples to the Graph as the original Graph is parsed
So for example it would automatically add the following:
<my:Eukaryota> <rdf:type> <my:Organism>.
<my:Mammal> <rdf:type> <my:Organism>.
<my:Mammal> <rdf:type> <my:Eukaryota>.
<my:Primate> <rdfs:type> <my:Organism>.
<my:Primate> <rdfs:type> <my:Eukaryota>.
<my:Primate> <rdfs:type> <my:Mammal>.
# etc...
How you do this in Jena I'm not sure, someone else who knows Jena would have to answer that.
As for SPARQL laalto is again entirely correct, in some cases though you might be able to do a simple query like the following if the Triple Store and the associated SPARQL endpoint you query have some inference capabilities
PREFIX my: <http://yournamespace.com>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
ASK { my:HomoSapiens rdf:type my:Mammal }
SPARQL 1.1 has arbitrary depth graph traversal. Which can be used for this. See related question at BioStar
ASK { :HomoSapiens rdfs:subClassOf+ :Mammal }