本体的一个小例子
@prefix : <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Product a owl:Class .
:Accessories rdfs:subClassOf :Product .
:hasAccessories a rdf:Property .
:hasAccessories rdfs:domain :Product.
:hasAccessories rdfs:range :Accessories.
:Mouse rdfs:subClassOf :Accessories.
:Keyboard rdfs:subClassOf :Accessories.
:Computer rdfs:subClassOf :Product .
:Desktop rdfs:subClassOf :Computer .
:Laptop rdfs:subClassOf :Computer .
:m1 a :Mouse .
:m2 a :Mouse .
:k1 a :Keyboard .
:k2 a :Keyboard .
:c1 a :Computer .
:c2 a :Computer .
:d1 a :Desktop .
:d2 a :Desktop .
:l1 a :Laptop .
:s a :Storage
:c1 :hasAccessories :m1 , :k1 .
:d1 :hasAccessories :m1 .
:d2 :hasAccessories :m2 .
:s :hasAccessories :k2 # <---- Note this is intentional bad design
我想检索
k2
作为唯一非计算机绑定的配件。
我没有推理,所以这个查询不起作用:
SELECT DISTINCT ?a WHERE
{
?c a :Computer.
?a a :Accessories .
FILTER NOT EXISTS {?c :hasAccessories ?a .}
}
输出:空
如果不是
Storage s
我可以执行此查询来获取所有非链接的配件
SELECT DISTINCT ?c ?a WHERE
{
?acc rdfs:subClassOf* :Accessories .
?a a ?acc .
FILTER NOT EXISTS {?c :hasAccessories ?a .}
}
输出:空
通过此查询查看继承不会过滤掉我的任何结果:
SELECT DISTINCT ?a WHERE
{
?computer rdfs:subClassOf* :Computer .
?c a ?computer.
?acc rdfs:subClassOf* :Accessories .
?a a ?acc .
FILTER NOT EXISTS {?c :hasAccessories ?a .}
}
输出:
k1, k2, m1, m2
我有一种模糊的感觉为什么会发生这种情况,例如它会找到反例
l1 not hasAccessory k1
,将 k1
放入结果中。
我需要如何调整查询以仅产生 k2
而不使用存储,即检查 only 的计算机子类?
事实上,您正在选择所有属于计算机的东西以及所有属于附件的东西,因为它们没有链接。
您想要的是选择所有附件以及它们链接的东西,因为这些不是计算机。所以翻转条件:
SELECT DISTINCT ?non-computer ?acc WHERE {
?accessory rdfs:subClassOf* :Accessories .
?acc a ?accessory .
?non-computer :hasAccessories ?acc .
FILTER NOT EXISTS {
?computer rdfs:subClassOf* :Computer .
?non-computer a ?computer
}
}