2

考虑以下 RDF:

semapi:BaseClass     a rdfs:Class; 
                     rdfs:subClassOf rdfs:Class .

semapi:hasChainTo a rdf:Property; 
                   rdfs:domain semapi:BaseClass;
                   rdfs:range  semapi:BaseClass .                   

semapi:DerivedClass  a rdfs:Class; rdfs:subClassOf semapi:BaseClass .                  

instances:Instance1 a semapi:DerivedClass;
                    semapi:hasChainTo (
                        [
                            a semapi:DerivedClass;
                                    semapi:hasChainTo (
                                           [C1]
                                           [C2]
                                    )
                            ]
                     )

如果semapi:hasChainTo rdfs:range semapi:BaseClass那么它意味着列表rdf:type semapi:BaseClass.

我真正想说的是列表中的每个项目rdf:type都是(ei. [C1] rdf:type semapi:BaseClass, [C2] rdf:type semapi:BaseClass, ...)

我怎样才能做到这一点?我需要猫头鹰(最好不需要)吗?

4

1 回答 1

5

根据您想要执行此操作的方式,您有几个选择。我认为您正在尝试坚持非 OWL 推理,因此我们将确保包含这样的解决方案,但我也想谈谈 OWL 解决方案,因为对于一些类似的情况,它工作得很好。

使用 OWL 和自定义 ObjectList

如果您确实可以选择使用 OWL 推理器,那么这是一个很好的案例,您可以在其中创建自己的列表词汇并使用一些属性链。这个想法是你引入一个List具有个人nil和 属性的类firstrest。您实际上只是在自己的命名空间中复制词汇。然后假设您定义了两个属性

  • likes: 将一个人 X 与另一个人 Y 联系起来;“X喜欢Y”。
  • likesList: 将个人 X 与 X 喜欢的个人的列表(但不是 RDF 列表)相关联。

然后可以引入两个属性链公理

  • likesList subPropertyChain likesList o rest: 如果 X likesList (_ ...),那么 X likesList (...)。

这样,X likes (A B C)我们得到X likes (A B C)X likes (B C)X likes (C)X likes nil

  • likes subPropertyChain likesList o first: 如果 X 喜欢List (A ...),那么 X 喜欢 A。

然后,从上述所有推断的陈述中,我们得到X likes AX likes BX likes C

在 Turtle 中,这看起来像:

@prefix :        <http://www.example.org/distributing#> .
@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://www.example.org/distributing>
      a       owl:Ontology .

:List
      a       owl:Class .

:nil  a       :List , owl:NamedIndividual .

:first
      a       owl:ObjectProperty .

:rest
      a       owl:ObjectProperty .

:likes
      a       owl:ObjectProperty ;
      owl:propertyChainAxiom
              (:likesList :first) .

[]    a       owl:Axiom ;
      rdfs:comment "If X likesList (A ...), then X likes A." ;
      owl:annotatedProperty
              owl:propertyChainAxiom ;
      owl:annotatedSource :likes ;
      owl:annotatedTarget (:likesList :first) .

:likesList
      a       owl:ObjectProperty ;
      rdfs:comment "Relates an individual I1 to a ObjectList of individuals that I1 likes." ;
      owl:propertyChainAxiom
              (:likesList :rest) .

[]    a       owl:Axiom ;
      rdfs:comment "If X likesList (A B C), then since (B C) is the rest of (A B C), X likesList (B C), too." ;
      owl:annotatedProperty
              owl:propertyChainAxiom ;
      owl:annotatedSource :likesList ;
      owl:annotatedTarget (:likesList :rest) .

如果您必须手动编写 RDF,这会有点不方便,因为您必须这样做

X :likesList [ :first A ;
               :rest [ :first B ;
                       :rest [ :first C ;
                               :rest nil ] ] ] .

并且不能使用(...)Turtle 包含的漂亮语法。这对于您遇到的情况也没有帮助,因为 OWL 类不是个体,所以它们不能是对象属性的对象,rdf:type也不是对象属性。我只是想包含它,因为它是对象属性分布在(非 RDF)个人列表上的一种好方法,并且因为该方法使以下解决方案更清晰。

使用 SPARQL 查询

给定以下数据:

@prefix : <urn:ex:> .

:X :pList (:A :B :C :D) .

一个 SPARQL 查询,如

prefix : <http://example.org/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

construct { 
  ?x :p ?y 
} 
where { 
  ?x :pList/rdf:rest*/rdf:first ?y
}

生产

@prefix :        <http://example.org/> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

:X    :p            :A ;
      :p            :C ;
      :p            :B ;
      :p            :D .

在模仿上面基于 OWL 的方法时,我使用了两个属性pListp,但它们可能是相同的,在这种情况下p将“分布”在列表中。

在某处使用数据存储,您应该能够使用以下命令进行 SPARQL 更新insert/where

prefix : <http://example.org/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

insert { 
  ?x :p ?y 
} 
where { 
  ?x :pList/rdf:rest*/rdf:first ?y
}

将数据添加到存储中。

使用类似 Prolog 的语法

如果您想真正使用推理器执行此推理,那么您将处于推理器特定内容的领域。但是,许多推理器支持类似 Prolog 的查询语言,您也可以在那里编写这些规则。我不知道 AllegoGraph 的 RDFS++ 语法,但一般结构将包括一些定义,例如:

?x p ?y :- ?x pList ?list, ?list rdf:first ?y

?x pList ?l :- ?x pList ?list, ?list rdf:rest ?l
于 2013-08-07T22:32:57.247 回答