Skip to content

Commit 84d3cbd

Browse files
committed
WIP: Sketch correlated EXISTS
1 parent ac09851 commit 84d3cbd

File tree

1 file changed

+121
-204
lines changed

1 file changed

+121
-204
lines changed

spec/index.html

Lines changed: 121 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -8937,6 +8937,7 @@ <h5>Expand Syntax Forms</h5>
89378937
<p>Expand abbreviations for IRIs and triple patterns given in
89388938
<a href="#sparqlSyntax">section 4</a>.</p>
89398939
</section>
8940+
89408941
<section id="sparqlCollectFilters">
89418942
<h5>Collect <code>FILTER</code> Elements</h5>
89428943
<p><code>FILTER</code> expressions apply to the whole group graph pattern in which they
@@ -8952,13 +8953,120 @@ <h5>Collect <code>FILTER</code> Elements</h5>
89528953
Let FS := empty set
89538954
For each form FILTER(expr) in the group graph pattern
89548955
In expr, replace NOT EXISTS{P} with fn:not(<a href="#defn_evalExists">exists(translate(P)))</a>
8955-
In expr, replace EXISTS{P} with <a href="#defn_evalExists">exists(translate(P))</a>
8956+
In expr, replace EXISTS{P} with prepare(EXISTS{P})
89568957
FS := FS ∪ {expr}
89578958
End
89588959
</pre>
89598960
<p>The set of filter expressions <code>FS</code> is <a href="#sparqlAddFilters">used
89608961
later</a>.</p>
8962+
8963+
<div>
8964+
<i>Prepare EXISTS and NOT EXISTS</i>
8965+
<p><b>prepare(EXISTS{P})</b></p>
8966+
8967+
<div class="ednote">
8968+
<p>@@ Scoping rule already done (grammar note).<br/>
8969+
Prepare FILTER for exists.
8970+
</p>
8971+
<ul>
8972+
<li>A1 = translate(P) without applying simplification</li>
8973+
<li>A2 = A1 rewritten to include access current binding</li>
8974+
<li>A3 = A2 Remapped hidden-scope variables (if we do that)</li>
8975+
</ul>
8976+
8977+
<div class="defn">
8978+
<div>
8979+
<b>Definition: Access to the current binding</b>
8980+
<p>
8981+
During <a href="#sparqlQuery">translation to the SPARQL algebra</a>
8982+
</p>
8983+
<pre>
8984+
Replace each occurence of `Y` in X where `Y` is one of
8985+
<a href="#sparqlTranslateBasicGraphPatterns">Basic Graph Pattern</a>,
8986+
<a href="#sparqlTranslatePathExpressions">Property Path Expression</a>,
8987+
<a href="#sparqlTranslateGraphPatterns">`Graph(Var, pattern)`</a>,
8988+
<a href="#https://www.w3.org/TR/sparql12-query/#sparqlTranslateGraphPatterns">Inline Data</a>
8989+
with `join(Y, BindingInScope())`.</pre>
8990+
</div>
8991+
<div class="note">
8992+
c.f. section <a href="#sparqlTranslateGraphPatterns">Translate Graph Patterns</a>
8993+
where an empty basic graph pattern start any
8994+
<a href="#rGroupGraphPattern">GroupGraphPattern</a>.
8995+
It happens before the <a href="#sparqlSimplification">simplification step</a>.
8996+
</div>
8997+
</div>
8998+
8999+
<div class="ednote" id="note-BindingInScope">
9000+
<p>
9001+
One way to provide `BindingInScope` is to change `eval` to also have the current row
9002+
as an argument or a "null" token. . Normally this the "null" token. This would be set in
9003+
eval-filter.
9004+
</p>
9005+
<p>
9006+
Another way is to have a global (to the execution) variable. In eval-exists, the
9007+
old value is recorded, the global set to the new value, and reset on exit - this forms a
9008+
stack for nested EXISTS.
9009+
</p>
9010+
<p>
9011+
Modifing `eval` is better prepartion for other correlted operations.<br/>
9012+
A current-row stack in EXISTS isless intrusive.
9013+
</p>
9014+
</div>
9015+
9016+
<div class="defn">
9017+
<b>Definition: <span id="defn_projmap">Projection Expression Variable Remapping</span></b>
9018+
<p>
9019+
For a projection algebra operation #sparqlProjection `Project(A, PV)` acting on algreg express `A` and with set of variables `PV`, define
9020+
a partial mapping `F` from
9021+
`<a href="#sparqlQueryVariables">V</a>`,
9022+
the set of all variables, to `V` where:
9023+
</p>
9024+
<pre>F(v) = v1 if v is in PV, where v1 is a fresh variable
9025+
F(v) = v if v is not in PV</pre>
9026+
<p>
9027+
Define the Projection Expression Variable Remapping `ProjectMap(P, PV)`
9028+
</p>
9029+
<pre>ProjectMap(Project(A, PV)) = Project(A1, PV)
9030+
where A1 is the result of applying F
9031+
to every variable mentioned in A.</pre>
9032+
<p>
9033+
The Projection Expression Variable Remapping yields an algrebra expression that
9034+
evaluates to the same results as the Project argument. No variable of `ProjectMap(Project(A, PV))`
9035+
that is not in `PV` is mentioned anywhere else in the algebra expression for the query.
9036+
</p>
9037+
</div>
9038+
<p>This process is applied throughout the graph pattern of <code>EXISTS</code>:</p>
9039+
<div class="defn">
9040+
<b>Definition: <span id="defn_varrename">Variable Remapping</span></b>
9041+
<p>
9042+
For any algebra expression `X`, define the Variable Remapping `PrjMap(X)`
9043+
of algebra expression `X`:
9044+
</p>
9045+
<pre>PrjMap(X) = replace all project operations Project(P, PV)
9046+
with ProjectMap(P, PV) for each projection in X.</pre>
9047+
</div>
9048+
<p>
9049+
The outcome of `PrjMap` is independent of the order of replacement
9050+
(e.g. bottom-up or top-down).
9051+
Replacements may happen several times, depending on recursive order
9052+
but each time a replacement is made, the variable not used anywhere else.
9053+
</p>
9054+
9055+
<div class="note">
9056+
<p>
9057+
A variable inside a project expression that is not in the variables projected
9058+
is not affected by the values insertion operation because it is renamed apart.
9059+
</p>
9060+
<p>
9061+
This operation is as part of the <a href="#sparqlQuery">translation to the SPARQL
9062+
algebra</a>.
9063+
</p>
9064+
</div>
9065+
</div>
9066+
</div>
89619067
</section>
9068+
9069+
89629070
<section id="sparqlTranslatePathExpressions">
89639071
<h5>Translate Property Path Expressions</h5>
89649072
<p>The following table gives the translation
@@ -9215,6 +9323,9 @@ <h5>Filters of Group</h5>
92159323
</section>
92169324
<section id="sparqlSimplification">
92179325
<h5>Simplification step</h5>
9326+
9327+
<p class="ednote">@@ Move out of the general `translate()` process and perform once after top level translation only</p>
9328+
92189329
<p>Some groups of one graph pattern become <code>join(Z, A)</code>, where Z is the empty
92199330
basic graph pattern (which is the empty set). These can be replaced by A. The empty graph
92209331
pattern Z is the identity for join:</p>
@@ -10512,6 +10623,12 @@ <h3>Evaluation Semantics</h3>
1051210623
</div>
1051310624
<div class="defn">
1051410625
<p><b>Definition: <span id="defn_evalFilter">Evaluation of Filter</span></b></p>
10626+
10627+
<p class="ednote">@@ Make current μ available. Or use current language in Exist.
10628+
Long term: change eval() to be arity three - 3rd argument is "current row".
10629+
<a href="="note-BindingInScope">editors note</a>.
10630+
</p>
10631+
1051510632
<p><a href="#defn_eval" class="evalFct">eval</a>( |D|(|G|), <a href="#defn_absFilter" class="absOp">Filter</a>(|F|, |P|) ) = <a href="#defn_algFilter" class="algFct">Filter</a>( |F|, <a href="#defn_eval" class="evalFct">eval</a>(|D|(|G|), |P|), |D|(|G|) )</p>
1051610633
</div>
1051710634
<p>'substitute' is a filter function in support of the evaluation of
@@ -10527,6 +10644,9 @@ <h3>Evaluation Semantics</h3>
1052710644
</div>
1052810645
<div class="defn">
1052910646
<p><b>Definition: <span id="defn_evalExists">Evaluation of Exists</span></b></p>
10647+
10648+
<p class="ednote">@@ Update</p>
10649+
1053010650
<p>Let <var>μ</var> be the current solution mapping for a filter and |P| a graph pattern:</p>
1053110651
<blockquote>
1053210652
The value exists(|P|), given |D|(|G|) is true if and only if <a href="#defn_eval" class="evalFct">eval</a>( |D|(|G|), substitute(|P|, <var>μ</var>)) is
@@ -10650,209 +10770,6 @@ <h3>Evaluation Semantics</h3>
1065010770
<a href="#defn_eval" class="evalFct">eval</a>( |D|(|G|), <a href="#defn_absSlice" class="absOp">Slice</a>(|L|, |start|, |length|) ) = <a href="#defn_algSlice" class="algFct">Slice</a>( <a href="#defn_eval" class="evalFct">eval</a>(|D|(|G|), |L|), |start|, |length| )
1065110771
</p>
1065210772
</div>
10653-
10654-
<!-- ValuesInsertion -->
10655-
<section>
10656-
<h3>Values Insertion and `EXISTS`</h3>
10657-
<div class="ednote">
10658-
<p>The following subsections contain draft material for a revised
10659-
"`exists`" operation.
10660-
</p>
10661-
<p>
10662-
Background: <a href="https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0007/sep-0007.md">SPARQL CG SEP-0007</a>
10663-
</p>
10664-
</div>
10665-
<section>
10666-
<h4>Syntax Restriction</h4>
10667-
<p><i>Additional [[[#sparqlGrammar]]] note:</i></p>
10668-
<blockquote>
10669-
Any variable that is assigned to in the graph pattern of `EXISTS`/`NOT EXISTS` must not be in-scope.
10670-
This applies to `BIND`, variables introduced by `AS` in a `SELECT` clause, variables in a `VALUES`
10671-
clause, and variables introduced by `AS` in `GROUP BY`.
10672-
</blockquote>
10673-
<p>
10674-
Extend the "in-scope" rules to include the possible
10675-
variables that are in-scope for the current row:
10676-
</p>
10677-
<table style="border-collapse: collapse; border-color: #000000; border-spacing:5px; border-width: 1px">
10678-
<tbody>
10679-
<tr>
10680-
<th>Syntax Form</th>
10681-
<th>In-scope variables</th>
10682-
</tr>
10683-
<tr>
10684-
<td>`EXISTS` and `NOT EXISTS` filters </td>
10685-
<td><code>v</code> is in-scope if it is in-scope for the pattern to which the `FILTER` is applied.
10686-
</td>
10687-
</tr>
10688-
</tbody>
10689-
</table>
10690-
<div class="note">
10691-
<p>
10692-
This restriction means that inserted values
10693-
do not conflict with values assigned to variables within the pattern.
10694-
</p>
10695-
<p>
10696-
This operation is performed as part of query parsing.
10697-
</p>
10698-
</div>
10699-
</section>
10700-
<section>
10701-
<h4>Remapping</h4>
10702-
<p>
10703-
Remapping ensures that a variable name used inside a project expression,
10704-
but which is not part of the results of the evaluation of the project expression,
10705-
does not coincide with a variable mentioned anywhere else in the
10706-
algebra expression of a query.
10707-
</p>
10708-
<p>
10709-
Renaming these variables does not change the results of evaluating
10710-
the project expresssion.
10711-
</p>
10712-
<div class="defn">
10713-
<b>Definition: <span id="defn_projmap">Projection Expression Variable Remapping</span></b>
10714-
<p>
10715-
For a <a href="#sparqlProjection">projection algebra operation</a>
10716-
`Project(A, PV)` acting on algebra expression `A` and with set of variables `PV`,
10717-
define a mapping `F` from `V`,
10718-
<a href="#sparqlQueryVariables">the set of all variables</a>,
10719-
to `V` where:
10720-
</p>
10721-
<pre>F(v) = v1 if v is not in PV, where v1 is a fresh variable
10722-
F(v) = v if v is in PV</pre>
10723-
<p>
10724-
Define the Projection Expression Variable Remapping `ProjectMap(P, PV)`
10725-
</p>
10726-
<pre>ProjectMap(Project(A, PV)) = Project(A1, PV)
10727-
where A1 is the result of applying F
10728-
to every variable mentioned in A.
10729-
</pre>
10730-
<p>
10731-
The Projection Expression Variable Remapping yields an algrebra expression that
10732-
evaluates to the same results as the Project argument. No variable of `ProjectMap(Project(A, PV))`
10733-
that is not in `PV` is mentioned anywhere else in the algebra expression for the query.
10734-
</p>
10735-
</div>
10736-
<p>This process is applied throughout the graph pattern of <code>EXISTS</code>:</p>
10737-
<div class="defn">
10738-
<b>Definition: <span id="defn_varrename">Variable Remapping</span></b>
10739-
<p>
10740-
For any algebra expression `X`, define the Variable Remapping `PrjMap(X)`
10741-
of algebra expression `X`:
10742-
</p>
10743-
<pre>PrjMap(X) = replace all project operations Project(P, PV)
10744-
with ProjectMap(Project(A, PV), PV) for each projection in X.</pre>
10745-
</div>
10746-
<p>
10747-
The outcome of `PrjMap` is independent of the order of replacement
10748-
(whether "bottom-up" or "top-down") order.
10749-
Replacements may happen several times, depending on recursive order
10750-
but each time a replacement is made, the variable not used anywhere else.
10751-
</p>
10752-
10753-
<div class="note">
10754-
<p>
10755-
A variable inside a project expression that is not in the variables projected
10756-
is not affected by the values insertion operation because it is renamed apart.
10757-
</p>
10758-
<p>
10759-
This operation is as part of the <a href="#sparqlQuery">translation to the SPARQL
10760-
algebra</a>.
10761-
</p>
10762-
</div>
10763-
</section>
10764-
<section>
10765-
<h4>Values Insertion</h4>
10766-
<p>
10767-
Alternative 1: rewrite the algebra during
10768-
<a href="#sparqlQuery">translation to the SPARQL algebra</a>
10769-
to include a function that evaluates to the current row.
10770-
</p>
10771-
10772-
<div class="defn">
10773-
<div>
10774-
<b>Definition: <span id="defn_correlate">Values In Scope</span></b>
10775-
<p>
10776-
Define the function `BindingInScope()`.
10777-
Evaluation of `BindingInScope()` results in a table of one row,
10778-
being the current binding of the enclosing filter.
10779-
</p>
10780-
</div>
10781-
<p class="ednote">Need to define `BindingInScope`</p>
10782-
</div>
10783-
10784-
<div class="defn">
10785-
<div>
10786-
<b>Definition: Access to the current binding</b>
10787-
<p>
10788-
During <a href="#sparqlQuery">translation to the SPARQL algebra</a>
10789-
</p>
10790-
<p class="ednote">Define putting in the `BindingInScope` operator</p>
10791-
<pre>
10792-
Replace each occurence of Y where Y is one of
10793-
<a href="#sparqlTranslateBasicGraphPatterns">Basic Graph Pattern</a>,
10794-
<a href="#sparqlTranslatePathPatterns">Property Path Patterns</a>,
10795-
<a href="#sparqlTranslateGraphPatterns">Graph(Var, pattern)</a>,
10796-
<a href="#https://www.w3.org/TR/sparql12-query/#sparqlTranslateGraphPatterns">Inline Data</a>
10797-
with join(Y, BindingInScope()).</pre>
10798-
</div>
10799-
<div class="note">
10800-
c.f. section <a href="#sparqlTranslateGraphPatterns">Translate Graph Patterns</a>
10801-
where an empty basic graph pattern start any
10802-
<a href="#rGroupGraphPattern">GroupGraphPattern</a>.
10803-
It happens before the <a href="#sparqlSimplification">simplification step</a>.
10804-
</div>
10805-
</div>
10806-
10807-
<div class="example">
10808-
<p>
10809-
Examples
10810-
</p>
10811-
</div>
10812-
10813-
<p>
10814-
Alternative 2: rewrite the algebra during execution. This corresponds to the
10815-
<a href="https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0007/sep-0007.md">original SEP-0007 proposal</a>.
10816-
</p>
10817-
<div class="defn">
10818-
<div>
10819-
<b>Definition: <span id="defn_insertvalues">Insert Values</span></b>
10820-
<p>
10821-
Define the function `InsertValues(X, μ)`
10822-
</p>
10823-
<pre>Let Table(μ) = { μ } and multiplicity( μ | Table(μ) = { μ } ) = 1
10824-
10825-
Replace each occurence of Y in X where Y is one of
10826-
<a href="#sparqlTranslateBasicGraphPatterns">Basic Graph Pattern</a>,
10827-
<a href="#sparqlTranslatePathPatterns">Property Path Patterns</a>,
10828-
<a href="#sparqlTranslateGraphPatterns">Graph(Var, pattern)</a>,
10829-
<a href="#https://www.w3.org/TR/sparql12-query/#sparqlTranslateGraphPatterns">Inline Data</a>
10830-
with join(Y, Table(μ)).</pre>
10831-
10832-
</div>
10833-
</div>
10834-
</section>
10835-
10836-
<section>
10837-
<h4>Evaluation of EXISTS</h4>
10838-
<div class="defn">
10839-
<b>Definition: <span id="x-defn_evalExists">Evaluation of Exists</span></b>
10840-
<p>
10841-
Let `μ` be the current solution mapping for a filter, and `X` a graph pattern,
10842-
define the Evaluation of Exists `exists(X)`
10843-
</p>
10844-
<p class="ednote">
10845-
@@ Set up the current row for `BindingdInScope`.
10846-
</p>
10847-
<pre>exists(X) = true
10848-
if eval( D(G), μ)
10849-
is a non-empty solution sequence.
10850-
exists(X) = false otherwise</pre>
10851-
</div>
10852-
</section>
10853-
</section>
10854-
<!-- ValuesInsertion -->
10855-
1085610773
</section>
1085710774

1085810775
<section id="sparqlBGPExtend">

0 commit comments

Comments
 (0)