我正在开发一种本体论来模拟制造系统中的关系。我把它分解成类似的菜肴计划:
ex:potatoes rdf:type owl:Class .
ex:fish rdf:type owl:Class .
ex:beef rdf:type owl:Class .
ex:rice rdf:type owl:Class ;
owl:disjointWith ex:potatoes .
ex:chicken rdf:type owl:Class ;
owl:disjointWith ex:fish .
ex:pork rdf:type owl:Class ;
owl:disjointWith ex:beef .
ex:dish1 rdf:type owl:Class ;
rdfs:subClassOf ex:dishes ;
owl:unionOf ( ex:pork ex:potatoes ) .
ex:dish2 rdf:type owl:Class ;
rdfs:subClassOf ex:dishes ;
owl:unionOf ( ex:rice ex:chicken ) .
ex:dish3 rdf:type owl:Class ;
rdfs:subClassOf ex:dishes ;
owl:unionOf ( ex:fish ex:potatoes ) .
ex:dish4 rdf:type owl:Class ;
rdfs:subClassOf ex:dishes ;
owl:unionOf ( ex:beef ex:rice ) .
所以我有一些分离类,我想查询这样的模型:如果有人说他想要米和鸡,请排除每个包含析取类的菜(这里是鱼和土豆)。经过一些研究后,我有这样的想法:
"PREFIX ex: <http://example.org/>"+
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX owl: <http://www.w3.org/2002/07/owl#>"+
"PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>"+
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"SELECT ?x "+
"WHERE {"+
"?x rdfs:subClassOf ex:dishes. "+
"FILTER (!isBlank(?x))"+
"FILTER NOT EXISTS { "+
"?x rdfs:subClassOf ?y ."+
"?y rdfs:subClassOf ex:dishes ."+
"FILTER (?x!=?y)"+
"}"+
"FILTER NOT EXISTS {"+
"?z rdfs:subClassOf ?x ." +
"?z owl:disjointWith ex:chicken . }" +
"FILTER NOT EXISTS {"+
"?z rdfs:subClassOf ?x ." +
"?z owl:disjointWith ex:rice . }" +
"}";
它有效,我得到了正确的结果:
------------
| x |
============
| ex:dish4 |
| ex:dish2 |
------------
有更有效的方法吗?似乎不必要的复杂。并且必须使用&#34; FILTER NOT EXISTS {添加整个块 ?z rdfs:subClassOf?x。 ?z owl:disjointWith ex:chicken。 } 每次? 有什么建议吗?
答案 0 :(得分:2)
我已经修改了一些数据,使一些表示更直接,并且没有关于OWL语义的混淆。但是,它直接类似于您正在使用的表示,因此您应该能够更改属性并使其工作。首先,这是数据。你有一些成分,某些成分与其他成分不相容。 (不相容意味着不相交,但不相交并不意味着不相容。毕竟,鸡肉和米饭显然是截然不同的东西,因此是不相交的类别,但这并不意味着它们与成分不相容。)
@prefix : <urn:ex:>
# Incompatibities
:rice :incompatibleWith :potatoes .
:potatoes :incompatibleWith :rice .
:chicken :incompatibleWith :fish .
:fish :incompatibleWith :chicken .
:beef :incompatibleWith :pork .
:pork :incompatibleWith :beef .
# Ingredients
:dish1 a :Dish ; :ingredients (:pork :potatoes) .
:dish2 a :Dish ; :ingredients (:rice :chicken) .
:dish3 a :Dish ; :ingredients (:fish :potatoes) .
:dish4 a :Dish ; :ingredients (:beef :rice) .
现在,查询只需要询问菜肴,然后检查菜中的每种成分是否 与鸡肉或米饭不相容。
prefix : <urn:ex:>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select ?dish where {
?dish a :Dish .
filter not exists {
?dish :ingredients/rdf:rest*/rdf:first ?ingredient .
?ingredient :incompatibleWith ?incompatibleIngredient .
filter (?incompatibleIngredient in (:rice, :chicken))
}
}
----------
| dish |
==========
| :dish4 |
| :dish2 |
----------
如果你真的关心空间,你甚至可以将两行结合起来
?dish :ingredients/rdf:rest*/rdf:first ?ingredient .
?ingredient :incompatibleWith ?incompatibleIngredient .
进入
?dish :ingredients/rdf:rest*/rdf:first/:incompatibleWith ?incompatibleIngredient .
我认为这有点难以阅读,因为隐含的是列表中的值(通过以下:ingredients / rdf:rest * / rdf:first 得到的)是菜中的成分。