Удаление нежелательных ответов суперкласса в SPARQL
У меня есть файл OWL, который включает в себя таксономическую иерархию, в которую я хочу написать запрос, в котором ответ включает каждого человека и его непосредственного таксономического родителя. Вот пример (полный запрос довольно сложный).
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <urn:ex:> .
:fido rdf:type :Dog .
:Dog rdfs:subClassOf :Mammal .
:Mammal rdfs:subClassOf :Vertebrate .
:Vertebrate rdfs:subClassOf :Animal .
:fido :hasToy :bone
:kitty rdf:type :Cat .
:Cat rdfs:subClassOf :Mammal .
:kitty :hasToy :catnipMouse .
И этот запрос делает то, что я хочу.
prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
prefix : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual rdf:type ?type .
}
Проблема в том, что я предпочел бы использовать аргументированную версию файла OWL, которая неудивительно, что включает в себя дополнительные утверждения:
:fido rdf:type :Mammal .
:fido rdf:type :Vertebrate .
:fido rdf:type :Animal .
:kitty rdf:type :Mammal .
:kitty rdf:type :Vertebrate .
:kitty rdf:type :Animal .
И теперь запрос приводит к дополнительным ответам о том, что Fido является млекопитающим, и т. Д. Я мог бы просто отказаться от использования аргументированной версии файла, или, поскольку запросы SPARQL вызываются из Java, я мог бы выполнить несколько дополнительных запросов к найти наименее включенный тип, который появляется. Мой вопрос заключается в том, существует ли разумное решение SPARQL для возврата только решения Dog.
1 ответ
Общее решение заключается в том, что вы просите указать только прямой тип. Класс C
это прямой тип экземпляра X
если:
X
имеет типC
- здесь нет
C'
такой что:X
имеет типC'
C'
это подклассC
C'
не равноC
(это последнее условие необходимо, кстати, потому что в RDF/OWL отношение подкласса является рефлексивным: каждый класс является подклассом сам по себе)
В SPARQL это выглядит примерно так:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual a ?type .
FILTER NOT EXISTS { ?individual a ?other .
?other rdfs:subClassOf ?type .
FILTER(?other != ?type)
}
}
В зависимости от того, какой API/ триплет-хранилище / библиотека вы используете для выполнения этих запросов, могут быть и другие, специфичные для инструмента решения. Например, API Sesame (раскрытие: я в команде разработчиков Sesame) имеет возможность отключить рассуждения для цели одного запроса:
TupleQuery query = conn.prepareTupleQuery(SPARQL, "SELECT ...");
query.setIncludeInferred(false);
TupleQueryResult result = query.evaluate();
Sesame также предлагает дополнительный дополнительный механизм вывода (называемый "непосредственным средством определения типа"), который вводит дополнительные "виртуальные" свойства, которые вы можете запрашивать, например: sesame:directType
, sesame:directSubClassOf
и т.д. Другие инструменты, несомненно, будут иметь аналогичные параметры.