2

I have an ontology something like:

:indi_1 a :Segment; a [ :builds only {:indi_2}]; :hasID 1.

Now I want to find the individual(s) which indi_1 builds. I made the following query:

SELECT distinct ?a
WHERE {:indi_1 a ?b. ?b a _:blankNode}

but I still get the segment in my results. Plus I can't reach inside the blank node to retrive the indi_2.

How should I build my query?

msc87
  • 943
  • 3
  • 17
  • 39

1 Answers1

4

I don't know why you'd expect ?b a :blankNode to require that ?b is a blank node. :blankNode is a blank node, which in a SPARQL query like this acts as a variable, so it's just requiring that ?b has some type. Your query as written isn't even legal. It looks like you want :indi_1 a ?b . ?b a _:blankNode instead (note the ., not a ;).

At any rate, to check whether something a blank node, look at the SPARQL 1.1 spec, and notice that there's an isBlank function. That's what you'd use to filter your results. You'd have something like this:

select * {
  ?a a ?b 
  filter isBlank(?b)
}

But if what you're actually looking for is the list of individuals, you actually need to look a bit more closely at the RDF serialization of your data. You don't actually care that ?b is blank, but rather that it's a restriction with the right properties. From an axiom like:

    :a builds only {:b, :c}

you end up with RDF like this:

:a      a       owl:NamedIndividual , owl:Thing ;
        a       [ a                  owl:Restriction ;
                  owl:allValuesFrom  [ a          owl:Class ;
                                       owl:oneOf  ( :c :b )
                                     ] ;
                  owl:onProperty     :builds
                ] .

So your query would be:

prefix :      <http://www.example.org/>
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#>

select ?x ?y {
  ?x a [ owl:allValuesFrom [ owl:oneOf/rdf:rest*/rdf:first ?y ] ] .
}
-----------
| x  | y  |
===========
| :a | :c |
| :a | :b |
-----------

You can clean that up a little bit with more property paths:

select ?x ?y {
  ?x rdf:type/owl:allValuesFrom/owl:oneOf/rdf:rest*/rdf:first ?y .
}

OWL isn't the same as RDF. SPARQL is an RDF query language. OWL can be serialized as RDF, but the serialization isn't always all that pretty, so SPARQL isn't necessarily the best way to query OWL, even though OWL can be serialized to RDF. It's kind of like searching for text in a document by searching for specific bytes or bits in the file. It might work, but if someone were to change the character encoding, you could have the same text, but different bytes or bits, so the query might not work anymore.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Or use something like SPARQL DL if the ontology fits into memory and no CWA is needed. – UninformedUser Jul 25 '17 at 18:36
  • The query you are suggesting is working for me. Thanks a lot! As far as I know, for SPARQL DL, I need to have my ontology reasoned which is not possible as it is too complex to be reasoned. So I am extracting information in a hard way by coding, That's why I needed this query. – msc87 Jul 26 '17 at 11:48