RDF - 将rdf:type分配给列表中的所有项目

par*_*ent 2 rdf semantic-web rdfs turtle-rdf

考虑以下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]
                                    )
                            ]
                     )
Run Code Online (Sandbox Code Playgroud)

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

我真正的意思是说每个项目在列表rdf:type(EI, [C1] rdf:type semapi:BaseClass,[C2] rdf:type semapi:BaseClass,...)

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

Jos*_*lor 5

根据您的想法,您有几个选择.我认为你正在努力坚持非OWL推理,所以我们确保包含这样的解决方案,但我也想触及OWL解决方案,因为对于某些类似的情况,它的效果非常好.

使用OWL和自定义ObjectList

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

  • likes:将个人X与另一个人Y联系起来; "X喜欢Y".
  • likesList:将个人X与X喜欢的个人列表(不是RDF列表)联系起来.

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

  • likesList subPropertyChain likesList o rest:如果X喜欢List(_ ...),那么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 A,X 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) .
Run Code Online (Sandbox Code Playgroud)

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

X :likesList [ :first A ;
               :rest [ :first B ;
                       :rest [ :first C ;
                               :rest nil ] ] ] .
Run Code Online (Sandbox Code Playgroud)

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

使用SPARQL查询

鉴于以下数据:

@prefix : <urn:ex:> .

:X :pList (:A :B :C :D) .
Run Code Online (Sandbox Code Playgroud)

像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
}
Run Code Online (Sandbox Code Playgroud)

产生

@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 .
Run Code Online (Sandbox Code Playgroud)

在模仿上面的OWL为基础的方法,我用了两个性质pListp,但他们却是相同的,在这种情况下p会被"分配"在列表中.

使用某个数据存储区,您应该能够使用insert/where以下命令执行SPARQL更新:

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
}
Run Code Online (Sandbox Code Playgroud)

将数据添加到商店.

使用类似Prolog的语法

如果你想真正用推理器进行这种推理,那么你将成为推理者特定的东西.但是,许多reasoners支持类似Prolog的查询语言,你也可以在那里编写这些规则.我不知道AllegoGraph的RDFS ++语法,但一般结构包括一些定义,如:

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

?x pList ?l :- ?x pList ?list, ?list rdf:rest ?l
Run Code Online (Sandbox Code Playgroud)