I am trying to write a SPARQL query which should give me all foaf:Agents
which aren't foaf:Persons
.
I can't see a way to apply this OPTIONAL/BOUND construct to this problem, because all the properties like rdfs:subClassOf
and rdf:type
are transitive and reflexive.
I tried this:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
But rdf:type seems to be transitive, at least with JENA/ARQ/SDB.
The reason this isn't working is because you have two separate variable bindings (?x
and ?y
) which are unrelated in your query. So ?x
must be bound to appear in the result set (which is what you want), but if ?y
is unbound, you have not learned anything new about ?x
.
Update: In an ideal query, there would be no need for ?y
at all; you could test the incoming/outgoing edegs of ?x
directly. This is difficult (impossible?) to do in SPARQL 1.0 when you want to check if an edge does not exist on a given variable binding. However, SPARQL 1.1 will provide support for negation:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?agent
WHERE
{
?agent rdf:type foaf:Agent .
FILTER NOT EXISTS { ?agent rdf:type foaf:Person . }
}
@Kingsley Idehen's approach (using third-party SPARQL extensions) should help you solve the problem in the short run.