-
-
Save jindrichmynarz/c2e332d5ab35b47d95f17bb78dfccc07 to your computer and use it in GitHub Desktop.
# SPARQL 1.1 implementation of concise bounded description (<https://www.w3.org/Submission/CBD>). | |
PREFIX : <http://example.com/> | |
PREFIX non: <http://non/> | |
CONSTRUCT { | |
:resource ?p1 ?r1 . | |
?r2 ?p2 ?r3 . | |
} | |
WHERE { | |
# :resource is the IRI of the resource we want to describe. | |
:resource ?p1 ?r1 . | |
OPTIONAL { | |
# Since variables cannot be used in SPARQL 1.1 property paths | |
# we can ask for any but a (presumably) non-existent property. | |
# We use zero or more quantifier (i.e. "*") to recursively | |
# expand to blank node neighbourhood. | |
?r1 (!non:existent)* ?r2 . | |
FILTER (isBlank(?r1) && isBlank(?r2)) | |
?r2 ?p2 ?r3 . | |
} | |
} |
@prefix : <http://example.com/> . | |
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |
:resource a :C ; | |
:p1 [ | |
a :D ; | |
:p2 [ | |
a :E | |
] | |
] . | |
:C a rdfs:Class . | |
:D a rdfs:Class . | |
:E a rdfs:Class . |
Furthermore this is completely be impractical on any but the tiniest stores
How about restricting the paths between ?r1
and ?r2
to blank nodes only?
PREFIX : <http://example.com/>
PREFIX non: <http://non/>
CONSTRUCT {
<urn:X> ?p1 ?r1 .
?r2 ?p2 ?r3 .
}
WHERE {
<urn:X> ?p1 ?r1
OPTIONAL {
?r1 (!non:existent)* ?r2 .
FILTER (isBlank(?r1) && isBlank(?r2))
FILTER NOT EXISTS {
?r1 (!non:existent)+ ?mid .
?mid (!non:existent)* ?r2 .
FILTER (!isBlank(?mid))
}
?r2 ?p2 ?r3 .
}
}
Returns the following for the example data (using Jena ARQ version 3.3.0):
<urn:X> <urn:p> [ <urn:p> <urn:Y> ] .
Regarding the impracticality for real data, this is only an exploration of an idea. I haven't tried it with non-toy data.
OK, start with crazy and then double down -- I like it! =)
I can't check at the moment but you may try ARQ on this:
<urn:X> <urn:p> _:b1 .
_:b1 <urn:p> <urn:Y>, _:b2 .
<urn:Y> <urn:p> _:b2 .
_:b2 <urn:p> <urn:Z> .
I think your mid-point filter might now break the _:b1 -> _:b2
path because there's an alternative path via :Y
. But it's late and I could easily be wrong.
You're right. Again, there are corner cases that break the query. There's no free lunch.
Yeah. This is the main reason we implemented SPARQL-style path queries in Stardog. Traversals are hard in pure SPARQL.
I don't see the correspondence between recursive CBD and Stardog path queries. Is it possible to implement the recursive CBD in Stardog-flavoured SPARQL?
We plan to use PATH for that but from what I know we cannot use it in sub-selects right now
No, not really. The problem is that
?r1 (!non:existent)* ?r2
would also match pairs of bnodes which are connected via IRI nodes, while you want bnode-only paths. Counter example:Results for
<urn:X>
: