- From: Peter F. Patel-Schneider <pfpschneider@gmail.com>
- Date: Thu, 14 Jul 2016 10:37:33 -0700
- To: Gregory Williams <greg@evilfunhouse.com>
- Cc: Andy Seaborne <andy@apache.org>, public-sparql-exists@w3.org
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