Отрицание SPARQL: Все foaf:Агенты, которые не foaf:Люди

Я пытаюсь написать запрос SPARQL, который должен дать мне все foaf:Agents, которые не являются foaf:Persons.

Я не вижу способа применить эту НЕОБЯЗАТЕЛЬНУЮ/СВЯЗАННУЮ конструкцию к этой проблеме, потому что все свойства, такие как rdfs:subClassOf и rdf:type, транзитивны и рефлексивны.

Я пробовал это:

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

Но rdf:type кажется транзитивным, по крайней мере, с JENA/ARQ/SDB.


person Juri Glass    schedule 23.10.2009    source источник


Ответы (5)


Причина, по которой это не работает, заключается в том, что у вас есть две отдельные привязки переменных (?x и ?y), которые не связаны в вашем запросе. Таким образом, ?x должен быть связан, чтобы появиться в наборе результатов (это то, что вы хотите), но если ?y не связан, вы не узнали ничего нового о ?x.

Обновление: в идеальном запросе вообще не было бы необходимости в ?y; вы можете напрямую протестировать входящие/исходящие потоки ?x. Это сложно (невозможно?) сделать в SPARQL 1.0, когда вы хотите проверить, не существует ли ребро для данной привязки переменной. Однако SPARQL 1.1 поддерживает отрицание:

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 (с использованием сторонних расширений SPARQL) должен помочь вам решить проблему в краткосрочной перспективе.

person Phil M    schedule 23.10.2009
comment
Но как установить отношение между ?x и ?y ? - person Juri Glass; 24.10.2009
comment
SPARQL 1.1 определенно будет иметь отрицание, рабочая группа на ISWC 2009 была ясна в этом - person RobV; 30.10.2009
comment
Обратите внимание, что синтаксис SPARQL 1.1 (как указано в ссылке) на самом деле теперь FILTER NOT EXISTS (требуется ключевое слово FILTER впереди) - person Tom Saleeba; 11.05.2017

Чтобы сделать это в SPARQL 1.0, вам нужно написать:

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

По словам Фила М., в SPARQL 1.1 будет представлен новый синтаксис, который значительно упростит написание.

person Lee    schedule 25.10.2009

Вот (черновик) спецификации SPARQL 1.1 для отрицания: http://www.w3.org/TR/sparql11-query/#negation

person Dan Brickley    schedule 06.09.2011

Через конечную точку Virtuoso SPARQL Extensions для проверки http://lod.openlinksw.com/sparql (LOD Cloud Cache Экземпляр)

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 
person Kingsley Uyi Idehen    schedule 24.10.2009

Следующее теперь работает благодаря 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 . })
}

Ссылки на живые примеры:

  1. Решение запроса

  2. Определение запроса

person Kingsley Uyi Idehen    schedule 13.04.2013