Open dlutz2 opened 7 years ago
While class expressions describe sets of individuals than can be queried via SPARQL SELECT
queries, it's not clear what queries you expect to get for ABox axioms.
Maybe we should generate SPARQL ASK
queries in that case?
I would find class expression -> SPARQL rewriting helpful, too. Maybe that's because I make punning statements? For example, I need to find all drug prescription individuals that mention any drug tablet that (indirectly) has the drug 'rosuvastatin' as an active ingredient
X a 'drug prescription' http://purl.obolibrary.org/obo/PDRO_0000024 X mentions 'rosuvastatin Oral Tablet' http://purl.obolibrary.org/obo/DRON_00027869
'rosuvastatin Oral Tablet' Superclasses & Asserted Axioms: drug tablet has_proper_part some (scattered molecular aggregate and (is bearer of some active ingredient) and (has granular part some rosuvastatin))
where rosuvastatin is http://purl.obolibrary.org/obo/DRON_00018679
See also https://stackoverflow.com/questions/51001818/rewrite-owl-class-expression-as-sparql-query
The example code:
var ce2s = new OWLClassExpressionToSPARQLConverter()
var a2s = new OWLAxiomToSPARQLConverter("?s", "?o")
var preManager = new OWLManager
var manager = OWLManager.createOWLOntologyManager()
var ontology = manager.loadOntologyFromOntologyDocument(new File("animals.owl"))
var factory = manager.getOWLDataFactory()
var iri = IRI.create("http://example.com/carnivore")
var someClass = factory.getOWLClass(iri)
var declarationAxiom = factory.getOWLDeclarationAxiom(someClass)
println(declarationAxiom)
var asSparql = a2s.convert(declarationAxiom, "?s", "?o")
Ontology: <http://example.com/animals.owl>
ObjectProperty: <http://example.com/eats>
Class: <http://example.com/animal>
Class: <http://example.com/carnivore>
EquivalentTo:
<http://example.com/eats> some <http://example.com/animal>
SubClassOf:
<http://example.com/animal>
example output:
sbt:hello> run
[info] Packaging /home/mark/owl2sparql4turbo/target/scala-2.10/hello_2.10-1.0.jar ...
[info] Done packaging.
[info] Running HelloWorld
Declaration(Class(<http://example.com/carnivore>))
with the warning
0 [run-main-0] WARN org.aksw.owl2sparql.OWLAxiomToSPARQLConverter - Ignoring axiom Declaration(Class(http://example.com/carnivore)) . Reason: Annotation axioms are not supported. [success] Total time: 1 s, completed Jun 23, 2018 10:33:33 AM
expected output:
select ?s
where
{
?s rdfs:subClassOf <http://example.com/animal> ?r .
?r a owl:Restriction ;
owl:onProperty <http://example.com/eats> ;
owl:someValuesFrom <http://example.com/animal> .
}
Thank you for the request. Will check tomorrow what's not working as expected.
@turbomam Regarding your example, an OWL declaration axiom is just a statement about the type of the entity. It doesn't contain any meaningful but just declares the existence and the type. In the ontology two axioms do exist, you'd have to use one of those axioms as input.
I added an experimental converter from an OWL class expression to a SPARQL query that retrieves subclasses: https://github.com/SmartDataAnalytics/OWL2SPARQL/blob/develop/src/main/java/org/aksw/owl2sparql/OWLClassExpressionToSPARQLSubClassQueryConverter.java
Right now, it is only in the develop
branch and of course it's missing documentation.
You'll need 0.2-SNAPSHOT
version as dependency.
Not sure whether this is what you need, but you could check with your use-case and let me know what's missing resp. is what's wrong.
Usage:
OWLClassExpressionToSPARQLSubClassQueryConverter converter = new OWLClassExpressionToSPARQLSubClassQueryConverter();
String targetVar = "?x";
OWLClassExpression ce = ...
// with more compact notation of blank nodes
String queryStr = converter.convert(ce, targetVar);
// alternatively, the Jena query object
Query query = converter.asQuery(ce, targetVar);
Thanks. It's possible that you have provided exactly what I was asking for, but I can't seem to get it to write a query for anything besides ?x rdfs:SubClassOf ?x
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#>
Prefix: xml: <http://www.w3.org/XML/1998/namespace>
Prefix: xsd: <http://www.w3.org/2001/XMLSchema#>
Ontology: <http://example.com/animals.owl>
ObjectProperty: <http://example.com/eats>
Class: <http://example.com/animal>
Class: <http://example.com/carnivore>
SubClassOf:
<http://example.com/animal>
and (<http://example.com/eats> some <http://example.com/animal>)
import org.aksw.owl2sparql._
import org.semanticweb.owlapi.apibinding.OWLManager
import org.semanticweb.owlapi.model.IRI
import java.io.File
object HelloWorld {
def main(args: Array[String]): Unit = {
var manager = OWLManager.createOWLOntologyManager()
var ontology = manager.loadOntologyFromOntologyDocument(new File("animals.owl"))
var factory = manager.getOWLDataFactory()
var iri = IRI.create("http://example.com/carnivore")
var someClass = factory.getOWLClass(iri)
var declarationAxiom = factory.getOWLDeclarationAxiom(someClass)
var scConverter = new OWLClassExpressionToSPARQLSubClassQueryConverter();
var targetVar = "?x";
var queryStr = scConverter.convert(someClass, targetVar)
println(queryStr)
}
}
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT ?x WHERE { ?x rdf:type owl:Class ;
rdfs:subClassOf <http://example.com/carnivore> .
}
select ?s
where
{
?s rdfs:SubClassOf <http://example.com/animal> , ?r .
?r a owl:Restriction ;
owl:onProperty <http://example.com/eats> ;
owl:someValuesFrom <http://example.com/animal> .
}
As I said before, a declaration axiom is just a statement about the type and existence of an entity, see the W3C documentation. That's why
factory.getOWLDeclarationAxiom(someClass)
is not what I guess you expect. First of all, you're using the datafactory, thus, it's creating a new axiom and not querying existing axioms in the ontology (doesn't matter in this case, but for others it would - clearly you're interested in axioms contained in the ontology). In your example,
Class: <http://example.com/animal>
is a declaration axiom, just stating that there is an OWL class called http://example.com/animal
.
An OWL ontology consists of a set of OWL axioms. What you'd need in your example is to get the superclass of http://example.com/carnivore
- and indeed that's defined in a SubClassOf axiom here (might also be defined by means of an EquivalentClasses axiom).
Note, there might be multiple axioms!
OWL API provides access to what you want by
1) the OWLOntology
object with getSubClassAxiomsForSubClass(OWLClass cls)
method - in this case you'll get axioms and have to extract the superclasses by yourself
2) EntitySearcher.getSuperClasses(OWLClass e, OWLOntology ontology)
- here you'll get class expressions. as a warning, this won't cover class expressions in EquivalentClasses axioms
3) StructuralReasoner
with getSuperClasses(OWLClassExpression ce, boolean direct)
Thanks, your feedback was very helpful.
I have switched my example (https://github.com/turbomam/owl2sparql4turbo, specifially https://github.com/turbomam/owl2sparql4turbo/blob/master/src/main/scala/ROTS.scala) from using an extremely short ontology about animals to a slightly longer ontology about my real problem, drug tablets.
Now I get the kind of output I hoped for:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT ?x WHERE { ?x rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty <http://www.obofoundry.org/ro/ro.owl#has_proper_part> ;
owl:someValuesFrom [ owl:intersectionOf ( <http://purl.obolibrary.org/obo/OBI_0000576>
[ rdf:type owl:Restriction ;
owl:onProperty <http://purl.obolibrary.org/obo/BFO_0000053> ;
owl:someValuesFrom <http://purl.obolibrary.org/obo/DRON_00000029>
]
[ rdf:type owl:Restriction ;
owl:onProperty <http://purl.obolibrary.org/obo/BFO_0000071> ;
owl:someValuesFrom <http://purl.obolibrary.org/obo/CHEBI_30618>
]
) ;
rdf:type owl:Class
]
] .
}
for an input like
...
Class: obo:DRON_00027869
Annotations:
rdfs:label "rosuvastatin Oral Tablet"^^xsd:string,
obo:DRON_00010000 "402354"^^xsd:string
SubClassOf:
obo:DRON_00000022,
<http://www.obofoundry.org/ro/ro.owl#has_proper_part> some
(obo:OBI_0000576
and (obo:BFO_0000053 some obo:DRON_00000028)
and (obo:BFO_0000071 some obo:DRON_00018679))
...
Is support for ABox axioms planned? Individuals in class expressions seem to be supported. Or am I missing something? thanks