This is completely unrelated to any recent questions about the rule engine and builtins. :) I've got this data:
@prefix : <http://example.org/> . :a :atIndex 0 . :b :atIndex 1 . :c :atIndex 2 . :d :atIndex 3 . Here's a query that finds an ?element at an ?index, binds ?index2 to ?index - 1, and optionally selects an ?element2 that is at ?index2. prefix : <http://example.org/> select ?element ?index ?element2 ?index2 where { ?element :atIndex ?index . BIND( ?index - 1 as ?index2 ) OPTIONAL { ?element2 :atIndex ?index2 . } } order by ?index The results are as expected: $ arq --data data.n3 --query query.sparql --------------------------------------- | element | index | element2 | index2 | ======================================= | :a | 0 | | -1 | | :b | 1 | :a | 0 | | :c | 2 | :b | 1 | | :d | 3 | :c | 2 | --------------------------------------- Moving the BIND into the OPTIONAL, i.e., prefix : <http://example.org/> select ?element ?index ?element2 ?index2 where { ?element :atIndex ?index . OPTIONAL { BIND( ?index - 1 as ?index2 ) ?element2 :atIndex ?index2 . } } order by ?index produces lots more results; it seems that there's no constraint on the ?index within the OPTIONAL, so ?index2 can range over everything. $ arq --data data.n3 --query query.sparql --------------------------------------- | element | index | element2 | index2 | ======================================= | :a | 0 | :a | 0 | | :a | 0 | :b | 1 | | :a | 0 | :c | 2 | | :a | 0 | :d | 3 | | :b | 1 | :a | 0 | | :b | 1 | :b | 1 | | :b | 1 | :c | 2 | | :b | 1 | :d | 3 | | :c | 2 | :a | 0 | | :c | 2 | :b | 1 | | :c | 2 | :c | 2 | | :c | 2 | :d | 3 | | :d | 3 | :a | 0 | | :d | 3 | :b | 1 | | :d | 3 | :c | 2 | | :d | 3 | :d | 3 | --------------------------------------- Now, using a FILTER in the OPTIONAL: prefix : <http://example.org/> select ?element ?index ?element2 ?index2 where { ?element :atIndex ?index . OPTIONAL { FILTER( ?index - 1 = ?index2 ) ?element2 :atIndex ?index2 . } } order by ?index produces results that actually show that ?index2 is constrained, and are almost the same the as the first query (except that the case where ?index2 is -1 doesn't occur): $ arq --data data.n3 --query query.sparql --------------------------------------- | element | index | element2 | index2 | ======================================= | :a | 0 | | | | :b | 1 | :a | 0 | | :c | 2 | :b | 1 | | :d | 3 | :c | 2 | --------------------------------------- Is this expected? Why can't the BIND inside the optional reference the outer binding of ?index? In the spec, I do read about the difference of scope between, e.g., FILTER NOT EXISTS { ?n ... } and MINUS { ?n ... }, where in the former, ?n can refer to an outer binding, but for the latter, it cannot. I think that 18.2.1 Variable Scope [1] is probably relevant here, but I'm not sure how to get an answer from it. Thanks in advance! //JT [1] http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#variableScope -- Joshua Taylor, http://www.cs.rpi.edu/~tayloj/
