Skip to content

Commit dc25411

Browse files
committed
Add = and != for IRIs, bnodes and triple terms
1 parent 03fb4e0 commit dc25411

File tree

1 file changed

+126
-102
lines changed

1 file changed

+126
-102
lines changed

Diff for: spec/index.html

+126-102
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@
243243
span.cancast:hover { background-color: #ffa;
244244
color: black; }
245245

246-
.SPARQLoperator { background-color: #FFFFbf; /* yellow */
247-
}
246+
.SPARQLoperator { font-weight: 600; }
248247

249248
/* ReSpec */
250249
dfn { font-style: normal ; }
@@ -4665,6 +4664,7 @@ <h3>Operand Data Types</h3>
46654664
<p>SPARQL language extensions may treat additional types as being derived from XML schema
46664665
datatypes.</p>
46674666
</section>
4667+
46684668
<section id="evaluation">
46694669
<h3>Filter Evaluation</h3>
46704670
<p>SPARQL provides a subset of the functions and operators defined by
@@ -4826,6 +4826,7 @@ <h4>Effective Boolean Value (EBV)</h4>
48264826
with a datatype of <code>xsd:boolean</code> and a lexical value of "false".</p>
48274827
</section>
48284828
</section>
4829+
48294830
<section id="OperatorMapping">
48304831
<h3>Operator Mapping</h3>
48314832
<p>The SPARQL grammar identifies a set of operators
@@ -4925,7 +4926,7 @@ <h3>Operator Mapping</h3>
49254926
<th colspan="5" class="subHeading" scope="col">Logical Connectives</th>
49264927
</tr>
49274928
<tr>
4928-
<th>
4929+
<th><span id="logical-or-operator"/>
49294930
<a href="#rConditionalOrExpression" title="ConditionalOrExpression">A <span class="FAOTtoken">||</span> B</a>
49304931
</th>
49314932
<td>
@@ -4934,7 +4935,7 @@ <h3>Operator Mapping</h3>
49344935
<td>
49354936
xsd:boolean <a href="#ebv-arg">(EBV)</a>
49364937
</td>
4937-
<td class="sparqlOp">
4938+
<td class="sparqlOp"><span id="logical-and-operator"/>
49384939
<a href="#func-logical-or" class="SPARQLoperator">logical-or</a>(A, B)
49394940
</td>
49404941
<td>xsd:boolean</td>
@@ -5275,32 +5276,91 @@ <h3>Operator Mapping</h3>
52755276
<th colspan="5" class="subHeading" scope="col">SPARQL Tests</th>
52765277
</tr>
52775278
<tr>
5278-
<th>
5279-
<a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">=</span> B</a>
5280-
</th>
5279+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">=</span> B</a></th>
5280+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-iri">IRI</a></span></td>
5281+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-iri">IRI</a></span></td>
5282+
<td>
5283+
<a href="#func-sameTerm">sameTerm</a>(A, B)
5284+
</td>
5285+
<td>xsd:boolean</td>
5286+
</tr>
5287+
<tr>
5288+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">=</span> B</a></th>
5289+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-blank-node">Blank Node</a></span></td>
5290+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-blank-node">Blank Node</a></span></td>
5291+
<td>
5292+
<a href="#func-sameTerm">sameTerm</a>(A, B)
5293+
</td>
5294+
<td>xsd:boolean</td>
5295+
</tr>
5296+
<tr>
5297+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">=</span> B</a></th>
5298+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-triple-term">Triple Term</a></span></td>
5299+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-triple-term">Triple Term</a></span></td>
5300+
<td>
5301+
( A.subject = B.subject ) <a href="#logical-and-operator" class="SPARQLoperator">&&</a><br/>
5302+
( A.predicate = B.predicate ) <a href="#logical-and-operator" class="SPARQLoperator">&&</a><br/>
5303+
( A.object = B.object )
5304+
</td>
5305+
<td>xsd:boolean</td>
5306+
</tr>
5307+
<tr>
5308+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">!=</span> B</a></th>
5309+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-iri">IRI</a></span></td>
5310+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-iri">IRI</a></span></td>
5311+
<td><a data-cite="XPATH-FUNCTIONS-31#func-not">fn:not</a>(<a href="#func-sameTerm">sameTerm</a>(A, B))</td>
5312+
<td>xsd:boolean</td>
5313+
</tr>
5314+
<tr>
5315+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">!=</span> B</a></th>
5316+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-blank-node">Blank Node</a></span></td>
5317+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-blank-node">Blank Node</a></span></td>
5318+
<td>
5319+
<a data-cite="XPATH-FUNCTIONS-31#func-not">fn:not</a>(<a href="#func-sameTerm">sameTerm</a>(A, B)
5320+
</td>
5321+
<td>xsd:boolean</td>
5322+
</tr>
5323+
<tr>
5324+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">!=</span> B</a></th>
5325+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-triple-term">Triple Term</a></span></td>
5326+
<td><span class="type RDFterm"><a data-cite="RDF12-CONCEPTS#dfn-triple-term">Triple Term</a></span></td>
5327+
<td>
5328+
( A.subject != B.subject ) <a href="#logical-or-operator" class="SPARQLoperator">||</a><br/>
5329+
( A.predicate != B.predicate ) <a href="#logical-or-operator" class="SPARQLoperator">||</a><br/>
5330+
( A.object != B.object )
5331+
</td>
5332+
<td>xsd:boolean</td>
5333+
</tr>
5334+
<tr>
5335+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">=</span> B</a></th>
52815336
<td><span class="type RDFterm">RDF term</span></td>
52825337
<td><span class="type RDFterm">RDF term</span></td>
52835338
<td class="xpathOp">
5284-
<a href="#func-sameValue" class="SPARQLoperator">sameValue</a>(A, B)
5285-
</td>
5339+
<a href="#func-sameValue">sameValue</a>(A, B)
5340+
</td>
52865341
<td>xsd:boolean</td>
52875342
</tr>
52885343
<tr>
5289-
<th>
5290-
<a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">!=</span> B</a>
5291-
</th>
5344+
<th><a href="#rRelationalExpression" title="RelationalExpression">A <span class="FAOTtoken">!=</span> B</a></th>
52925345
<td><span class="type RDFterm">RDF term</span></td>
52935346
<td><span class="type RDFterm">RDF term</span></td>
52945347
<td class="xpathOp">
5295-
<a data-cite="XPATH-FUNCTIONS-31#func-not">fn:not</a>(<a href="#func-sameValue" class="SPARQLoperator">sameValue</a>(A, B))
5348+
<a data-cite="XPATH-FUNCTIONS-31#func-not">fn:not</a>(<a href="#func-sameValue">sameValue</a>(A, B))
52965349
</td>
52975350
<td>xsd:boolean</td>
52985351
</tr>
52995352
</tbody>
53005353
</table>
5301-
<div id="ebv-arg"></div>xsd:boolean function arguments marked with "(EBV)" are
5354+
<p>
5355+
<span id="ebv-arg"></span>xsd:boolean function arguments marked with "(EBV)" are
53025356
coerced to xsd:boolean by evaluating the <a href="#ebv">effective boolean value of that
53035357
argument.</a>
5358+
</p>
5359+
<p>
5360+
Operators <span class="SPARQLoperator">=</span> and <span class="SPARQLoperator">!=</span> applied to
5361+
<a data-cite="RDF12-CONCEPTS#dfn-triple-term">triple terms</a>
5362+
apply the operator to each of the components.
5363+
</p>
53045364
<section id="operatorExtensibility">
53055365
<h4>Operator Extensibility</h4>
53065366
<p>SPARQL language extensions may provide additional associations between operators and
@@ -5314,6 +5374,7 @@ <h4>Operator Extensibility</h4>
53145374
BY</code></a> clause.</p>
53155375
</section>
53165376
</section>
5377+
53175378
<section id="SparqlOps">
53185379
<h3>Function Definitions</h3>
53195380
<p>This section defines the operators and functions introduced by the SPARQL query language.
@@ -5678,7 +5739,7 @@ <h5>sameTerm</h5>
56785739
defined in [[[RDF12-CONCEPTS]]] [[RDF12-CONCEPTS]]; returns FALSE otherwise.</p>
56795740
<p>
56805741
|term1| and |term2| are the
5681-
<a data-cite="RDF12-CONCEPTS#dfn-rdf-term-equality">same RDF terms</a>
5742+
<a data-cite="RDF12-CONCEPTS#dfn-rdf-term-equality">same RDF term</a>
56825743
if one of the following is true:
56835744
</p>
56845745
<ul>
@@ -5756,77 +5817,61 @@ <h5>sameValue</h5>
57565817

57575818
<p>This function cannot be used directly in expressions. The purpose
57585819
of this function is to define the semantics of the "=" operator when applied to
5759-
two RDF terms that do not fall into any of the other, more concrete cases
5820+
two RDF terms that do not fall into the concrete cases
57605821
covered in the operator mapping table in Section
57615822
<a href="#OperatorMapping" class="sectionRef"></a>.
57625823
</p>
57635824

5764-
<p class="ednote" style="background-color: #EEE">
5765-
Revise for triple terms.
5766-
<br/>
5767-
Consider adding non-literal `=` to operator mapping table.
5768-
</p>
5769-
57705825
<p>The result of this function is determined by going through the following steps.</p>
5826+
57715827
<ol>
57725828
<li>If <code>term1</code> and <code>term2</code> are
57735829
<a data-cite="RDF12-CONCEPTS#dfn-rdf-term-equality">equal RDF terms</a>,
5774-
the return TRUE.
5830+
then return TRUE.
57755831
</li>
5776-
<li>If both arguments are literals,
5832+
<li>If <code>term1</code> or <code>term2</code> is an
5833+
<a data-cite="RDF12-CONCEPTS#dfn-iri">IRI</a> or a
5834+
<a data-cite="RDF12-CONCEPTS#dfn-blank-node">blank node</a>
5835+
then return FALSE.
5836+
<li>If <code>term1</code> and <code>term2</code> are both
57775837
<a data-cite="RDF12-CONCEPTS#dfn-literal">literals</a>
5778-
and one or both arguments are known to be ill-typed,
5838+
and one or both of these literals has a datatype that is
5839+
not handled by the SPARQL processor,
57795840
then produce a type error.
57805841
</li>
5781-
<li>If <code>term1</code> and <code>term2</code> both
5842+
<li>If <code>term1</code> and <code>term2</code> are both
5843+
<a data-cite="RDF12-CONCEPTS#dfn-literal">literals</a>
5844+
and one or both of these literals are known to be
5845+
<a data-cite="RDF12-CONCEPTS#dfn-ill-typed">ill-typed</a>,
5846+
then produce a type error.
5847+
</li>
5848+
<li>
5849+
`"NaN"^^xsd:double` and `"NaN"^^xsd:float` are considered to
5850+
represent the same value.
5851+
If <code>term1</code> and <code>term2</code> are
5852+
both "NaN" for either xsd:double or xsd:float, then
5853+
return TRUE.
5854+
</li>
5855+
<li>If <code>term1</code> and <code>term2</code> are both
57825856
<a data-cite="RDF12-CONCEPTS#dfn-literal">literals</a>
5783-
and the SPARQL processor can determine the values are equal,
5857+
and the SPARQL processor can determine that their the values are equal,
57845858
then return TRUE.
57855859
</li>
5786-
<li>If <code>term1</code> and <code>term2</code> both
5860+
<li>If <code>term1</code> and <code>term2</code> are both
57875861
<a data-cite="RDF12-CONCEPTS#dfn-literal">literals</a>
57885862
and the SPARQL processor can determine the values can not be equal,
57895863
then return FALSE.
57905864
</li>
5791-
<li>Otherwise, return FALSE.
5865+
<li>
5866+
If <code>term1</code> and <code>term2</code> are both
5867+
<a data-cite="RDF12-CONCEPTS#dfn-triple-term">triple terms</a>,
5868+
apply the function `sameValue` pair-wise to each of the components.
5869+
Return TRUE if each component pair returns TRUE;
5870+
produce a type error if any component pair produces an error;
5871+
otherwise return FALSE.
57925872
</li>
5873+
<li>Otherwise, return FALSE.</li>
57935874
</ol>
5794-
<div class="ednote" style="background-color: #EEE">
5795-
<p>
5796-
The treatment of `NaN` can not be consistent with both "same term means same value"
5797-
and "`fn:numeric-equal(NaN, NaN)` is false". So it is an arbitrary choice with
5798-
arguments for all three possible choices.
5799-
For pattern matching, `"NaN"^^xsd:double` must match itself and
5800-
`"NaN"^^xsd:double` does not pattern match `"NaN"^^xsd:float`.
5801-
</p>
5802-
<p>
5803-
The operator mapping for `=` goes to `fn:numeric-compare` which is false.
5804-
The `sameValue` result could be made an error (or false) as a special case.
5805-
</p>
5806-
<p>
5807-
`"NaN"^^xsd:double = "NaN"^^xsd:float` is also handled by the
5808-
operator mapping and is false &ndash; `xsd:float` is promoted to `xsd:double`.
5809-
A reading of IEEE 754 is that `"NaN"^^xsd:double` and `"NaN"^^xsd:float`
5810-
are the same term also suggests that `sameValue` is true.
5811-
</p>
5812-
<p>
5813-
<b>Proposal 1</b>: follow "sameTerm means sameValue" and `sameValue("NaN"^^xsd:double, "NaN"^^xsd:double)`
5814-
and `sameValue("NaN"^^xsd:float, "NaN"^^xsd:float)` are <i>true</i>s.
5815-
<br/>
5816-
<b>Proposal 2</b>:
5817-
follow "there is one NaN" so `sameValue("NaN"^^xsd:double, "NaN"^^xsd:float)` is <i>true</i>.
5818-
</p>
5819-
<p>
5820-
Ref</i>: <a href="https://www.w3.org/TR/xmlschema11-2/#dt-specialvalue">XSD schema 1.1 special values</a>
5821-
"are members of the datatype's ·value space·. ". It is not clear whether "special value" literals
5822-
added to the value spaces of `xsd:double` and `xsd:float` are "the same" literals.
5823-
<p>
5824-
<i>Ref</i>: <a href="https://en.wikipedia.org/wiki/IEEE_754#Special_values">(wikipedia) IEEE_754 Special Values</a>
5825-
<i>IEEE 754 specifies a special value called "Not a Number" (NaN)</i>.
5826-
suggests they are the same.
5827-
</p>
5828-
</div>
5829-
58305875
<div id="sameValue-ill-typed" class="note">
58315876
<p>A literal is
58325877
<a data-cite="RDF12-CONCEPTS#dfn-ill-typed">ill-typed</a>
@@ -5847,31 +5892,19 @@ <h5>sameValue</h5>
58475892
The <a href="#OperatorMapping">Operator Mapping</a> for "`=`"
58485893
is the function
58495894
<a data-cite="XPATH-FUNCTIONS-31#func-numeric-equal">`fn:numeric-equal`</a>
5850-
which returns `false` when comparing arguments involving `NaN`.
5851-
However, `sameTerm("NaN"^^xsd:double, "NaN"^^xsd:double)` is true;
5852-
`sameValue` treats "NaN" as the "same value".
5853-
`sameTerm("NaN"^^xsd:double, "NaN"^^xsd:float)` is `true`.
5895+
which is defined to return `false` when comparing arguments involving `NaN`.
5896+
However, `sameTerm("NaN"^^xsd:double, "NaN"^^xsd:double)` is true.
5897+
The function `sameValue` defines `sameValue("NaN"^^xsd:double, "NaN"^^xsd:double)`
5898+
to be true because the arguments are the same element of the value space.
58545899
</p>
5855-
</div>
5856-
<div id="sameValue-old-name" class="note">
5857-
<p>This function was previously called `RDFterm-equal`.</p>
5858-
</div>
5859-
5860-
<div class="ednote" style="background-color: #EEE">
58615900
<p>
5862-
A SPARQL processor may support datatypes beyond those required.
5863-
Suppose `ex:romanNumeral` is the datatype IRI
5864-
<a href="https://en.wikipedia.org/wiki/Roman_numerals">roman numerals</a>
5865-
which are integer numbers. The SPARQL processor may then be able
5866-
to detemine if two literals have the same value, for example,
5867-
`sameValue(4, "IV"^^ex:romanNumeral)` can then return `true`
5868-
because argument bot represent the value 4.
5869-
For `sameValue("abc"^^xsd:string, "IV"^^ex:romanNumeral)`
5870-
can return `false` because `xsd:string` and `ex:romanNumeral`
5871-
have different value spaces so the arguments can not be the same value.
5901+
`sameValue` treats the values of `"NaN"^^xsd:double` and `"NaN"^^xsd:float` as being
5902+
the same. `sameValue("NaN"^^xsd:double, "NaN"^^xsd:float)` is `true`.
58725903
</p>
58735904
</div>
5874-
5905+
<p id="sameValue-zeros" class="note">
5906+
For xsd:double and xsd:float, `+0`, `-0` and `0` are same value.
5907+
</p>
58755908
<p id="func-sameValue-note1" class="note">
58765909
An extended implementation may support additional datatypes for literals. An
58775910
implementation processing a query that tests for equivalence of literals with non-recognized datatypes
@@ -5890,22 +5923,6 @@ <h5>sameValue</h5>
58905923
<th>sameValue</th>
58915924
<th>Results</th>
58925925
</tr>
5893-
<tr>
5894-
<td><code>sameValue(2, +2)</code></td>
5895-
<td>true</td>
5896-
</tr>
5897-
<tr>
5898-
<td><code>sameValue(2.0, 2)</code></td>
5899-
<td>true</td>
5900-
</tr>
5901-
<tr>
5902-
<td><code>sameValue(2, "2")</code></td>
5903-
<td>false</td>
5904-
</tr>
5905-
<tr>
5906-
<td><code>sameValue(4, "iv"^^my:romanNumeral)</code></td>
5907-
<td>error, or true by extension</td>
5908-
</tr>
59095926
<tr>
59105927
<td><code>sameValue(1e10, "NaN"^^xsd:double)</code></td>
59115928
<td>false</td>
@@ -5918,9 +5935,16 @@ <h5>sameValue</h5>
59185935
<td><code>sameValue("NaN"^^xsd:double, "NaN"^^xsd:float)</code></td>
59195936
<td>true</td>
59205937
</tr>
5938+
<tr>
5939+
<td><code>sameValue( &lt;&lt(:s :p 123)&gt;&gt , &lt;&lt(:s :p 123.0)&gt;&gt )</td>
5940+
<td>true</td>
5941+
</tr>
59215942
</tbody>
59225943
</table>
59235944
</div>
5945+
<p id="sameValue-old-name" class="note">
5946+
This function was called `RDFterm-equal` up until SPARQL 1.1.
5947+
</p>
59245948
</section>
59255949

59265950
<section id="func-isIRI">

0 commit comments

Comments
 (0)