我使用onspy在Python中递归运行以下查询:
SELECT ?c WHERE {
?c rdfs:subClassOf ?restriction .
?restriction owl:onProperty :has_part ; owl:someValuesFrom ?p .
VALUES ?p { <some_uri> }
}
Run Code Online (Sandbox Code Playgroud)
基本上,我获取从中返回的值并重新运行查询以遵循本体中“具有部分”关系的层次结构。我希望通过向查询本身添加递归来避免进行多个 SPARQL 查询。我知道如何使用单个三元组执行此操作rdfs:subClassOf*,但无法弄清楚组合两个三元组的语法:
?c rdfs:subClassOf ?restriction .
?restriction owl:onProperty :has_part ; owl:someValuesFrom ?p .
Run Code Online (Sandbox Code Playgroud)
这可能吗?
我无法给出正式的证明,但这看起来不可能。这不是属性路径的设计目的,也不是存在某些扩展的原因(1、2 )。
在某些承诺下(例如,使用树状结构),可以使用找出一些东西FILTER NOT EXISTS,但这不是通用解决方案。
这个想法是通过两个查询来完成此操作。本质上,这件事已经SELECT结束了CONSTRUCT。顺便说一句,这样的 SPARQL 扩展已经被提出了。
让我们使用Ontospy 所基于的rdflib ,因为
Ontospy 不提供任何本体编辑功能,也不能用于询问三元组存储。
输入 (ontology.ttl)
@prefix : <http://www.example.org/ontology#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <http://www.example.org/ontology> .
<http://www.example.org/ontology> rdf:type owl:Ontology .
:hasPart rdf:type owl:ObjectProperty .
:Country rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :hasPart ;
owl:someValuesFrom :State
] .
:State rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :hasPart ;
owl:someValuesFrom :City
] .
:City rdf:type owl:Class .
Run Code Online (Sandbox Code Playgroud)
Python代码
@prefix : <http://www.example.org/ontology#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <http://www.example.org/ontology> .
<http://www.example.org/ontology> rdf:type owl:Ontology .
:hasPart rdf:type owl:ObjectProperty .
:Country rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :hasPart ;
owl:someValuesFrom :State
] .
:State rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :hasPart ;
owl:someValuesFrom :City
] .
:City rdf:type owl:Class .
Run Code Online (Sandbox Code Playgroud)
输出
:Country :hasSome+ :State
:State :hasSome+ :City
:Country :hasSome+ :City
Run Code Online (Sandbox Code Playgroud)
如果您不想修改初始 RDFLib 图,只需创建另一个图:
import rdflib
g = rdflib.Graph()
g.parse("ontology.ttl", format="n3")
qres = g.update(
"""PREFIX : <http://www.example.org/ontology#>
INSERT { ?c :hasSome ?p }
WHERE { ?c rdfs:subClassOf [ owl:onProperty :hasPart ;
owl:someValuesFrom ?p ] }""")
qres = g.query(
"""PREFIX : <http://www.example.org/ontology#>
SELECT ?a ?b WHERE {?a :hasSome+ ?b }""")
for row in qres:
print("%s :hasSome+ %s" % row)
qres = g.update(
"""PREFIX : <http://www.example.org/ontology#>
DELETE { ?s :hasSome ?o } WHERE { ?s :hasSome ?o }""")
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您可能可以使用transitiveClosure()ortransitive_objects()代替第二个查询。