【问题标题】:Classes and subclasses in OWL for SPARQL queries with inferenceOWL 中用于推理的 SPARQL 查询的类和子类
【发布时间】:2017-06-22 12:16:15
【问题描述】:

我有一个无法解决的关于 OWL 和 SPARQL 的问题。我已经定义了几个类,但是对于所讨论的问题,只有 3 个是重要的:People, Men and Women;其定义如下:

<#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
}

如果我现在想得到推断两者都是 People 的男性和女性的总数,我认为由于两者都是 People 的子类,我可以进行以下查询:

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

但是我没有得到任何结果

我是否误解了类和子类之间的关系以实现我想要做的事情或会出现什么问题? (我正在使用 Virtuoso 服务器)。

【问题讨论】:

  • 您应该知道您正在使用双关语这一事实,即 MenWomen 的 URI 与 OWL 类和 OWL 数据属性相同。我不明白你为什么要这样做。
  • 接下来,您使用ex:People 作为属性,因此,您必须定义ex:Menex:Womenex:People 的子属性。如果支持,您必须在三重存储中启用推理。
  • 但是,更重要的是,这只会导致两行,这意味着您必须使用 sum 函数在 SPARQL 查询中进行聚合。

标签: sparql owl semantic-web ontology linked-data


【解决方案1】:

您应该意识到您正在使用双关语这一事实,即 MenWomen 的 URI 与 OWL 类和 OWL 数据属性相同。我不明白你为什么要这样做。为什么不介绍numberOfMennumberOfWomennumberOfPeople 之类的属性?

接下来,您使用ex:People 作为属性,因此,您必须定义ex:Menex:Womenex: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 属性路径。

但是,更重要的是,这只会导致两行,这意味着您必须使用 sum 函数在 SPARQL 查询中进行聚合,例如:

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

请注意,此查询仅在只有一个度数和分支时才有效,否则它将对重复值求和。

【讨论】:

  • 由于本体不是很复杂,我曾想过将所有类和数据类型放在同一个URI中,以单个地址为基础,并用#引用每个元素;这是我第一次必须完全构建一个本体,就像我在几个地方看到过一样。将它们定义为一个类的想法是能够引用 DBpedia 或 Schema.org 的等效类。我是否采用了错误的方法?
  • 顺便说一句,在将 #People、#Men 和 #Women 更改为“owl: DatatypeProperty”后,我在您输入的查询中遇到错误 (syntax error at '?X' before '?p'),但 #Men和#Women 分开仍然给我正确的结果。有什么我做错了吗?
  • 缺少.。我现在修好了
  • 感谢您的回复,我终于理解并使它工作了。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-08-25
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
相关资源
最近更新 更多