@@ -8937,6 +8937,7 @@ <h5>Expand Syntax Forms</h5>
8937
8937
<p>Expand abbreviations for IRIs and triple patterns given in
8938
8938
<a href="#sparqlSyntax">section 4</a>.</p>
8939
8939
</section>
8940
+
8940
8941
<section id="sparqlCollectFilters">
8941
8942
<h5>Collect <code>FILTER</code> Elements</h5>
8942
8943
<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>
8952
8953
Let FS := empty set
8953
8954
For each form FILTER(expr) in the group graph pattern
8954
8955
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})
8956
8957
FS := FS ∪ {expr}
8957
8958
End
8958
8959
</pre>
8959
8960
<p>The set of filter expressions <code>FS</code> is <a href="#sparqlAddFilters">used
8960
8961
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>
8961
9067
</section>
9068
+
9069
+
8962
9070
<section id="sparqlTranslatePathExpressions">
8963
9071
<h5>Translate Property Path Expressions</h5>
8964
9072
<p>The following table gives the translation
@@ -9215,6 +9323,9 @@ <h5>Filters of Group</h5>
9215
9323
</section>
9216
9324
<section id="sparqlSimplification">
9217
9325
<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
+
9218
9329
<p>Some groups of one graph pattern become <code>join(Z, A)</code>, where Z is the empty
9219
9330
basic graph pattern (which is the empty set). These can be replaced by A. The empty graph
9220
9331
pattern Z is the identity for join:</p>
@@ -10512,6 +10623,12 @@ <h3>Evaluation Semantics</h3>
10512
10623
</div>
10513
10624
<div class="defn">
10514
10625
<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
+
10515
10632
<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>
10516
10633
</div>
10517
10634
<p>'substitute' is a filter function in support of the evaluation of
@@ -10527,6 +10644,9 @@ <h3>Evaluation Semantics</h3>
10527
10644
</div>
10528
10645
<div class="defn">
10529
10646
<p><b>Definition: <span id="defn_evalExists">Evaluation of Exists</span></b></p>
10647
+
10648
+ <p class="ednote">@@ Update</p>
10649
+
10530
10650
<p>Let <var>μ</var> be the current solution mapping for a filter and |P| a graph pattern:</p>
10531
10651
<blockquote>
10532
10652
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>
10650
10770
<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| )
10651
10771
</p>
10652
10772
</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
-
10856
10773
</section>
10857
10774
10858
10775
<section id="sparqlBGPExtend">
0 commit comments