Recursion 可以在SPARQL中表达递归定义吗?
假设您有一个简单的社交网络,其中人们必须只有一个属性Recursion 可以在SPARQL中表达递归定义吗?,recursion,constraints,rdf,sparql,Recursion,Constraints,Rdf,Sparql,假设您有一个简单的社交网络,其中人们必须只有一个属性rdfs:label,其值为“Person”,并且可以有任意数量的foaf:knows,其值也必须是具有相同结构的人。一些示例数据可以是: :peter foaf:knows :john; foaf:knows :anna; rdfs:label "Person" . :john foaf:knows :anna; rdfs:label "Person" . :anna rdfs:label
rdfs:label
,其值为“Person”
,并且可以有任意数量的foaf:knows
,其值也必须是具有相同结构的人。一些示例数据可以是:
:peter foaf:knows :john;
foaf:knows :anna;
rdfs:label "Person" .
:john foaf:knows :anna;
rdfs:label "Person" .
:anna rdfs:label "Person" .
从逻辑上讲,定义可以是:
∀x(人(x)≡ rdfs:标签(x,“人”)∧∀y(rdfs:label(x,y)→y=“个人”)∧∀y(foaf:knows(x,y)→个人(y)))
可以在SPARQL中表达这些递归定义吗
我能够在没有递归引用的情况下将查询的一部分表示为:
前缀ex:
前缀foaf:
前缀rdfs:
选择人{
#确保只有一个rdfs:label
{选择人{
?人员rdfs:标签?o。
}分组依据?具有(计数(*)=1)的人员
#确保rdfs:label值为“Person”
{选择人{
?人员rdfs:标签?o。
过滤器((?o=“Person”))
}分组依据?具有(计数(*)=1)的人员
#计算foaf的数量:知道
{选择人员(计数(*)作为p_c0){
?foaf人员:知道[]。
}按人分组
}
#计算foaf的数量:使用具有个人结构的值进行了解
{选择人员(计数(*)作为p_c1){
人物foaf:知道?人物1.#我如何表达人物1具有人物结构?
}按人分组
}
过滤器(?p_c0=?p_c1)
}
有可能在SPARQL中表达这样的递归定义吗
注:根据Joshua的建议,我对问题进行了编辑,将“约束”一词改为“定义”
这是一个定义,而不是一对约束
我们经常根据必要条件和充分条件来考虑定义。充分条件是那些给我们“足够”的信息来推断某事物是给定集合的一个元素,必要条件是那些告诉我们更多关于个体的信息。例如,在OWL中,我们可能有以下公理:
Man&SQQ子部分;人人员和SQQ子部分;∃哈斯名称 第一个是人的充分条件:知道某事物是人就足以决定它也是人。第二个是人的必要条件:如果某物是人,那么它必须有一个名字。(同时,我们还可以注意到,第一条公理是人的必要条件:如果某物是人,那么它一定是人。第二条公理是人的充分条件∃hasName;如果某事物是人,那么它必须有一个名称。) 约束检查的任务通常是找到满足类的充分条件但不满足所有必要条件的个体。这不是你想要做的。相反,你要寻找的是满足做人的必要和充分条件的个人:
@prefix : <http://stackoverflow.com/q/25256452/1281433/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
:peter foaf:knows :john;
foaf:knows :anna;
rdfs:label "Person" .
:john foaf:knows :anna;
rdfs:label "Person" .
:anna rdfs:label "Person" .
:mary rdfs:label "Person" .
:tom rdfs:label "Cat" .
:pluto rdfs:label "Dog" ; foaf:knows :tom .
:ben rdfs:label "Wolf"; rdfs:label "Person" .
:mary rdfs:label "Person"; foaf:knows :ben .
:sam rdfs:label "Person"; foaf:knows :mary .
约束检查
现在,假设上面的条件1和2实际上是做人的必要条件。然后,根据充分条件,我们可以编写不同的查询来查找冲突。您可能希望在图中有非person节点,因此您可能有一个充分条件,即节点具有rdf:type:person。然后可以使用如下查询:
前缀rdfs:
前缀:
#--有两种类型的东西:Person
#--可能是无效的。(i) 它可能缺少标签,或者
#--有“人”以外的标签;(ii)资讯科技
#--可以有一个值foaf:knows*这不是
#--拥有rdf:type:Person。
选择?人在哪里{
#--检查图表中的每个人。
?人a:人。
{#--检查一下?这个人有标签,而且
#--除了“人”之外,它没有其他标签
可选{个人rdfs:label?label}
过滤器(!bound(?label)| |?label!=“Person”)
}联合
{#--检查foaf:的每个值是否都知道
#--还有类型:Person.If某个值
#--具有类型:Person,但违反了约束,
#--我们分开来接。
foaf人员:知道?x。
筛选器不存在{?x a:Person}
}
}
前面的答案的一个问题是,它需要一个额外的谓词来获取Person类型的值
然而,问题是我们想通过结构来识别一个人,在这种情况下,这意味着:
rdfs:label
属性,其值为“Person”
foaf:knows
属性,其值遵循这些约束:peter foaf:knows :john;
foaf:knows :anna;
rdfs:label "Person" .
:john foaf:knows :anna;
rdfs:label "Person" .
:anna rdfs:label "Person" .
前缀rdfs:
前缀foaf:
前缀:
选择?人在哪里{
#--检查图中的每个非文字节点。
人:*?人。
过滤器(!isLiteral(?person))
{#--检查一下?这个人有标签,而且
#--除了“Pers”之外,它没有其他标签