Re: Issue-3 - Blank nodes substituted into BGPs act as variables

On 07/14/2016 10:05 AM, Gregory Williams wrote:
> On Jul 14, 2016, at 9:57 AM, Peter F. Patel-Schneider wrote
>>
>> Both expectations and behaviour here are consistent with joining a
single-element multiset of solution bindings to the unmodified BGP.  Given
this, my view is that EXISTS should be defined in this way.
>>
>> That is, the pattern that is evaluated for this EXISTS should be
>>
>> Join( { { (?s, _:s1) } }, BGP(?s :p 1) )
>>
>> instead of
>>
>> BGP(_:s1 :p 1)
>>
>> I believe that this approach is suitable not just here but as the complete
definition of EXISTS.  The details of the approach involve injecting a special
syntactic token into the argument of EXISTS that is then replaced by the
multiset during Filter evaluation.  Variations of this approach are possible,
matching much of the behaviour of different SPARQL implementations of EXISTS.

>
> That seems like a reasonable approach when the EXISTS pattern is just a BGP,
but doesn't it quickly fail when the pattern is more complex?
>
> SELECT * WHERE { ?s :p ?o FILTER EXISTS { ?x :q ?y FILTER(?y = ?o) } }
>
> If you inject a multiset to be joined at the top level of the exists
pattern, it will join with the filter, right? But the filter depends on the
substituted value of ?o being available, so will necessarily fail as ?o will
always be unbound during evaluation.
>
> .greg

You have to put the multiset and Join in the right place.  If you think
syntactically, it is like putting a generalized VALUES construct as the first
element of the GroupGraphPattern that is the argument to EXISTS, i.e., changing
   { ?x :q ?y FILTER(?y = ?o) }
to
   { VALUES* (?s ?o) { ... } ?x :q ?y FILTER(?y = ?o) }
where ... is the correct values for ?s and ?o (and can be blank nodes).  To
make that all easy, an initial replacement has to be done on the syntactic
level, i.e., when FILTERS are gathered (18.2.2.2), and then when the exists is
evaluated (18.6) the current solution mapping has to be pushed to the correct ....

Evaluating the query on the graph
  :b :p :c .
  :d :q :c .
results in the exists evaluating something like
 Filter( (?y=?o), Join( { { (:s,:b), (:o,:c) } } , BGP( ?x :q ?y )
which should all work out.

The simplest version of the approach does diverge from the semantics for
exists in several ways, but current implementations also diverge from the
semantics for exists - not only for blank nodes but also in lots of other places.

peter

Received on Thursday, 14 July 2016 17:38:06 UTC