3

OWL 本体可能具有 A、B 和 C 类以及公理(在 DL 表示法中):

A ⊑ (B ⊓ C)

或近似曼彻斯特 OWL 语法:

一个类(BC)

从逻辑上讲,A 是 B 的子类,A 是 C 的子类,但是三元组

A rdfs:subClassOf B
A rdfs:subClassOf C

不一定存在于 OWL 本体的 RDF 序列化中。例如,考虑 Protégé 中的这个非常简单的本体及其在 RDF/XML 和 Turtle 中的 RDF 序列化:

在此处输入图像描述

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="http://stackoverflow.com/q/19924861/1281433/sample.owl#"
    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#">
  <owl:Ontology rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl"/>
  <owl:Class rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl#C"/>
  <owl:Class rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl#B"/>
  <owl:Class rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl#A">
    <rdfs:subClassOf>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Class rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl#B"/>
          <owl:Class rdf:about="http://stackoverflow.com/q/19924861/1281433/sample.owl#C"/>
        </owl:intersectionOf>
      </owl:Class>
    </rdfs:subClassOf>
  </owl:Class>
</rdf:RDF>
@prefix :      <http://stackoverflow.com/q/19924861/1281433/sample.owl#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://stackoverflow.com/q/19924861/1281433/sample.owl>
        a       owl:Ontology .

:B      a       owl:Class .

:C      a       owl:Class .

:A      a                owl:Class ;
        rdfs:subClassOf  [ a                   owl:Class ;
                           owl:intersectionOf  ( :B :C )
                         ] .

序列化有一个三元组 with rdfs:subClassOf,但对象不是:Bor :C,所以像这样的查询

:A rdfs:subClassOf ?superclass

不会返回:A. 我怎样才能编写一个 SPARQL 查询来返回这些超类:A

4

1 回答 1

6

听起来你有一个类是某个交叉类的子类。例如,你可能有

学生注册了一些课程

在 Protégé OWL 本体编辑器中,这看起来像:

学生的定义

如果您为子类编写 SPARQL 查询,例如,

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?subclass ?superclass where { 
  ?subclass rdfs:subClassOf ?superclass
}

并且您没有推理器来推断其他数据,您不会在结果中将Student视为子类,但您可能会看到一个空白(匿名)节点:

---------------------------------------------------------
| subclass                                 | superclass |
=========================================================
| <http://www.examples.org/school#Student> | _:b0       |
---------------------------------------------------------

要理解为什么会这样,您需要看一下本体的 RDF 序列化。在这种情况下,它是(在 RDF/XML 中):

<rdf:RDF
    xmlns="http://www.examples.org/school#"
    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#">
  <owl:Ontology rdf:about="http://www.examples.org/school"/>
  <owl:Class rdf:about="http://www.examples.org/school#Course"/>
  <owl:Class rdf:about="http://www.examples.org/school#Person"/>
  <owl:Class rdf:about="http://www.examples.org/school#Student">
    <rdfs:subClassOf>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Class rdf:about="http://www.examples.org/school#Person"/>
          <owl:Restriction>
            <owl:onProperty>
              <owl:ObjectProperty rdf:about="http://www.examples.org/school#enrolledIn"/>
            </owl:onProperty>
            <owl:someValuesFrom rdf:resource="http://www.examples.org/school#Course"/>
          </owl:Restriction>
        </owl:intersectionOf>
      </owl:Class>
    </rdfs:subClassOf>
  </owl:Class>
</rdf:RDF>

或者在更易读的 Turtle 中(也更像 SPARQL 查询语法):

@prefix :      <http://www.examples.org/school#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

:Student  a              owl:Class ;
        rdfs:subClassOf  [ a                   owl:Class ;
                           owl:intersectionOf  ( :Person [ a                   owl:Restriction ;
                                                           owl:onProperty      :enrolledIn ;
                                                           owl:someValuesFrom  :Course
                                                         ] )
                         ] .

:Person  a      owl:Class .

:enrolledIn  a  owl:ObjectProperty .

:Course  a      owl:Class .

<http://www.examples.org/school>
        a       owl:Ontology .

实际上,Student rdfs:subClassOf [ ... ]数据中有一个三元组,但[ ... ]是一个空白节点;它是一个匿名的owl:Class,是其他一些类的交集。推理者可以告诉您,如果X ⊑ ( YZ ) 然后XYXZ,但 SPARQL 查询本身不会这样做。但是,您可以像这样进行更复杂的 SPARQL 查询:

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 ?subclass ?superclass where {
  { ?subclass rdfs:subClassOf ?superclass }
  union
  { ?subclass rdfs:subClassOf [ owl:intersectionOf [ rdf:rest* [ rdf:first ?superclass ] ] ] }
}
--------------------------------------------------------------------------------------
| subclass                                 | superclass                              |
======================================================================================
| <http://www.examples.org/school#Student> | _:b0                                    |
| <http://www.examples.org/school#Student> | <http://www.examples.org/school#Person> |
| <http://www.examples.org/school#Student> | _:b1                                    |
--------------------------------------------------------------------------------------

两个空白节点分别是匿名交集类和匿名限制类(enrolledIn some Course)。如果您只想要 IRI 结果,您可以使用filter

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 ?subclass ?superclass where {
  { ?subclass rdfs:subClassOf ?superclass }
  union
  { ?subclass rdfs:subClassOf [ owl:intersectionOf [ rdf:rest* [ rdf:first ?superclass ] ] ] }

  filter( isIRI( ?superclass ) )
}
--------------------------------------------------------------------------------------
| subclass                                 | superclass                              |
======================================================================================
| <http://www.examples.org/school#Student> | <http://www.examples.org/school#Person> |
--------------------------------------------------------------------------------------

现在,作为最后一点,如果你想让你的查询更小一点,因为这两个unioned 模式的唯一区别是连接?subclass和的路径?superclass,你实际上可以只用一个属性路径来编写它。(虽然,如Sparql 查询 Subclass 或 EquivalentTo中所述,如果这样做,您可能会遇到 Protégé 的一些问题。)这个想法是您可以重写它:

{ ?subclass rdfs:subClassOf ?superclass }
union
{ ?subclass rdfs:subClassOf [ owl:intersectionOf [ rdf:rest* [ rdf:first ?superclass ] ] ] }

因此,通过使用属性路径,这也消除了对空白节点的需要:

?subclass ( rdfs:subClassOf |
            ( rdfs:subClassOf / owl:intersectionOf / rdf:rest* / rdf:first ) ) ?superclass

你可以再简化一点

?subclass rdfs:subClassOf/((owl:intersectionOf/rdf:rest*/rdf:first)+) ?superclass

你甚至可以从中删除一层括号,使其成为

?subclass rdfs:subClassOf/(owl:intersectionOf/rdf:rest*/rdf:first)+ ?superclass

但是你必须开始记住优先规则,这不是很有趣。该查询虽然有效:

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 ?subclass ?superclass where {
  ?subclass rdfs:subClassOf/(owl:intersectionOf/rdf:rest*/rdf:first)+ ?superclass
  filter( isIRI( ?superclass ) )
}
--------------------------------------------------------------------------------------
| subclass                                 | superclass                              |
======================================================================================
| <http://www.examples.org/school#Student> | <http://www.examples.org/school#Person> |
--------------------------------------------------------------------------------------
于 2013-11-12T14:56:22.443 回答