This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
The XTTF does not agree on the result of the following query: fn:subsequence((1,2,3,4), -2, 4) The result is determined by the following two statements: "returns the items in $sourceString whose position $p obeys: fn:round($startingLoc) <= $p < fn:round($startingLoc) + fn:round($length)" which means -2 <= $p < 2 "If $startingLoc is zero or negative, the subsequence includes items from the beginning of the $sourceSeq." but it is not clear in which order the rules are applied to identify valid positions. We found two possible interpretations: 1. apply the second rule first and define the valid positions as 1 <= $p < 5 such that the result is "1 2 3 4", or 2. define the valid positions first as -2 <= $p < 2 and start with position 1, such that the result is "1". We have not reached agreement in the XQuery Test Task Force and ask the Working Group for clarification. On behalf of XTTF Andreas Behm
Normally the rules are interpreted in order as they appear in the document. So this should return "1". Best regards Michael
Section 1.4 says "For most functions there is an initial paragraph describing what the function does followed by semantic rules. These rules are meant to be followed in the order that they appear in this document." Thus, as Michael Rys has pointed out the result should be "1". I'm closing this issue.
That seems to imply that the "$startingLoc is zero or negative" rule would never be applied.
I think this is a case (there are many others in F+O) where the spec is trying to be too helpful, and where it doesn't distinguish clearly enough between rules and helpful remarks about the consequences of the rules. I think the sentence "If $startingLoc is zero or negative, the subsequence includes items from the beginning of the $sourceSeq." falls into the "helpful remark" category. It's an incomplete statement. Both the suggested answers (1,2,3,4) and (1) in fact have the property that the result includes items from the start of the input sequence, so this sentence doesn't help to decide which of these answers is right. There are other cases (for example subsequence((1,2), -10, 0) where the sentence is false - in this case the result doesn't include any items from the start of the input sequence. Personally, I would structure the specification of this function as: <quote> SUMMARY: Returns the contiguous sequence of items in the value of $sourceSeq beginning at the position indicated by the value of $startingLoc and continuing for the number of items indicated by the value of $length. RULES: In the two-argument case, returns the items in $sourceSeq whose position $p obeys: fn:round($startingLoc) le $p In the three-argument case, returns the items in $sourceSeq whose position $p obeys: fn:round($startingLoc) le $p and $p lt fn:round($startingLoc) + fn:round($length) NOTES If $sourceSeq is the empty sequence, the empty sequence is returned. If $startingLoc is zero or negative, the subsequence includes items from the beginning of the $sourceSeq. If $length is not specified, the subsequence includes items to the end of $sourceSeq. If $length is greater than the number of items in the value of $sourceSeq following $startingLoc, the subsequence includes items to the end of $sourceSeq. The first item of a sequence is located at position 1, not position 0. For detailed type semantics, see Section 7.2.11 The fn:subsequence functionFS </quote> Specifying it this way deals unambiguously and economically with awkward corner cases such as a position or length of infinity or NaN. (Note also, the current text has an incorrect reference to $sourceString)
On rereading this text, it occurs to me that there's nothing in the either the old or the new version that states unequivocally that the order of items in the result is the same as the order in the input (which I believe is true even in unordered mode). This can be fixed by changing the rules to: RULES In the two-argument case, returns $sourceSeq[fn:round($startingLoc) le position()] In the three-argument case, returns $sourceSeq[fn:round($startingLoc) le position() and position() lt fn:round($startingLoc) + fn:round($length)] Since we get many questions about it, it might also be worth adding a NOTE The reason the function accepts arguments of type xs:double is that many computations on untyped data return an xs:double result; and the reason for the rounding rules is to compensate for any imprecision in these floating-point computations.
The WGs decided on July 22, 2005 to improve the description of this function according to comments #4 and #5 by Michael Kay below.