考虑以下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
,...)
我该怎么做?我需要猫头鹰(最好不要)吗?
答案 0 :(得分:5)
根据您的想法,您可以选择一些选项。我认为你正在努力坚持非OWL推理,所以我们确保包含这样的解决方案,但我确实想要触及OWL解决方案,因为在某些类似的情况下,它的效果非常好。 / p>
如果你做可以选择使用OWL推理器,那么这是一个很好的例子,你可以创建自己的列表词汇表并使用一些属性链。我们的想法是,您引入一个类List
,其中包含个人nil
,以及属性first
和rest
。您只是在自己的命名空间中复制词汇表。然后我们假设你定义了两个属性
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喜欢列表(A ...),则X喜欢A。然后,从上述所有推断语句中,我们得到X likes A
,X likes B
和X 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)个人列表上,并且因为该方法使以下解决方案更加清晰。
给出如下数据:
@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的方法时,我使用了两个属性pList
和p
,但它们可能是相同的,在这种情况下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
}
将数据添加到商店。
如果你想让这个推理用推理器来执行,你就会进入推理者特定的领域。但是,许多reasoners支持类似Prolog的查询语言,你也可以在那里编写这些规则。我不知道AllegoGraph的RDFS ++语法,但一般结构会包含一些定义,如:
?x p ?y :- ?x pList ?list, ?list rdf:first ?y
?x pList ?l :- ?x pList ?list, ?list rdf:rest ?l