用于在SPARQL中操作RDF集合的函数

用于在SPARQL中操作RDF集合的函数,rdf,sparql,Rdf,Sparql,我想知道SPARQL中是否有一些操作RDF集合的函数 激励问题如下 假设你有: @prefix : <http://example.org#> . :x1 :value 3 . :x2 :value 5 . :x3 :value 6 . :x4 :value 8 . :list :values (:x1 :x2 :x3 :x4) . @前缀:。 :x1:值3。 :x2:值5。 :x3:值6。 :x4:值8。 :列表:值(:x1:x2:x3:x4)。 你要计算以下公式:((Xn-

我想知道SPARQL中是否有一些操作RDF集合的函数

激励问题如下

假设你有:

@prefix : <http://example.org#> .
:x1 :value 3 .
:x2 :value 5 .
:x3 :value 6 .
:x4 :value 8 .

:list :values (:x1 :x2 :x3 :x4) .
@前缀:。
:x1:值3。
:x2:值5。
:x3:值6。
:x4:值8。
:列表:值(:x1:x2:x3:x4)。
你要计算以下公式:((Xn-Xn-1)+…(X2-X1))/(N-1)

有什么通用的计算方法吗

到目前为止,我只能计算一组固定的值。例如,对于4个值,我可以使用以下查询:

prefix : <http://example.org#> 
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?r { 
 ?list :values ?ls .
 ?ls rdf:first ?x1 .
 ?ls rdf:rest/rdf:first ?x2 .
 ?ls rdf:rest/rdf:rest/rdf:first ?x3 .
 ?ls rdf:rest/rdf:rest/rdf:rest/rdf:first ?x4 .
 ?x1 :value ?v1 .
 ?x2 :value ?v2 .
 ?x3 :value ?v3 .
 ?x4 :value ?v4 .
 BIND ( ((?v4 - ?v3) + (?v3 - ?v2) + (?v2 - ?v1)) / 3 as ?r)
}
前缀:
前缀rdf:
选择?r{
?列表:值?ls。
?ls rdf:第一个?x1。
?ls rdf:剩余/rdf:第一个?x2。
ls-rdf:rest/rdf:rest/rdf:first?x3。
ls-rdf:rest/rdf:rest/rdf:rest/rdf:first?x4。
x1:值v1。
?x2:值?v2。
?x3:值?v3。
?x4:值?v4。
绑定((?v4-?v3)+(?v3-?v2)+(?v2-?v1))/3作为?r)
}
我想要的是访问第n个值并定义某种递归函数来计算该表达式的方法。我认为这是不可能的,但也许有人有一个很好的解决方案。

没有内置的公式使公式更简单… SPARQL确实包含一些用于算术和聚合计算的数学函数。但是,我不知道有什么特别方便的方法可以在SPARQL中简洁地表示数学表达式。我最近一直在看一篇文章,其中讨论了表示数学对象(如表达式和定义)的本体。他们实现了一个系统来评估这些,但我认为它没有使用SPARQL(或者至少,它不仅仅是SPARQL的简单扩展)

温泽尔、肯和海纳·莱因哈特。“第24届OpenMath研讨会和第7届数学用户界面研讨会(MathUI)联合会议记录”。2012年

…但我们仍然可以做这个案子。 也就是说,这种特殊情况并不难做到,因为在SPARQL中使用RDF列表并不难,SPARQL包含了该表达式所需的数学函数。首先,介绍一下RDF列表表示,这将使解决方案更容易理解。(如果您已经熟悉这一点,可以跳过下一段或两段。)

RDF列表是链接列表,每个列表通过
RDF:first
属性与其第一个元素相关,通过
RDF:rest
与列表的其余部分相关。因此,方便的符号
(:x1:x2:x3:x4)
实际上是以下内容的简写:

_:l1 rdf:first :x1 ; rdf:rest _:l2 .
_:l2 rdf:first :x2 ; rdf:rest _:l3 .
_:l3 rdf:first :x3 ; rdf:rest _:l4 .
_:l3 rdf:first :x4 ; rdf:rest rdf:nil .
[]
表示空白节点,我们可以使这一点更加清楚:

[ rdf:first :x1 ;
  rdf:rest [ rdf:first :x2 ;
             rdf:rest [ rdf:first :x3 ;
                        rdf:rest [ rdf:first :x4 ;
                                   rdf:rest rdf:nil ]]]]
