SPARQL Negación: Todos foaf: Agentes que no son foaf: Personas
Pregunta
Estoy tratando de escribir una consulta SPARQL que debería proporcionarme todos los foaf: Agents
que no son foaf: Persons
.
No puedo ver una manera de aplicar este OPCIONAL / BOUND construya este problema, porque todas las propiedades como rdfs: subClassOf
y rdf: type
son transitivas y reflexivas.
He intentado esto:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person }
FILTER ( !BOUND(?y) ) }
Pero rdf: type parece ser transitivo, al menos con JENA / ARQ / SDB.
Solución
La razón por la que esto no funciona es porque tiene dos enlaces de variables independientes (? x
y ? y
) que no están relacionados en su consulta. Por lo tanto, ? X
debe estar obligado a aparecer en el conjunto de resultados (que es lo que desea), pero si ? Y
no está vinculado, no ha aprendido nada nuevo sobre ? x
.
Actualización: en una consulta ideal, no habría necesidad de ? y
en absoluto; usted podría probar los edegs entrantes / salientes de ? x
directamente. Esto es difícil (¿imposible?) En SPARQL 1.0 cuando quiere verificar si no existe un borde en un enlace de variable dado. Sin embargo, SPARQL 1.1 proporcionará soporte para la negación:
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 . }
}
El enfoque de @Kingsley Idehen (usar extensiones SPARQL de terceros) debería ayudarlo a resolver el problema a corto plazo.
Otros consejos
Para hacer esto en SPARQL 1.0, deberías escribir:
SELECT * WHERE {
?x rdf:type foaf:Agent
OPTIONAL { ?y rdf:type foaf:Person . FILTER (?x = ?y) . }
FILTER ( !BOUND(?y) )
}
Como dice Phil M , SPARQL 1.1 introducirá una nueva sintaxis para que esto sea mucho más sencillo de escribir.
Aquí está la especificación de SPARQL 1.1 (borrador) para la negación: http: // www. w3.org/TR/sparql11-query/#negation
Extensiones SPARQL de Via Virtuoso punto final para la verificación http://lod.openlinksw.com/sparql (instancia de caché en la nube de LOD)
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
Lo siguiente ahora funciona, cortesía de 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 . })
}
Enlaces de ejemplo en vivo: