Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SPARQL Negation: All foaf:Agents which aren't foaf:Persons

Tags:

rdf

sparql

foaf

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.

like image 242
Juri Glass Avatar asked Oct 23 '09 19:10

Juri Glass


People also ask

What is Sparql used for?

SPARQL can be used to express queries across diverse data sources, whether the data is stored natively as RDF or viewed as RDF via middleware. SPARQL contains capabilities for querying required and optional graph patterns along with their conjunctions and disjunctions.

Which clauses in Sparql can be used to match partial information in an RDF graph?

The query consists of two parts: the SELECT clause identifies the variables to appear in the query results, and the WHERE clause provides the basic graph pattern to match against the data graph.

Is Sparql case sensitive?

CAPS: Though SPARQL is case-insensitive, SPARQL keywords in this section are written in uppercase for readability. Italics: Terms in italics are placeholder values that you replace in the query.

What is bind in Sparql?

BIND. SPARQL's BIND function allows us to assign a value to a variable.


2 Answers

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

like image 191
Kingsley Uyi Idehen Avatar answered Sep 21 '22 23:09

Kingsley Uyi Idehen


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.

like image 41
Phil M Avatar answered Sep 19 '22 23:09

Phil M