<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>2789</bug_id>
          
          <creation_ts>2006-02-01 12:45:23 +0000</creation_ts>
          <short_desc>Substitutability of duration subtypes</short_desc>
          <delta_ts>2006-03-04 00:24:53 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>XPath / XQuery / XSLT</product>
          <component>Functions and Operators 1.0</component>
          <version>Candidate Recommendation</version>
          <rep_platform>PC</rep_platform>
          <op_sys>Windows XP</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Michael Kay">mike</reporter>
          <assigned_to name="Ashok Malhotra">ashok.malhotra</assigned_to>
          
          
          <qa_contact name="Mailing list for public feedback on specs from XSL and XML Query WGs">public-qt-comments</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>8079</commentid>
    <comment_count>0</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-01 12:45:24 +0000</bug_when>
    <thetext>Frans Englich posted as follows on the mulberry xsl-list yesterday:

&lt;quote&gt;
Saxon 8.6 fails this expression with XPTY0004, &quot;Cannot compare 
xdt:yearMonthDuration to xs:duration&quot;:

xdt:yearMonthDuration(&quot;P200Y2M&quot;) eq xs:duration(&quot;P200Y2M&quot;)


The XPath 2.0 book specifies these operators:

A eq B  xdt:yearMonthDuration     xdt:yearMonthDuration  
A eq B  xdt:dayTimeDuration  	  xdt:dayTimeDuration  
A eq B  xs:duration               xs:duration

It also says this:

&lt;quote&gt;
Any operator listed in the operator mapping tables may be validly applied to 
an operand of type AT if the table calls for an operand of type ET and 
type-matches(ET, AT) is true (see 2.5.4 SequenceType Matching). For example, 
a table entry indicates that the gt operator may be applied to two xs:date 
operands, returning xs:boolean. Therefore, the gt operator may also be 
applied to two (possibly different) subtypes of xs:date, also returning 
xs:boolean.
&lt;/quote&gt;

Doesn&apos;t type-matches(xs:duration, xdt:yearMonthDuration) hold true? My point 
being that the expression should succeed because xdt:yearMonthDuration is a 
subtype of xs:duration and that the xs:duration-eq operator therefore can be 
applied. If that is the case, which I doubt, the eq/ne operators for the two 
XDT durations are redudant, since the xs:duration-eq/ne operators covers 
them.

What clause in any of the specifications disallow the above operand 
combination? (and the others variations by the same principle)
&lt;/quote&gt;

I think Frans has a good point here. op:duration-equal is defined as

if (cast as xdt:yearMonthDuration ($arg1) eq
      cast as xdt:yearMonthDuration($arg2) 
   and
      cast as xdt:dayTimeDuration($arg1) eq 
      cast as xdt:dayTimeDuration ($arg2)) return fn:true()
  else return fn:false()

and this produces the correct result for any combination of duration,
dayTimeDuration, and yearMonthDuration.

So I think we should remove the four lines in the operator mapping table that
define eq and ne operations between subtypes of duration, and the corresponding
functions op:dayTimeDuration-equal and op:yearMonthDuration-equal.

Michael Kay</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8080</commentid>
    <comment_count>1</comment_count>
    <who name="Frans Englich">frans.englich</who>
    <bug_when>2006-02-01 13:53:39 +0000</bug_when>
    <thetext>   
I thought some more about it, and the current situation is a bit of a can of   
worms, I&apos;d say. Consider the following expression:   
   
xs:duration(xdt:dayTimeDuration(&quot;P365D&quot;))   
       eq   
xs:duration(xdt:yearMonthDuration(&quot;P1Y&quot;))   
   
   
From what I can tell, the validity of this expression depends on whether the   
dynamic types(xdt:dayTimeDuration/xdt:yearMonthDuration) or the static   
types(xs:duration/xs:duration) are used for the operator lookup. Perhaps,  
behavior could in practice become implementation dependent, considering the  
freedom implementations have in handling the types of values(subtype  
substitution, for example). The essence seems to be that in the case of the  
duration operators one can&apos;t rely on the very primitive base type(which  
one can in all other cases), but that a sub-type/dynamic type might be of  
importance. But yes, the solution Michael proposed seems to solve all this.  
  
Also, the pseudo function in op:duration-equal can be simplified into:   
   
