【问题标题】:Sparql query Subclass or EquivalentToSparql 查询 Subclass 或 EquivalentTo
【发布时间】:2014-01-13 13:14:37
【问题描述】:

我想查询尼古丁(产品)的所有子类。
结果必须是(鼻形式尼古丁,来自 ni 的口咽部 ..(4 项).. 见图片) 我尝试通过 rdfs:subClassOf+ 和 owl:equivalentClass+ 进行查询,但没有成功 尝试从this example 这里的代码相同。

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>           
PREFIX owl: <http://www.w3.org/2002/07/owl#>        
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>         
SELECT * WHERE 
{       
  ?s owl:equivalentClass+ ?o . # and try   ?s rdfs:subClassOf ?o    
  filter(?s=<http://snomed.info/id/323283001>)       
}

this image from protege 谢谢。

第一个查询很难解释和做,因为文件太大,一些 IRI 不是子类也不是等效类,我改变了查询方式

<owl:Class rdf:about="http://snomed.info/id/323283001">
    <rdfs:label xml:lang="en">Nicotine (product)</rdfs:label>
    <rdfs:subClassOf>
        <owl:Class>
            <owl:intersectionOf rdf:parseType="Collection">
                <rdf:Description rdf:about="http://snomed.info/id/420383004"/>
                <rdf:Description rdf:about="http://snomed.info/id/425288007"/>
                <owl:Restriction>
                    <owl:onProperty rdf:resource="http://snomed.info/id/127489000"/>
                    <owl:someValuesFrom rdf:resource="http://snomed.info/id/68540007"/>
                </owl:Restriction>
            </owl:intersectionOf>
        </owl:Class>
    </rdfs:subClassOf>
</owl:Class>

我要查询所有id(id/420383004, id/425288007, id/127489000 and id/68540007)

来自 owl:Class rdf:about="http://snomed.info/id/323283001" 请告诉我一些想法。谢谢

【问题讨论】:

  • 我看不到那张图片。你可以使用,也许,imgur?然后有足够声誉的人可以更新您的问题以正确包含图片。
  • 啊,感谢您发布该更新。请注意,数据中没有三元组http://snomed.info/id/323283001 rdfs:subClassOf http://snomed.info/id/420383004,尽管前者是后者的子类。不过,通过使用稍微复杂一点的 SPARQL 查询,您可以获得简单的交集类。我会更新我的答案。但是,请求http://snomed.info/id/127489000 没有意义,因为它是一个属性,请求http://snomed.info/id/68540007 也没有意义,因为即使它是一个类,尼古丁也不是它的子类。
  • 谢谢。我们可以将 id/127489000 和 id/68540007 丢弃到查询中。
  • 好的,我已经更新了我的答案。

标签: rdf sparql owl protege description-logic


【解决方案1】:

首先,关于您的 SPARQL 查询的几点说明是有序的。第一个是关于*+ 在属性路径中的区别,第二个是关于filtervalues 的使用。然后我们可以看看如何从数据中查询不同类型的子类/超类关系。这里的技巧是,我们正在寻找的一些关系是我们通常会使用 OWL 推理器的关系,但我们正在尝试使用 SPARQL 进行一些 OWL 推理

关于原始查询的几点说明

属性路径,+*

请注意,在您链接到的另一个问题中,属性路径使用 * 运算符,这意味着长度为零或更长的路径。长度为零或更多的路径可能非常重要,因为如果您的表单数据中没有明确的三元组

:MyClass owl:equivalentClass :MyClass

你不会得到任何匹配的查询

?myClass owl:equivalentClass+ :MyClass

但你会得到一个结果(:MyClass

?myClass owl:equivalentClass* :MyClass

实际上,即使owl:equivalentClass 一个对称属性(即,从a owl:equivalentClass b我们可以推断 b owl:equivalentClass a),三元组可能只存在于数据中的一个方向,所以我们实际上需要

?myClass (owl:equivalentClass|^owl:equivalentClass)* :MyClass

使用values 代替filter

顺便说一句,请注意,在这个查询中,我直接在模式中使用了 IRI;无需像原始代码中那样filter

filter(?s=<http://snomed.info/id/323283001>)

如果您确实想将变量绑定到超类,使用values 会更容易,如

values ?superclass { <http://snomed.info/id/323283001> }
?subclass (rdfs:subClassOf|owl:equivalentClass)* ?superclass

通过 SPARQL 查询进行 OWL 推理

一般来说,类之间的关系(例如,子类和超类关系)是您可以使用 OWL 推理器为您确定的事情。但是,有些很简单,并且存在于 OWL 公理的 RDF 编码中,您可以使用 SPARQL 查询得出相同的结论。例如,如果您想在基于rdfs:subClassOfowl:equivalentClass 的层次结构中查找子类关系,您可以使用这样的模式:

?subclass (rdfs:subClassOf|owl:equivalentClass|^owl:equivalentClass)* ?superclass

现在,如下所述,您可能会在使用 Protégé 的 SPARQL 选项卡时遇到一些问题,因此我建议您将 | 的用法保留为二进制大小写,这样您就可以实际编写,在这种情况下:

?subclass (rdfs:subClassOf|(owl:equivalentClass|^owl:equivalentClass))* ?superclass

现在,您实际查看的数据使用了更复杂的类表达式。当你有一个形式为

的 OWL 公理时
A subClassOf (B and C)

你实际上是在说有一个类A,并且有一个(通常是匿名的)类是一个交集类,它是B的交集C。你没有公理

A subClassOf B
A subClassOf C

对您可用,尽管它们确实在逻辑上跟随。你得到的案例实际上也包括一个存在的限制,就像

A subClassOf (B and C and (p some D))

重要的是要注意 A 的超类是 B、C 和 (p some D)。特别是,A 不是 p 或 D 的子类。通过具体示例可能更容易看出:

TiredManWearingHat subClassOf(男人TiredPerson (戴一些帽子)

戴帽子的疲惫的人显然是男人,显然是疲倦的人,显然是戴着帽子的东西,但他肯定不是戴帽子的人(这甚至没有意义),而且他是当然不是帽子。这是一个最小的本体,它具有我们可以使用的结构:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns="https://stackoverflow.com/q/21092246/1281433/data.owl#">
  <owl:Ontology rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl"/>
  <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#C"/>
  <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#B"/>
  <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#A">
    <rdfs:subClassOf>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#B"/>
          <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#C"/>
          <owl:Restriction>
            <owl:onProperty>
              <owl:ObjectProperty rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#p"/>
            </owl:onProperty>
            <owl:someValuesFrom>
              <owl:Class rdf:about="https://stackoverflow.com/q/21092246/1281433/data.owl#D"/>
            </owl:someValuesFrom>
          </owl:Restriction>
        </owl:intersectionOf>
      </owl:Class>
    </rdfs:subClassOf>
  </owl:Class>
</rdf:RDF>

我已经为Retrieving superclasses implied by OWL intersection classes 写了一个答案,描述了如何编写关于交叉类的查询,所以我不会在这里再次解释所有内容,但我将包含一个适用于这种情况的查询.我展示的结果是我使用 Jena 的命令行 SPARQL 查询工具得到的结果。

prefix :      <https://stackoverflow.com/q/21092246/1281433/data.owl#> 
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> 
prefix owl:   <http://www.w3.org/2002/07/owl#> 
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 

select ?superclass where {
  :A (rdfs:subClassOf|(owl:intersectionOf/rdf:rest*/rdf:first))* ?superclass .
}
--------------
| superclass |
==============
| :A         |
| _:b0       |
| :B         |
| :C         |
| _:b1       |
--------------

现在,空白节点有匿名交叉类和匿名限制类。如果您不想将它们包含在结果中,可以很容易地将它们过滤掉:

prefix :      <https://stackoverflow.com/q/21092246/1281433/data.owl#> 
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> 
prefix owl:   <http://www.w3.org/2002/07/owl#> 
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 

select ?superclass where {
  :A (rdfs:subClassOf|(owl:intersectionOf/rdf:rest*/rdf:first))* ?superclass .
  filter(!isBlank(?superclass))
}
--------------
| superclass |
==============
| :A         |
| :B         |
| :C         |
--------------

如果您也想遵循等效类,也可以将^owl:equivalentClass|owl:equivalentClass 添加到该属性路径中。

在 Protégé 中执行此操作

正如我所说,上面的结果是使用 Jena 的命令行工具。你说你想在 Protégé 中做这件事,这让事情变得有点困难,因为它似乎引入了一些问题。我显示的最后一个查询仅在 Protégé 中产生 A 和 B;由于某种原因,它不包括 C:

但是,空白节点的处理要好一些(即,我们可以删除filter 并获得一些有用的输出):

不幸的是,我不确定如何获得与 Jena 在 Protégé 中提供的相同输出,但我正在通过电子邮件发送他们的邮件列表。

【讨论】:

  • 对不起先生。但不适合我。请试试这个 rdf 文件 sendspace.com/file/5olz6h 并使用 protege 来 sparql 查询这个 protege.stanford.edu/download/registered.html
  • @user3190242 这是一个 45 MB 的 rdf 文件。恐怕我无法下载和测试。请注意,StackOverflow 上的问题需要尽可能重现。请创建一个较小的本体,您可以将其复制并粘贴到问题中,并告诉我们您期望什么样的结果。如果没有一些数据可以使用,并且不知道您想要获得什么结果,我们无法做得比这更好。
  • 这一切都可以在 Protege 上进行测试,但不能在 DotNetRdf 上获得任何输出,它们是异常“集合中变量的值无法更改”这个错误发生在 rdf 附近:rest*/rdf:first 因为我尝试删除一些 * 然后没有错误也没有数据
  • @user3190242 您没有在问题中提到使用 dotNetRDF;你提到了Progtégé。如果这在 Protégé 中对您有用,那么您可能想要接受答案。 dotNetRDF 特定问题最好作为另一个问题提出,您可以在其中提供更多信息(更多人会看到它,包括 dotNetRDF 开发人员,而很多人不会看到这些 cmets)。
猜你喜欢
  • 1970-01-01
  • 2015-05-09
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 2014-05-30
  • 2012-03-27
相关资源
最近更新 更多