This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 30317 - [XP31] Subtype rules for maps tested against functions conflict, because of zero-or-one cardinality in rule 35
Summary: [XP31] Subtype rules for maps tested against functions conflict, because of z...
Status: NEW
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XPath 3.1 (show other bugs)
Version: Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Jonathan Robie
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-08 20:52 UTC by Abel Braaksma
Modified: 2018-11-08 20:52 UTC (History)
0 users

See Also:


Attachments

Description Abel Braaksma 2018-11-08 20:52:59 UTC
A map item can have a value of type item()*. The rules for the subtype relationship (2.5.6.2 The judgement subtype-itemtype(Ai, Bi)) for maps state:

35. Ai is map(K, V), and Bi is function(xs:anyAtomicType) as V?. 

I see two issues with this statement:

1) Bi can be any subtype of function(xs:anyAtomicType) as V?. It doesn't have to be exactly that type.

2) It should be V*, not V?

Example: map{'a': (1, 2)} instance of function(xs:int) as item()?

a) Current rules

The map type of map(K, V) is: map(xs:string, xs:integer*)

The corresponding function then becomes: function(xs:anyAtomicType) as xs:integer?

Result of the type test would then be true, but that is clearly wrong, considering the co-variance of the return type.

b) If we replace V? with V* 

Now the rewrite is instead: function(xs:anyAtomicType) as xs:integer*

Now the instance-of expressions would correctly return true.

Saxon gets it right with the (b) scenario, even though that is at odds with the spec. I think (b) is the correct approach.

The same error can be found in section 2.5.5.8 Map Test.

I propose the rule be rewritten in an erratum, something along these lines:

<proposal>
35. Ai is map(K, V), and Bi is function(xs:anyAtomicType) as V* or a subtype thereof. 
</proposal>

This change would, however, lead to  map{'a': 1} being no longer a subtype of function(xs:int) as item()?

To fix that, we could write it as follows:

<proposal>
35. Ai is map(K, VA), and Bi is function(KB) as VB, where subtype(VA, VB) and subtype-itemtype(KB, xs:anyAtomicType).
</proposal>

This latter syntax would be more in line with rule 28, also on maps and emphasizes the co-variance/contra-variance rules that are in place here.