return cast as xdt:yearMonthDuration($arg1) eq   
       cast as xdt:yearMonthDuration($arg2)    
                and   
       cast as xdt:dayTimeDuration($arg1) eq    
       cast as xdt:dayTimeDuration($arg2)  
  
It is less code(the if-expression was removed), but, of course, that doesn&apos;t  
necessarily mean readability is improved.  
   
  
Frans   
   
  
  </thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8081</commentid>
    <comment_count>2</comment_count>
    <who name="Michael Rys">mrys</who>
    <bug_when>2006-02-01 15:05:55 +0000</bug_when>
    <thetext>In the expression

xs:duration(xdt:dayTimeDuration(&quot;P365D&quot;))   
       eq   
xs:duration(xdt:yearMonthDuration(&quot;P1Y&quot;))   

both the static and dynamic type of the two values will be xs:duration (the 
cast changes the dynamic type as well). So I do not see your problem....
</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8085</commentid>
    <comment_count>3</comment_count>
    <who name="Frans Englich">frans.englich</who>
    <bug_when>2006-02-01 15:58:26 +0000</bug_when>
    <thetext>     
Yes Rys, I think you are right.    
    
I don&apos;t know your reasoning, but from what I can tell a cast expression can    
return a value whose type is more specific than the static one(from the 
definition of dynamic type). However, the reason why that doesn&apos;t apply to this 
particular case of xs:duration/xdt:dayTimeDuration is that the relevant 
sections in F&amp;O special case those; xdt:dayTimeDuration isn&apos;t treated as a 
xs:duration value.    
    
Curiosity: my conclusion is that the expression in comment #1 triggers a   
bug in Saxon, but when Saxon implements what likely is the result of this   
report(the eq ops for xdt:durations are removed) the bug will go away.   
    
    
Frans   
   
     </thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8087</commentid>
    <comment_count>4</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-01 18:05:49 +0000</bug_when>
    <thetext>The Saxon problem is off-topic for this list, but is now fixed.

Michael Kay</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8088</commentid>
    <comment_count>5</comment_count>
    <who name="Michael Rys">mrys</who>
    <bug_when>2006-02-01 18:47:00 +0000</bug_when>
    <thetext>&quot;I don&apos;t know your reasoning, but from what I can tell a cast expression can 
return a value whose type is more specific than the static one(from the 
definition of dynamic type).&quot;

Sorry, but a cast cannot return a more specific dynamic type than the static 
type. Casting is actually changing the dynamic type and transforms the value 
from one type&apos;s value space to another type&apos;s value space.

&quot;treat as&quot; does not change the dynamic type...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8089</commentid>
    <comment_count>6</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-01 19:17:43 +0000</bug_when>
    <thetext>In discussion it emerged (i.e., Mary Holstege noticed!) that we can&apos;t simply get
rid of op:yearMonthDuration-equal and op:dayTimeDuration-equal because the
definition of op:duration-equal invokes these functions implicitly. On the other
hand, the definition of equality on the two subtypes is not saying anything very
profound. So we probably need a revised definition of op:duration-equal, in
which case the other two functions can be dropped. I was actioned to write a
concrete proposal.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8091</commentid>
    <comment_count>7</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-01 19:36:32 +0000</bug_when>
    <thetext>&quot;Sorry, but a cast cannot return a more specific dynamic type than the static 
type.&quot;

I&apos;ve asked myself this question a number of times, and have come to the
conclusion that the result of a cast *can* be a subtype of the type requested. I
think it is a general property of our processing model (see 2.2.3.2) that
expressions can return a value whose dynamic type is a subtype of the type
implied by the static signature. For example the specification requires that the
result of 1+1 is an xs:integer, and an implementation that returns a value of
type xs:short conforms to this requirement because every xs:short is an
xs:integer. By the same reasoning it is acceptable for xs:int(1+1) to return a
value whose most specific type is xs:short. 

In Saxon, casting to a supertype is generally a no-op, and I believe this is
conformant.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8092</commentid>
    <comment_count>8</comment_count>
    <who name="Michael Rys">mrys</who>
    <bug_when>2006-02-01 19:45:31 +0000</bug_when>
    <thetext>I agree with your interpretation for arithmetic. But this is incorrect when 
casting. Casting per definition needs to change both the static and dynamic 
type. Casting up the type hierarchy is only a noop regarding the value 
transformation, but it has to change the type annotation...

Best regards
Michael</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8118</commentid>
    <comment_count>9</comment_count>
    <who name="Colin Adams">colin</who>
    <bug_when>2006-02-03 07:14:41 +0000</bug_when>
    <thetext>Note that 365D is not necessarilly equal to 1Y. Isn&apos;t this why we have two
distinct, non-overlapping sub-types of xs:duration in the first place?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8313</commentid>
    <comment_count>10</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-17 19:34:13 +0000</bug_when>
    <thetext>The discussion on this bug has explored some interesting side alleys, but I&apos;m
now trying to fulfil action A-288-29 by proposing changes for how durations
should be compared for equality (that is, eq and ne).

1. In the XPath/XQuery book, appendix B.2, delete the lines

A eq B 	xdt:yearMonthDuration 	xdt:yearMonthDuration 	
A eq B 	xdt:dayTimeDuration 	xdt:dayTimeDuration 
A ne B 	xdt:yearMonthDuration 	xdt:yearMonthDuration 	
A ne B 	xdt:dayTimeDuration 	xdt:dayTimeDuration	

2. In F+O delete sections 10.4.1 (op:yearMonthDuration-equal) and 10.4.4
(op:dayTimeDuration-equal)

3. To 10.4.7 op:duration-equal add after the second paragraph:

Note that this function (like any other) may be applied to arguments that are
derived from the types given in the function signature, including the two
subtypes xdt:dayTimeDuration and xdt:yearMonthDuration. With the exception of
the zero-length duration, no instance of xdt:dayTimeDuration will ever be equal
to an instance of xdt:yearMonthDuration.

Change the definition of the semantics of the function to read:

The semantics of the function are defined by the following expression:

xdt:yearMonthDuration($arg1) div xdt:yearMonthDuration(&apos;P1M&apos;)
 eq
xdt:yearMonthDuration($arg2) div xdt:yearMonthDuration(&apos;P1M&apos;)
    and
xdt:dayTimeDuration($arg1) div xdt:dayTimeDuration(&apos;PT1S&apos;)
 eq
xdt:dayTimeDuration($arg2) div xdt:dayTimeDuration(&apos;PT1S&apos;)

that is, the months and seconds components of the two durations are each equal.
 

To the examples, add

op:duration-equal(xdt:yearMonthDuration(&apos;P0Y&apos;), xdt:dayTimeDuration(&apos;PT0D&apos;))
returns true

op:duration-equal(xdt:yearMonthDuration(&apos;P1Y&apos;), xdt:dayTimeDuration(&apos;PT365D&apos;))
returns false</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8324</commentid>
    <comment_count>11</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-19 13:48:43 +0000</bug_when>
    <thetext>A minor addition to the proposal in comment #10:

Take the existing examples in sections 10.4.1 (op:yearMonthDuration-equal) and
10.4.4 (op:dayTimeDuration-equal) and add them to the revised section 10.4.7
op:duration-equal.

Michael Kay</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8325</commentid>
    <comment_count>12</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2006-02-19 13:55:29 +0000</bug_when>
    <thetext>Ignore comment #11. There are no existing examples in sections 10.4.1
(op:yearMonthDuration-equal) and 10.4.4 (op:dayTimeDuration-equal). Instead,
create some new examples:

op:duration-equal(xdt:yearMonthDuration(&apos;P2Y&apos;), xdt:yearMonthDuration(&apos;P24M&apos;))
returns true

op:duration-equal(xdt:dayTimeDuration(&apos;P10D&apos;), xdt:dayTimeDuration(&apos;PT240H&apos;))
returns true

op:duration-equal(xs:duration(&apos;P2Y0M0DT0H0M0S&apos;), xdt:yearMonthDuration(&apos;P24M&apos;))
returns true

op:duration-equal(xs:duration(&apos;P0Y0M10D&apos;), xdt:dayTimeDuration(&apos;PT240H&apos;))
returns true

Michael Kay
 </thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>8349</commentid>
    <comment_count>13</comment_count>
    <who name="Jim Melton">jim.melton</who>
    <bug_when>2006-02-21 16:38:47 +0000</bug_when>
    <thetext>We accepted the solution in comment #10 and #12.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>