Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Support for ABox axioms #3

Open
dlutz2 opened this issue Mar 10, 2017 · 7 comments
Open

Enhancement: Support for ABox axioms #3

dlutz2 opened this issue Mar 10, 2017 · 7 comments
Assignees

Comments

@dlutz2
Copy link

dlutz2 commented Mar 10, 2017

Is support for ABox axioms planned? Individuals in class expressions seem to be supported. Or am I missing something?
thanks

@LorenzBuehmann
Copy link
Member

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?

@turbomam
Copy link

turbomam commented Jun 23, 2018

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

Copied from StackOverflow question

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")

example ontology:

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> .
}

@LorenzBuehmann
Copy link
Member

Thank you for the request.
Will check tomorrow what's not working as expected.

@LorenzBuehmann
Copy link
Member

@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);

@turbomam
Copy link

turbomam commented Jun 25, 2018

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

animals.owl

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>)

Scala script

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)

  }
}

actual output

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> .
}

expected/desire 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> .
}

@LorenzBuehmann
Copy link
Member

LorenzBuehmann commented Jun 26, 2018

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)

@turbomam
Copy link

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))
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants