Using SPARQL for limited RDFS and OWL reasoning
Asked Answered
I

2

10

What I'm currently using rdflib for creating and managing RDF graphs in Python. RDFlib doesn't do any RDFS or OWL reasoning, though. This leads to results like the following:

  1. If I have

    A rdf:type MyType .
    MyType rdfs:subClassOf SuperType .
    

    and I ask

    select ?x where {?x rdf:type SuperType}
    

    then I get nothing, but I'd like to get A (by RDFS semantics).

  2. The same thing happens with owl:equivalentClass. If I have

    A rdf:type MyType .
    MyType owl:equivalentClass SiblingType .
    

    and I ask

    select ?x where {?x rdf:type SiblingType}
    

    I'd like to get A, but I get nothing.

Is there a way to get these results?

Impractical answered 9/12, 2013 at 15:56 Comment(5)
For rdflib, this thread on answers.semanticweb.com may be usefulMagic
See also this Survey of Pythonic Tools for RDF and Linked DataMagic
Please note that "Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it."Symphonize
The answer provided so far is correct. The library you're using for RDF is fine; the problem is that you're looking for something that can do RDFS or OWL reasoning.Symphonize
At the risk of invalidating the other answer, I've edited this question to be on-topic by changing it to "how can we get the expected results with SPARQL?" This question is on topic, whereas the original (asking for Python libraries) was not.Symphonize
S
10

Although this is a library request problem and, as such, off topic for StackOverflow, I would like to point out that for many cases, you can answer both of these queries using sightly more sophisticated SPARQL queries. For both of these cases, you could use the following query to get the results you want, where <class-of-interest> is :SuperClass or :SiblingClass:

select ?x where {
  ?x rdf:type/(rdfs:subClassOf|owl:equivalentClass)* <class-of-interest> .
}

This finds ?xs that have a path to starting with rdf:type and followed by zero or more of rdfs:subClassOf or owl:equivalentClass and eventually gets to :SuperType.

For instance, consider the following data in Turtle/N3. (As an aside, if you're asking questions about running queries against data, provide data that we can work with. You provided something sort of like RDF data in your question, but nothing that we could copy and paste and write a query against.)

@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <https://mcmap.net/q/1060937/-using-sparql-for-limited-rdfs-and-owl-reasoning/1281433/>

:i1 a :C .
:C rdfs:subClassOf :D .
:D rdfs:subClassOf :E .

:i2 a :F .
:F rdfs:subClassOf :G1 .
:G1 owl:equivalentClass :G2 .
:G2 rdfs:subClassOf :H .

You can run a query like the one above to select individuals and their types (note that a is shorthand in SPARQL and Turtle/N3 for rdf:type):

prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://mcmap.net/q/1060937/-using-sparql-for-limited-rdfs-and-owl-reasoning/1281433/>

select ?i ?type where {
  ?i a/(rdfs:subClassOf|owl:equivalentClass)* ?type
}
--------------
| i   | type |
==============
| :i2 | :F   |
| :i2 | :G1  |
| :i2 | :G2  |
| :i2 | :H   |
| :i1 | :C   |
| :i1 | :D   |
| :i1 | :E   |
--------------
Symphonize answered 9/12, 2013 at 18:13 Comment(5)
Thank you @Joshua, did you get this result using redlib?Impractical
@Impractical Actually, I was using Jenna's command line tools. It's standard SPARQL 1.1 though, so it should work anywhere.Symphonize
@JoshuaTaylor thank you this query really helpful, kindly do you know where can I find the syntax you wrote? the one contains / and * so I can have a look about the other possible queries/features that sparql 1.1 hasHurling
@ania as I've said before many times, it's all in the documentation. If you search for "property path" in the SPARQL 1.1 spec, it'll come right up. (Granted, you would need to know the term "property path" in advance, in order to know what to search for, but I think I've mentioned it before. ..)Symphonize
@ania specifically, see section 9 Property Paths.Symphonize
P
9

Edit: this answer was posted in response to the original, different question.

I should get A, but I get nothing!

No, you shouldn’t. RDF itself does not include anything about ontologies, it’s just a dumb graph, and that is what RDFLib does.

Going beyond this is called reasoning over the data. It’s an extra layer. Bare RDFLib does not do reasoning because it is complex and, in general, very computationally expensive. There are third-party solutions for reasoning, but before you employ them, you ought to understand what they do and what performance impact they will have.

A naive approach to RDFS and OWL 2 reasoning over an RDFLib graph is Ivan Herman’s OWL 2 RL implementation. It’s very easy to use, but you almost certainly don’t want it unless you’re doing a toy application, because it’s a dumb algorithm that takes very long on a graph of a realistic size.

FuXi is a more powerful library, implementing the smarter Rete-UL algorithm. But I’m not sure if it is maintained or if it’s usable with the current versions of RDFLib.

There is also a wealth of non-Python-based solutions for reasoning, such as Pellet, but integrating them with RDFLib—or any other RDF library—may be a chore.

You should also consider what kind of inference your application actually requires. Do you need to infer that subclass membership? If you do, maybe it’s all you need? — then maybe you could do it manually by iterating over the X rdfs:subClassOf Y triples with RDFLib and inserting the new A rdf:type Y triples.

In any case, remember that Semantic Web reasoning is a complex topic that depends heavily on the application.

Panchito answered 9/12, 2013 at 18:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.