Классы и подклассы в OWL для запросов SPARQL с выводом

У меня есть вопрос по OWL и SPARQL, который я не могу решить. Я определил несколько классов, но для рассматриваемого вопроса важны только 3: Люди, мужчины и женщины; и его определения будут следующими:

<#People> a owl:Class ;
    rdfs:label "People"@en .

<#Men> a owl:Class ;
    rdfs:subClassOf <#People> ;
    rdfs:label "Men"@en .

<#Women> a owl:Class ;
    rdfs:subClassOf <#People> ;
    rdfs:label "Women"@en .

А затем данные в RDF, например:

<rdf:Description rdf:about="Registration#1">
    <rdfs:label>ARCHEOLOGY GRADUATE</rdfs:label>
    <ex:BranchKnowledge>ARTS AND HUMANITIES</ex:BranchKnowledge>
    <ex:Degree>ARCHEOLOGY GRADUATE</ex:Degree>
    <ex:Men rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">63</ex:Men>
    <ex:Women rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">99</ex:Women>
    <dcterms:coverage>2015/2016</dcterms:coverage>
</rdf:Description>

Если бы я хотел получить количество мужчин и женщин для каждого набора данных, я получил бы его с помощью следующего запроса:

SELECT ?X ?degree ?branch ?men ?women
WHERE {
  ?X ex:Degree ?degree .
  ?X ex:BranchKnowledge ?branch .
  ?X ex:Men ?men .
  ?X ex:Women ?women
}

Если теперь я хочу получить общее количество мужчин и женщин, делающих вывод, что оба являются людьми, я подумал, что, поскольку оба являются подклассами людей, я мог бы сделать следующий запрос:

SELECT ?X ?degree ?branch ?people
WHERE {
  ?X ex:Degree ?degree .
  ?X ex:BranchKnowledge ?branch .
  ?X ex:People ?people
}

Однако я не получаю никаких результатов.

Я неправильно истолковал отношения между классами и подклассами для того, что я хочу сделать, или в чем может быть проблема? (Я работаю на сервере Virtuoso).


person germaaan    schedule 22.06.2017    source источник
comment
Вы должны знать, что используете каламбур, то есть тот же URI для Men и Women, что и классы OWL и свойства данных OWL. Я не понимаю, зачем ты это делаешь.   -  person UninformedUser    schedule 22.06.2017
comment
Затем вы используете ex:People как свойство, поэтому вам нужно будет определить, что ex:Men и ex:Women являются подсвойствами ex:People. И тогда вы должны включить рассуждение в тройном хранилище, если оно поддерживается.   -  person UninformedUser    schedule 22.06.2017
comment
Но, что более важно, это приведет только к двум строкам, а это значит, что вам придется выполнять агрегацию в запросе SPARQL с помощью функции sum.   -  person UninformedUser    schedule 22.06.2017


Ответы (1)


Вы должны знать, что используете каламбур, то есть тот же URI для Men и Women, что и классы OWL и свойства данных OWL. Я не понимаю, зачем ты это делаешь. Почему бы вам не ввести такие свойства, как numberOfMen, numberOfWomen и numberOfPeople?

Затем вы используете ex:People как свойство, поэтому вам нужно определить, что ex:Men и ex:Women являются подсвойствами ex:People.

<#People> a owl:DatatypeProperty ;
    rdfs:label "People"@en .

<#Men> a owl:DatatypeProperty ;
    rdfs:subPropertyOf <#People> ;
    rdfs:label "Men"@en .

<#Women> a owl:DatatypeProperty ;
    rdfs:subPropertyOf <#People> ;
    rdfs:label "Women"@en .

Затем вам нужно включить рассуждение в тройном хранилище, если оно поддерживается, или использовать пути к свойствам SPARQL 1.1.

Но, что более важно, это приведет только к двум строкам, что означает, что вам нужно выполнить агрегацию в запросе SPARQL с помощью функции sum, например:

SELECT ?X ?degree ?branch (sum(?_people) as ?people)
WHERE {
  ?X ex:Degree ?degree .
  ?X ex:BranchKnowledge ?branch .
  ?p rdfs:subPropertyOf* ex:People .
  ?X  ?p ?_people
}
GROUP BY ?X ?degree ?branch

Обратите внимание, что этот запрос работает только в том случае, если есть только одна степень и ветвь, иначе он будет суммировать повторяющиеся значения.

person UninformedUser    schedule 22.06.2017
comment
Поскольку онтология не очень сложна, я подумал о том, чтобы поместить все классы и типы данных в один и тот же URI, взяв за основу один адрес и ссылаясь на каждый элемент символом #; это первый раз, когда мне приходится полностью строить онтологию, и я видел, как это делается в нескольких местах. Идея определения их как класса состоит в том, чтобы иметь возможность ссылаться на эквивалентные классы DBpedia или Schema.org. Возможно, я следую неправильному подходу? - person germaaan; 23.06.2017
comment
Кстати, после изменения #Люди, #Мужчины и #Женщины на owl: DatatypeProperty, я получаю ошибку в заданном вами запросе (syntax error at '?X' before '?p'), но #Мужчины и #Женщины по отдельности все равно дают мне правильный результат. Есть ли что-то, что я могу делать неправильно? - person germaaan; 23.06.2017
comment
отсутствовал .. Я исправил это сейчас - person UninformedUser; 23.06.2017
comment
Наконец-то мне удалось понять и заставить это работать благодаря вашему ответу. Спасибо. - person germaaan; 10.07.2017