Re: Proposal : deep binding injection

It looks to me as if the definition of Exists here is really going to be along
the lines of:

Let μ be the current solution mapping for a filter and P a graph pattern: The
value exists(P) given D(G) is true if and only if eval(D(G), P') is a
non-empty sequence.  Here P' is P with each BGP(...) in P replaced by
Join(BGP(...), μ') (or maybe Join(μ', BGP(...))) where μ' is the same as μ
except that it only maps variables that are STILL-IN-SCOPE at the point of the
BGP(...) in P.

STILL-IN-SCOPE is defined as

v is STILL-IN-SCOPE at P if v is mapped in the current solution mapping for
Exists(P)

if v is STILL-IN-SCOPE at an expression E then v is STILL-IN-SCOPE for each
subexpression of E

if v is STILL-IN-SCOPE at A(...), an application of a symbol in the SPARQL
algebra to some arguments, then v is STILL-IN-SCOPE at each expression and
pattern argument to A and to each expression and pattern element of a list or
set that is an argument to A
UNLESS
A(...) is of the form Project(P,{v1,...,vn}) and v is one of the vi.


Most of this machinery is to set up a particular meaning for

EXISTS { SELECT ?o WHERE { FILTER ( ?o = 4 ) } }

even though the current SPARQL spec breaks here.


If there is freedom to do something else in this case then a simpler solution
is possible.

Let μ be the current solution mapping for a filter and P a graph pattern:  The
value exists(P) given D(G) is true if and only if eval(D(G), P') is a
non-empty sequence.  Here P' is P with each BGP(...) in P that is not within a
Project application in P replaced by Join(BGP(...), μ) (or maybe Join(μ,
BGP(...)))

This would be the analogue of changing my proposal to

2/ When collecting FILTER elements replace EXISTS{P} in the filter
   expression with exists(t,translate( P' )) where t
   is a fresh token and similarly for NOT EXISTS{P}.  If P is a SubSelect
   then P' is { Initial(t) { P } } otherwise P' is P with each
GroupGraphPattern { Q } in P that is not inside a SubSelect replaced with {
Initial(t) Q }

peter


On 09/28/2016 04:44 PM, Andy Seaborne wrote:
> ** Intuition/Outline
> 
> Ensure that the variables from the row being filtered are available, not just
> their values as in the spec with substitution.
> 
> This is done by restricting the variable to the value of the row at the point
> where the variable is being bound.  This is in a BGP.   Use of AS ?x for ?x in
> the current row is not allowed : ?x is considered to be already set.
> 
> ** Proposal
> 
> Rewrite the pattern of the EXISTS filter; do this in a deep fashion, while
> respecting scoping rules.
> 
> Let V = in-scope variables at the point of the FILTER EXISTS.
> 
> For each BGP in the pattern:
>        Build a VALUES with variables of V still in-scope at this BGP.
>        This includes empty BGPs
> 
> Scoping applies.
> 
> ** Relationship to Issues
> 
> * Problem 2: Substitution happens where definitions are only for
> variables
> 
> Variables are retained so e.g. BOUND(?var) remains unchanged.
> 
> The row being tested has already defined ?VAR so by the rule of no
> reassignment, using VALUE ?VAR at the BGP makes these illegal if a BGP used
> ?VAR : this is true at present.  We can leave things as they are. ?VAR gets
> bound and presumably joined at some point (or it's out of scope).
> 
> Separately, a rule to forbid these forms might be clearer to users and in the
> spirit of ?VAR being fixed.  Then we can rewrite BGPs to include all vars.
> 
> * Problem 3: Blank nodes substituted into BGPs act as variables
> 
> No blank nodes are introduced into BGPs by substitution.
> 
> Binding for ?o = _:b
> { ?s ?p ?o } => { ?s ?p ?o . VALUES ?o {_:b} }
> 
> (in the algebra where _:b is not going to be remapped by surface syntax parsing)
> 
> * Problem 4: Substitution can flip MINUS to its disjoint-domain case
> 
> The domain of MINUS retains the same variables.
> 

Received on Thursday, 29 September 2016 03:20:50 UTC