- From: Peter F. Patel-Schneider <pfpschneider@gmail.com>
- Date: Mon, 27 Jun 2016 07:05:43 -0700
- To: public-sparql-dev@w3.org
Here is a run-through of an EXISTS over a subquery with a disconnected variable. I have kept IRIs in abbreviated form throughout and not bothered to provide their expansion. This does not change any of the analysis here. This run-through abides by the definitions in https://www.w3.org/TR/2013/REC-sparql11-query-20130321/ (without any suggested errata). There are no semantic anomalies or invalid arguments anywhere even taking the most stringent possible interpretation of the definitions, except for the implicit argument passed into the pattern in the exists but that is as called out in the definitions. This run-through shows how disconnected variables in subqueries inside EXISTS are defined to work by https://www.w3.org/TR/2013/REC-sparql11-query-20130321/ (without any suggested errata), i.e., they are replaced by the substitution that is part of the evalution of EXISTS. As a consequence, subqueries inside EXISTS cannot be evaluated until the solution mappings for the enclosing FILTER are known. This analysis does not mean that I think that disconnected variables in subqueries inside EXISTS should work this way or that SPARQL implementations work this way, just that this is how they are defined to work according to https://www.w3.org/TR/2013/REC-sparql11-query-20130321/ (without any suggested errata). QUERY: SELECT ?x WHERE { BIND ( :b AS ?x ) FILTER EXISTS { BIND ( :c AS ? y ) { SELECT ?z WHERE { ?z :d ?x . } } } PARSE (abbreviated somewhat): SelectQuery SelectClause Var ?x WhereClause GroupGraphPattern GroupGraphPatternSub GraphPatternNotTriples Bind Expression :b Var ?x GraphPatternNotTriples Filter Constraint BuiltInCall ExistsFunc GroupGraphPattern GroupGraphPatternSub GraphPatternNotTriples Bind Expression :c Var ?y GraphPatternNotTriples GroupOrUnionGraphPattern GroupGraphPattern SubSelect SelectClause Var ?z WhereClause GroupGraphPattern GroupGraphPatternSub TriplesBlock ?z :d ?x SolutionModifier ValuesClause SolutionModifier ALGEBRA (Z is the empty graph pattern): Project( Filter( exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) ) , Extend( Z, x, :b ) ) x ) Evaluation against the RDF graph G = { ( :b :d :e ) } in D = { G } eval ( D(G), Project( Filter( exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) ) , Extend( Z, x, :b ) ) x ) ) Project( eval ( D(G), Filter( exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) ) , Extend( Z, x, :b ) ) ) x ) Project( Filter( exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) ) , eval ( D(G), Extend( Z, x, :b ) ) , D(G) ) x ) Project( Filter( exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) ) , { { ( x, :b ) } } , D(G) ) x ) Project( { (x,:b) | exists( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) )(x,:b) } , * D(G) is an implicit argument here x ) Note that the argument to exists is a graph pattern, as required. Project( { (x,:b) | eval( D(G), substitute( Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d ?x) ) , z ) ) ) (x,:b) ) ) /= { } } , x ) Project( { (x,:b) | eval( D(G), Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d :b) ) , z ) ) ) ) /= { } } , x ) Note that the result of the substitute is a pattern, as required. Project( { (x,:b) | eval( D(G), Join( Extend( Z, y, :c ) , ToMultiset( Project( ToList( BGP(?z :d :b) ) , z ) ) ) ) /= { } } , x ) Project( { (x,:b) | Join( { { (y,:c) } }, { } ) /= { } } , x ) Project( { (x,:b) | { } /= { } } , x ) Project( { }, x ) { } Peter F. Patel-Schneider Nuance Communications
Received on Monday, 27 June 2016 14:06:27 UTC