一旦确定了列表的头部,即具有
rdf:first:x1
的元素,然后通过
rdf:rest/rdf:rest
的偶数重复(包括0)可从中访问的任何列表l是其
rdf:first
是列表的奇数元素的列表(因为您从1开始索引)。从l开始,向前一个
rdf:rest
,我们在一个l'处,它的
rdf:first
是列表中的偶数元素

由于SPARQL 1.1属性路径允许我们编写
(rdf:rest/rdf:rest)*
来表示
rdf:rest
的任何偶数重复,因此我们可以编写以下查询,将
?n
的奇数元素的
:value
和以下偶数元素的值绑定到
?nPlusOne
SELECT
表单中的数学很简单,尽管为了得到N-1,我们实际上使用了
2*COUNT(*)-1
,因为行数(每个行绑定元素N和N+1)是N/2

这就是自那以后的预期

 (5 - 3) + (8 - 6)     2 + 2     4      _ 
------------------- = ------- = --- = 1.3
      (4 - 1)            3       3
更新 我刚刚意识到上面实现的是基于我对求和是否正确的问题的评论,因为它非常容易简化。即,上述实现

(x2-x1)+(x4-x3)+……+(xN-xN-1)/(N-1)

而原来的问题是

(x2-x1)+(x3-x2)+…+(xN-1-xN-2)+(xN-xN-1)/(N-1)

原始列表更简单,因为这些对是由原始列表的每个
rdf:rest
标识的,而不仅仅是偶数的重复。使用与上述相同的方法,此查询可以表示为:

prefix : <http://example.org#> 
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ( SUM(?nPlusOne-?n)/COUNT(*) as ?result) {
 ?list :values [ rdf:rest* [ rdf:first [ :value ?n ] ; 
                             rdf:rest  [ rdf:first [ :value ?nPlusOne ]]]] .
}
当然,因为表达式可以简化为

xN-x1/(N-1)

我们还可以使用一个查询,将
?x1
绑定到列表的第一个元素,
?xn
绑定到最后一个元素,
?xi
绑定到列表的每个元素(这样
COUNT(?xi)
(还有
COUNT(*)
)就是列表中的项数):


您还可以查看用RDF描述/表示列表的其他方法,例如,借助。我认为使用此模型,您可以更轻松地查询所需内容;)

在您给出的特定示例中,加法和减法相互抵消,因此分子就是
?v4-?v1
。这就是你想要的吗?不,这只是一个简化的示例公式…真正的公式更复杂。它计算?v_N/?v_N(N-1)的平均值。不管怎样,谢谢你的评论:)好吧,那么,我认为使用我发布的答案,实际公式应该仍然有效。你试过根据你的实际情况调整答案吗?是的,我试过了,但不起作用。请注意,我必须使用这些对(xN,xN-1),(xN-1,xN-2),…是的,这是我答案的更新部分中讨论的内容,特别是该部分中的第一个SPARQL查询。这是一个多么好的答案!我开始遵循SWI Prolog的RDF路径,您的见解似乎很有价值。如果您对使用RDF的类似Prolog的方法感兴趣,包括正向和反向链接推理器。反向链接推理器是一个“表格数据日志引擎”。正向链接推理器还可以向引擎添加新的反向链接规则。你可能会觉得很有趣。谢谢你,约书亚。SWI Prolog具有
 (5 - 3) + (8 - 6)     2 + 2     4      _ 
------------------- = ------- = --- = 1.3
      (4 - 1)            3       3
prefix : <http://example.org#> 
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ( SUM(?nPlusOne-?n)/COUNT(*) as ?result) {
 ?list :values [ rdf:rest* [ rdf:first [ :value ?n ] ; 
                             rdf:rest  [ rdf:first [ :value ?nPlusOne ]]]] .
}
$ arq --query query.sparql --data data.n3 
------------------------------
| result                     |
==============================
| 1.666666666666666666666666 |
------------------------------
prefix : <http://example.org#> 
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT (((?xn-?x1)/(COUNT(?xi)-1)) as ?result) WHERE {
 ?list :values [ rdf:rest*/rdf:first [ :value ?xi ] ;
                 rdf:first [ :value ?x1 ] ;
                 rdf:rest* [ rdf:first [ :value ?xn ] ; 
                             rdf:rest  rdf:nil ]] .
}
GROUP BY ?x1 ?xn
$ arq --query query.sparql --data data.n3 
------------------------------
| result                     |
==============================
| 1.666666666666666666666666 |
------------------------------