Skip to content

Commit

Permalink
Move the operator mapping tables, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelhkay committed Jan 28, 2025
1 parent d65e1dd commit 7c24c8e
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 128 deletions.
132 changes: 71 additions & 61 deletions specifications/xpath-functions-40/src/function-catalog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3062,8 +3062,8 @@ compare($N * $arg2, 0) eq compare($arg1, 0).</eg>
<p>The <code>$value</code> argument may be of any numeric data type
(<code>xs:double</code>, <code>xs:float</code>, <code>xs:decimal</code>, or their
subtypes including <code>xs:integer</code>). Note that if an <code>xs:decimal</code> is
supplied, it is not automatically promoted to an <code>xs:double</code>, as such
promotion can involve a loss of precision.</p>
supplied, it is not automatically converted to an <code>xs:double</code>, as such
conversion can involve a loss of precision.</p>
<p>If the supplied value of the <code>$value</code> argument is an empty sequence, the
function behaves as if the supplied value were the <code>xs:double</code> value
<code>NaN</code>.</p>
Expand Down Expand Up @@ -3928,8 +3928,8 @@ translate(value := '٢٠٢٣', replace := '٠١٢٣٤٥٦٧٨٩', with := '01234
ref="ieee754-2019"
/> specification of the <code>pown</code> function applied to a
64-bit binary floating point value and an integer.</p>
<p>Otherwise <code>$y</code> is converted to an <code>xs:double</code> by numeric
promotion, and the result is <code>$x</code> raised to the power of
<p>Otherwise <code>$y</code> is cast to an <code>xs:double</code>,
and the result is <code>$x</code> raised to the power of
<code>$y</code> as defined in the <bibref
ref="ieee754-2019"
/> specification of the
Expand Down Expand Up @@ -8373,7 +8373,7 @@ xs:dayTimeDuration($arg2) div xs:dayTimeDuration('PT1S')
<p>The result of <code>seconds($n)</code> is approximately equal to the result of
the expression <code>xs:dayTimeDuration('PT1S') * $n</code>. The equivalence is only
approximate, because <code>seconds($n)</code> uses the exact <code>xs:decimal</code>
value supplied, whereas multiplying a duration by a number first promotes the number
value supplied, whereas multiplying a duration by a number first converts the number
to an <code>xs:double</code> value, which may lose precision.</p>
</fos:notes>
<fos:examples>
Expand Down Expand Up @@ -14428,29 +14428,9 @@ return exists($break)
</ulist>


<p diff="del" at="A"
>If the input sequence contains values of different numeric types that differ from each
other by small amounts, then the eq operator is not transitive, because of rounding
effects occurring during type promotion. In the situation where the input contains three
values <code>A</code>, <code>B</code>, and <code>C</code> such that <code>A eq B</code>,
<code>B eq C</code>, but <code>A ne C</code>, then the number of items in the result
of the function (as well as the choice of which items are returned) is <termref
def="implementation-dependent"
>implementation-dependent</termref>, subject only to the constraints that (a) no two
items in the result sequence compare equal to each other, and (b) every input item that
does not appear in the result sequence compares equal to some item that does appear in
the result sequence.</p>

<p diff="del" at="A">For example, this arises when computing:</p>

<eg diff="del" at="A"><![CDATA[ distinct-values(
(xs:float('1.0'),
xs:decimal('1.0000000000100000000001',
xs:double('1.00000000001'))]]></eg>


<p diff="del" at="A"
>because the values of type <code>xs:float</code> and <code>xs:double</code> both compare
equal to the value of type <code>xs:decimal</code> but not equal to each other. </p>

</fos:rules>
<fos:notes>
<p>If <code>$values</code> is the empty sequence, the function returns the empty sequence.</p>
Expand Down Expand Up @@ -17152,26 +17132,21 @@ declare function equal-strings(
</fos:summary>
<fos:rules>
<p>If <code>$values</code> is the empty sequence, the empty sequence is returned.</p>
<p>If <code>$values</code> contains values of type <code>xs:untypedAtomic</code> they are cast
to <code>xs:double</code>. </p>
<p>Duration values must either all be <code>xs:yearMonthDuration</code> values or must all
be <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
rules defined in <specref
ref="op.numeric"
/> are used to promote all values to a single
common type. After these operations, <code>$values</code> must satisfy the following condition:</p>
<p>There must be a type <var>T</var> such that:</p>
<p>Any item in <code>$values</code> that is an instance of <code>xs:untypedAtomic</code>
is cast to <code>xs:double</code>. </p>
<p>After this conversion, one of the following conditions must be true:</p>
<olist>
<item><p>every item in <code>$values</code> is an instance of <var>T</var>.</p></item>
<item><p><var>T</var> is one of <code>xs:double</code>, <code>xs:float</code>,
<code>xs:decimal</code>, <code>xs:yearMonthDuration</code>, or
<code>xs:dayTimeDuration</code>.</p></item>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:yearMonthDuration</code>.</p></item>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:dayTimeDuration</code>.</p></item>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:numeric</code>.</p></item>
</olist>


<p>The function returns the average of the values as <code>sum($values) div
count($values)</code>; but the implementation may use an otherwise equivalent algorithm
that avoids arithmetic overflow.</p>
that avoids arithmetic overflow. Note that the <function>fn:sum</function> function
allows the input sequence to be reordered, which may affect the result in edge cases
when the sequence contains a mixture of different numeric types.</p>

</fos:rules>
<fos:errors>
Expand Down Expand Up @@ -17219,6 +17194,16 @@ declare function equal-strings(
code="0006"/>. </p>
</fos:example>
</fos:examples>
<fos:changes>
<fos:change issue="1682" date="2025-01-27">
<p>In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification
was unclear whether it was permitted to add the first two integer items using
integer arithmetic, rather than converting all items to doubles before
performing any arithmetic. The 4.0 specification is clear that this is
permitted; but since the items can be reordered before being added, this
is not required.</p>
</fos:change>
</fos:changes>
</fos:function>

<fos:function name="max" prefix="fn">
Expand Down Expand Up @@ -17558,34 +17543,36 @@ declare function equal-strings(
<p>Returns a value obtained by adding together the values in <code>$values</code>.</p>
</fos:summary>
<fos:rules>
<p>Any values of type <code>xs:untypedAtomic</code> in <code>$values</code> are cast to
<p>The result of the function when a single argument
is supplied is the result of the expression: <code>fn:sum($arg, 0)</code>.</p>
<p>Any value of type <code>xs:untypedAtomic</code> in <code>$values</code> is cast to
<code>xs:double</code>. The items in the resulting sequence may be reordered in an
arbitrary order. The resulting sequence is referred to below as the converted
sequence.</p>
<p diff="chg" at="2023-01-17">If the converted sequence is empty, then the function returns
<p>If the converted sequence is empty, then the function returns
the value of the argument <code>$zero</code>, which defaults to
the <code>xs:integer</code> value <code>0</code>.</p>
<p>If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is
returned.</p>
<p>All items in <code>$values</code> must be numeric or derived from a single base type. In
addition, the type must support addition. Duration values must either all be
<code>xs:yearMonthDuration</code> values or must all be
<code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
rules defined in <specref
ref="op.numeric"
/> are used to promote all values to a single
common type. The sum of a sequence of integers will therefore be an integer, while the
sum of a numeric sequence that includes at least one <code>xs:double</code> will be an
<code>xs:double</code>. </p>
<p>The result of the function is the value of the
<p>In other cases the items in the converted sequence are added pairwise according
the rules of the <code>+</code> operator.</p>

<p>Specifically, the result of the function is the value of the
expression:</p>
<eg xml:space="preserve">
if (empty($c)) then $zero
else if (count($c) eq 1) then $c
else head($c) + sum(tail($c))</eg>
<p>where <code>$c</code> is the converted sequence.</p>
<p>The result of the function <phrase diff="chg" at="2023-01-17">when a single argument is supplied</phrase> is the result of the expression:
<code>fn:sum($arg, 0)</code>.</p>

<p>This has the effect that a type error will occur unless one of the following
conditions is satisfied:</p>

<olist>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:yearMonthDuration</code>.</p></item>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:dayTimeDuration</code>.</p></item>
<item><p>Every item in <code>$values</code> is an instance of <code>xs:numeric</code>.</p></item>
</olist>



</fos:rules>
<fos:errors>
Expand All @@ -17604,7 +17591,20 @@ else head($c) + sum(tail($c))</eg>
the <code>$zero</code> argument is used only when the input sequence is empty, not
when a non-empty sequence sums to zero. For example, <code>sum((-1, +1), xs:double('NaN'))</code>
returns the <code>xs:integer</code> value <code>0</code>, not <code>NaN</code>.</p>
<p> If the converted sequence contains exactly one value then that value is returned.</p>
<p>The sum of a sequence of integers will be an integer, while the
sum of a numeric sequence that includes at least one <code>xs:double</code> will be an
<code>xs:double</code>.</p>
<p>If the converted sequence contains exactly one value then that value is returned.</p>
<p>If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is
returned.</p>
<p>In edge cases the fact that the input sequence may be reordered makes the result
slightly unpredictable. For example, if the input contains two <code>xs:decimal</code>
values and an <code>xs:float</code>, then the decimal values might be added using
decimal arithmetic, or they might both be converted to <code>xs:float</code>
(potentially losing precision) before any arithmetic is performed.
</p>


</fos:notes>
<fos:examples>
<fos:variable name="d1" id="v-sum-d1" select="xs:yearMonthDuration(&quot;P20Y&quot;)"/>
Expand Down Expand Up @@ -17678,6 +17678,16 @@ else head($c) + sum(tail($c))</eg>
/>. </p>
</fos:example>
</fos:examples>
<fos:changes>
<fos:change issue="1682" date="2025-01-27">
<p>In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification
was unclear whether it was permitted to add the first two integer items using
integer arithmetic, rather than converting all items to doubles before
performing any arithmetic. The 4.0 specification is clear that this is
permitted; but since the items can be reordered before being added, this
is not required.</p>
</fos:change>
</fos:changes>
</fos:function>
<!--<fos:function name="to" prefix="op">
<fos:signatures>
Expand Down Expand Up @@ -18249,7 +18259,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
<p>If <code>$source</code> is the empty sequence, the result is an empty sequence.</p>
<p>If <code>$source</code> is a relative URI reference, it is resolved relative to the value
of the <term>static base URI</term> property from the static context. The resulting absolute URI is
promoted to an <code>xs:string</code>.</p>
cast to an <code>xs:string</code>.</p>
<p>If the <term>available documents</term> described in <xspecref spec="XP31"
ref="eval_context"
/> provides a mapping from this string to a document node, the
Expand Down
44 changes: 13 additions & 31 deletions specifications/xpath-functions-40/src/xpath-functions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -692,33 +692,17 @@ Michael Sperberg-McQueen (1954–2024).</p>
<div2 id="id-function-calls">
<head>Function calls</head>

<p>Rules for passing parameters to operators are described in the relevant sections
<p>Rules for evaluating the operands of operators are described in the relevant sections
of <bibref ref="xquery-40"/> and <bibref ref="xpath-40"/>. For example, the rules for
passing parameters to arithmetic operators are described in <xspecref spec="XP31" ref="id-arithmetic"/>. Specifically, rules for parameters of
evaluating the operands of arithmetic operators are described in <xspecref spec="XP31" ref="id-arithmetic"/>.
Specifically, rules for parameters of
type <code>xs:untypedAtomic</code> and the empty sequence are specified in this section.</p>
<p>As is customary, the parameter type name indicates that the function or operator
accepts arguments of that type, or types derived from it, in that position. This
is called <emph>subtype substitution</emph> (See <xspecref spec="XP31" ref="id-sequencetype-matching"/>). In addition, numeric type instances and
instances of type <code>xs:anyURI</code> can be promoted to produce an argument
of the required type. (See <xspecref spec="XP31" ref="promotion"/>).</p>
<olist>
<item>
<p><emph>Subtype Substitution</emph>: A derived type may substitute for
its base type. In particular, <code>xs:integer</code> may be used
where <code>xs:decimal</code> is expected.</p>
</item>
<item>
<p><emph>Numeric Type Promotion</emph>: <code>xs:decimal</code> may be
promoted to <code>xs:float</code> or <code>xs:double</code>.
Promotion to <code>xs:double</code> should be done directly, not via
<code>xs:float</code>, to avoid loss of precision.</p>
</item>
<item>
<p><emph>anyURI Type Promotion</emph>: A value of
type <code>xs:anyURI</code> can be promoted to the
type <code>xs:string</code>. </p>
</item>
</olist>
<p>For function calls, the required type of an argument is defined in the function
signature of each function, and the way in which a supplied value is converted to the
required type (or rejected if it cannot be converted) is defined by the
<xtermref spec="XP40" ref="dt-coercion-rules"/>.</p>



<p>Some functions accept a single value or the empty sequence as an argument and
some may return a single value or the empty sequence. This is indicated in the
Expand Down Expand Up @@ -1655,10 +1639,8 @@ This differs from <bibref ref="xmlschema-2"/>, which defines
The exceptions are <code>op:numeric-divide</code>, which returns
an <code>xs:decimal</code> if called with two <code>xs:integer</code> operands,
and <code>op:numeric-integer-divide</code> which always returns an <code>xs:integer</code>.</p>
<p>If the two operands of an arithmetic expression are not of the same type, <emph>subtype substitution</emph>
and <emph>numeric type promotion</emph> are used to obtain two operands of the
same type. <xspecref spec="XP31" ref="promotion"/> and <xspecref spec="XP31" ref="mapping"/> describe the semantics of these operations in
detail. </p>
<p>If the two operands of an arithmetic expression are not of the same type, they
may be converted to a common type as described in <xspecref spec="XP40" ref="id-arithmetic-expressions"/>. </p>
<p>The result type of operations depends on their argument datatypes and is defined
in the following table:</p>
<table role="no-code-break data">
Expand Down Expand Up @@ -1735,7 +1717,7 @@ This differs from <bibref ref="xmlschema-2"/>, which defines
</tr>
</tbody>
</table>
<p>These rules define any operation on any pair of arithmetic types. Consider the
<!--<p>These rules define any operation on any pair of arithmetic types. Consider the
following example:</p>
<eg xml:space="preserve"><![CDATA[op:operation(xs:int, xs:double) => op:operation(xs:double, xs:double)]]></eg>
<p>For this operation, <code>xs:int</code> must be converted to
Expand All @@ -1755,7 +1737,7 @@ This differs from <bibref ref="xmlschema-2"/>, which defines
<code>fenceHeight</code> can be substituted for its base type
<code>height</code> and <code>height</code> can be substituted for its base type
<code>xs:integer</code>. </p>

-->
<p>The basic rules for addition, subtraction, and multiplication
of ordinary numbers are not set out in this specification; they are taken as given. In the case of <code>xs:double</code>
and <code>xs:float</code> the rules are as defined in <bibref ref="ieee754-2019"/>. The rules for handling
Expand Down
4 changes: 2 additions & 2 deletions specifications/xquery-40/src/back-matter.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<div1 id="id-type-promotion-and-operator-mapping">
<!--<div1 id="id-type-promotion-and-operator-mapping">
<head>Type Promotion and Operator Mapping</head>
<div2 id="promotion">
Expand Down Expand Up @@ -315,7 +315,7 @@ operand must be of type <code>xs:gDay</code>.)</p>
</div2>
</div1>
</div1>-->


<div1 role="xquery" id="id-xq-context-components">
Expand Down
Loading

0 comments on commit 7c24c8e

Please sign in to comment.