On Wed, Jul 10, 2013 at 5:07 AM, Damian Steer <[email protected]> wrote: > On 9 Jul 2013, at 21:01, Joshua TAYLOR <[email protected]> wrote: > >> 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; > > SPARQL is evaluated inside out, so start with: > >> { >> BIND( ?index - 1 as ?index2 ) >> ?element2 :atIndex ?index2 . >> } > > ?index is unbound, so ?index2 isn't bound by that first bit. Effectively you > just have: > > { ?element2 :atIndex ?index2 } > > OPTIONAL does nothing, since there's no shared variable, so you end up with a > cross join: > > { ?element :atIndex ?index } > { ?element2 :atIndex ?index2 } > > i.e. every combination.
I know that when there are *sub*-queries in a query, they're evaluted from the inside out (i.e., innermost subqueries are evaluated first), but this doesn't make sense for OPTIONAL patterns, does it? The whole point of an optional pattern is to *extend* the solutions of the enclosing pattern if possible. In an example from the spec PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?mbox WHERE { ?x foaf:name ?name . OPTIONAL { ?x foaf:mbox ?mbox } } it would seem rather inefficient if the OPTIONAL pattern were treated first, particularly if, e.g., there were lots more ?x's that have foaf:mboxes than ?x's that have foaf:names. I don't expect OPTIONAL patterns to be evaluated separately from the pattern that they are attached to, but rather, once the pattern to which they are attached produces some solutions, to extend that solution, if possible. Another example from the spec shows the same sort of thing (although the FILTER in the OPTIONAL doesn't involve a variable from outside the OPTIONAL, so it doesn't shed any light on the next query): PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX ns: <http://example.org/ns#> SELECT ?title ?price WHERE { ?x dc:title ?title . OPTIONAL { ?x ns:price ?price . FILTER (?price < 30) } } >> 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): > > Ok, _now_ I'm scratching my head. This one makes sense to me, at least with the understanding I mentioned above. Since the OPTIONAL pattern is being used to *extend* the solution, ?index is a available within for use in the FILTER. //JT -- Joshua Taylor, http://www.cs.rpi.edu/~tayloj/
