SPARQL Negation: All foaf:Agents which aren't foaf:Persons
Asked Answered
A

5

13

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.

Atonsah answered 23/10, 2009 at 19:33 Comment(0)
G
13

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.

Gingerly answered 23/10, 2009 at 21:19 Comment(3)
But how do I set up a relation between ?x and ?y ?Atonsah
SPARQL 1.1 is definitely going to have negation, the working group panel at ISWC 2009 were clear on thatJaf
Note that SPARQL 1.1 syntax (as specified in the link) is actually FILTER NOT EXISTS now (needs the FILTER keyword up front)Barbosa
M
9

To do this in SPARQL 1.0, you'd have to write:

SELECT * WHERE { 
     ?x rdf:type foaf:Agent 
     OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . } 
     FILTER ( !BOUND(?y) ) 
}

As Phil M says, SPARQL 1.1 will introduce new syntax to make this much more straightforward to write.

Marita answered 25/10, 2009 at 1:4 Comment(0)
D
2

Via Virtuoso SPARQL Extensions endpoint for verification http://lod.openlinksw.com/sparql (LOD Cloud Cache Instance)

SELECT distinct ?x ?o 
WHERE { 
?x a foaf:Agent .
?x ?p ?o.
filter (!bif:exists ((select (1) where { ?x a foaf:Person } ))) 
} 
limit 10
DESCRIBE ?x 
WHERE { 
?x a foaf:Agent .
filter (!bif:exists ((select (1) where { ?x a foaf:Person } ))) 
} 
limit 200 
Divinadivination answered 24/10, 2009 at 14:32 Comment(0)
A
2

Here's the (draft) SPARQL 1.1 spec for negation: http://www.w3.org/TR/sparql11-query/#negation

Adequate answered 6/9, 2011 at 9:13 Comment(0)
D
2

The following now works, courtesy of SPARQL 1.1:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
SELECT DISTINCT COUNT(?agent)
WHERE 
{
    ?agent rdf:type foaf:Agent .
    FILTER (NOT EXISTS { ?agent rdf:type foaf:Person . })
}

Live example links:

  1. Query Solution

  2. Query Definition

Divinadivination answered 13/4, 2013 at 16:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.