#10496: The default call method of maps does not do as promised by the
documentation
-------------------------+--------------------------------------------------
   Reporter:  SimonKing  |       Owner:  robertwb        
       Type:  defect     |      Status:  new             
   Priority:  major      |   Milestone:  sage-4.6.2      
  Component:  coercion   |    Keywords:  generic call map
     Author:             |    Upstream:  N/A             
   Reviewer:             |      Merged:                  
Work_issues:             |  
-------------------------+--------------------------------------------------
 The documentation of `sage.categories.map.Map.__call__` states:
 {{{
 - If ``x`` can be coerced into the domain of ``self``, then the
   method ``_call_`` (single underscore) is called after
   coercion.
 - Otherwise, it is tried to call the method ``pushout`` to ``x``
   (which may be provided in subclasses); in that way, ``self``
   could be applied to objects like ideals.
 }}}

 However, in the code, we had
 {{{
             if not PY_TYPE_CHECK(x, Element):
                 return self._call_(x)
             elif (<Element>x)._parent is not self._domain:
                 try:
                     x = self._domain(x)
                 except TypeError:
                     try:
                         return self.pushforward(x)
                     except (TypeError, NotImplementedError):
                         raise ...

 }}}

 Hence, there is a typo in the documentation (it is pushforward, not
 pushout):

 1. If the argument is no element, one should expect that `pushforward`
 rather than `_call_` is called. This is a problem if the argument happens
 to be a sub-module. Sub-modules are no elements (this is incontrast to
 ideals). Hence, currently, module morphisms have to implement a custom
 `__call__` method.

 2. In contrast to the statement of the documentation, the code is only
 about conversion, but not about coercion. I think this is a problem, as in
 the following example. There is no coercion from the abstract number field
 to the embedded number field, but no error is raised when calling the
 coerce embedding of the embedded field with an element of the abstract
 field:
 {{{
   sage: K.<a>=NumberField(x^2-3,embedding=1)
   sage: L.<b>=NumberField(x^2-3)
   sage: K.has_coerce_map_from(L)
   False
   sage: K.coerce_embedding()(b)
   1.732050807568878?
 }}}

 3. I was told that in the `_call_` (single underscore) and
 `_call_with_args` methods one can assume that the argument belongs to the
 domain of the map. This is, however, not the case, since an argument that
 is not an element (like a python int, for example!) will not be converted
 into the domain before passing it to `_call_`.

 I propose the following:

  * If `parent(x)` does not coerce into the map's domain, `pushforward` is
 called on `x` together with the additional arguments. If it is not
 implemented or produces a `TypeError`, proceed with the next step.
  * Try to convert `x` into the domain; this is now either a coercion, or
 it is a back-up solution for the failing pushfoward. If the conversion
 fails, raise an error that mentions the pushforward method.
  * Call `_call_` resp. `_call_with_args`.

 There is a new doc test, demonstrating `_call_`, `_call_with_args` and
 `pushforward`. Apart from that, only small changes were needed in the
 doctests: Some error messages have changed.

 I have no idea about the proper component. I hope "coercion" is fine.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10496>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to