Definition: strongly bound variable
Let P,P1, P2 be graph patterns, SM be a set of solution modifiers, and E,E1,...En be expressions or project expressions.
A variable ?X is strongly bound within a graph pattern P if
- P is a triple pattern and ?X is a variable in P.
- P is a list group graph patterns P1 ... Pn and ?X is strongly bound within some Pi.
- P = P1 UNION P2 and ?X is strongly bound within P1 and within P2
- P = P1 OPTIONAL { P2 } and ?X is strongly bound within P1
- P = P1 FILTER ( E1 ) and ?X is strongly bound within P1
- P = P1 MINUS P2 and ?X is strongly bound in P1
- P = SELECT E1 ... En WHERE { P1 } and ?X is strongly bound in P1 and ?X = E_{i}
- P = P1 GROUP BY E1 ... En such that either there is an Ei of the form ?X or ?X is strongly bound in P1
- P = P1 HAVING ( E1 ) and ?X is strongly bound within P1
- P = P1 SM and ?X is strongly bound in P1.
- P = SERVICE t { P1 } then ?X is not strongly bound in P1 (what I want say here is that it is not possible to guarantee that a variable will be bounded after a SERVICE execution).
- P = P1 BINDINGS ?X_{1} ... ?X_{n} { BindingValues } and ?X is either strongly bound within P1 or ?X = ?X_{i} and UNBOUND is not a possible value for a ?X_{i} in BindingValues.
- P = GRAPH t { P1 } and ?X is strongly bound in P1
Definition: service-safeness
Let P be a graph pattern. P is service-safe if for every subpattern P1 of P such that P1 = SERVICE ?X P2 it hold that
- there exists a subpattern P3 of P different than P1 such that ?X is strongly bound in P3.
- P2 is service-safe.
Remarks: service-safeness shall guarantee that you can execute all the SERVICE patterns with variables in the end of a group in *arbitrary* order. Note that this does not capture passing bindings between SERVICE pattern, e.g. in
{ ?X :p :o SERVICE ?X { ?Y :p :o } SERVICE ?Y { ?Z :p :o } }
is not service-safe, since ?Y is not strongly safe here. If we want to allow this, we need to extend the definitions. However, if we want to capture this case, either we have to make the SERIVCE semantics order-dependent, or the engine needs to determine an implicit order of SERVICE calls that guarantees passing binding in the right-order, cf. the following variant of this query:
{ ?X :p :o SERVICE ?Y { ?Z :p :o } SERVICE ?X { ?Y :p :o } }
The above query can be "emulated" with a nested SERVICE call as follows:
{ ?X :p :o SERVICE ?X { ?Y :p :o SERVICE ?Y { ?Z :p :o } } }
However, this only works if the called services support (nested) SERVICE patterns.