Need help with coercion

5 views
Skip to first unread message

Volker Braun

unread,
Jul 7, 2010, 2:30:15 PM7/7/10
to sage-devel
While trying to subclass QuotientRing, I noticed that this class does
not follow the coercion model: It overrides __call__ and _coerce_impl,
which the reference manual frowns upon. So I tried to change
QuotientRing to work via _coerce_map_from_ and _element_constructor_
(see first_attempt.patch at http://trac.sagemath.org/sage_trac/ticket/9429).
That ends up working for QuotientRings, but apparently messes up
coercion for everything else:

sage: FF = FiniteField(7)
sage: P.<x> = PolynomialRing(FiniteField(7))
sage: x+1
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)

/home/vbraun/opt/sage-4.5.alpha1/devel/sage-main/<ipython console> in
<module>()

/home/vbraun/Sage/sage/local/lib/python2.6/site-packages/sage/
structure/element.so in sage.structure.element.RingElement.__add__
(sage/structure/element.c:10876)()

/home/vbraun/Sage/sage/local/lib/python2.6/site-packages/sage/
structure/coerce.so in
sage.structure.coerce.CoercionModel_cache_maps.bin_op (sage/structure/
coerce.c:6966)()

TypeError: unsupported operand parent(s) for '+': 'Univariate
Polynomial Ring in x over Finite Field of size 7' and 'Integer Ring'

Note that I neither touched finite fields nor polynomial rings, I only
changed QuotientRing. Moreover, the coercion model believes that it
should work and no coercion to any quotient ring is involved:

sage: cm = sage.structure.element.get_coercion_model()
sage: cm.explain(P, ZZ, operator.add)
Coercion on right operand via
Composite map:
From: Integer Ring
To: Univariate Polynomial Ring in x over Finite Field of size
7
Defn: Conversion map:
From: Integer Ring
To: Finite Field of size 7
then
Polynomial base injection morphism:
From: Finite Field of size 7
To: Univariate Polynomial Ring in x over Finite Field
of size 7
Arithmetic performed after coercions.
Result lives in Univariate Polynomial Ring in x over Finite Field of
size 7
Univariate Polynomial Ring in x over Finite Field of size 7

Can somebody who is more familiar with the coercion tell me what I am
doing wrong?

Volker

Simon King

unread,
Jul 7, 2010, 4:51:12 PM7/7/10
to sage-devel
Hi Volker!

On 7 Jul., 20:30, Volker Braun <vbraun.n...@gmail.com> wrote:
> sage: FF = FiniteField(7)
> sage: P.<x> = PolynomialRing(FiniteField(7))
> sage: x+1

Apparently the problem is in the _element_constructor_:

sage: P(1)
...
/home/king/SAGE/sage-4.4.2/local/lib/python2.6/site-packages/sage/
rings/polynomial/polynomial_ring.pyc in _element_constructor_(self, x,
check, is_gen, construct, **kwds)
281 elif P == self.base_ring():
282 return C(self, [x], check=True, is_gen=False,
--> 283 construct=construct)
284 elif self.base_ring().has_coerce_map_from(P):
285 return C(self, [x], check=True, is_gen=False,
...

Or is it?
sage: P._element_constructor_(1)
_element_constructor_(Finite Field of size 7, 0)
1

Strange.

Best regards,
Simon

Andrey Novoseltsev

unread,
Jul 10, 2010, 8:29:41 PM7/10/10
to sage-devel
So - what's going on in this example? _element_constructor_ is
improperly bound so that a wrong version gets called?..

Andrey

Simon King

unread,
Jul 11, 2010, 4:53:12 AM7/11/10
to sage-devel
On 11 Jul., 02:29, Andrey Novoseltsev <novos...@gmail.com> wrote:
> So - what's going on in this example? _element_constructor_ is
> improperly bound so that a wrong version gets called?..

I don't think so.I tried to insert some print statements in the
element constructor, and it seems that the right constructor *is*
called. So, I got soon rather puzzled as well.

Cheers,
Simon

Robert Bradshaw

unread,
Jul 13, 2010, 12:51:36 AM7/13/10
to sage-...@googlegroups.com
On Wed, Jul 7, 2010 at 11:30 AM, Volker Braun <vbrau...@gmail.com> wrote:
> While trying to subclass QuotientRing, I noticed that this class does
> not follow the coercion model: It overrides __call__ and _coerce_impl,
> which the reference manual frowns upon.

Yes. QuotientRing was implemented ages before the new coercion model
came into the scene. Unfortunately, a lot of stuff inherits from it,
so fixing it may be non-trivial. (Sorry this doesn't really answer
your question as to what's going wrong.)

What should have happened is that QuotientRing should be an abstract
class, and with subclasses QuotientRingGeneric and
FiniteField/IntegerModRing/etc. as the latter end up
ignoring/subverting the implementation of the former. This would make
things like this much easier to change.

- Robert

Volker Braun

unread,
Jul 13, 2010, 5:35:44 PM7/13/10
to sage-devel
I see, there is an inheritance chain

QuotientRing_generic -> IntegerModRing_generic ->
FiniteField_prime_modn

and they all circumvent the "official" coercion model. That at least
explains why polynomials over finite fields break when changing
QuotientRing_generic!

Volker

Reply all
Reply to author
Forward
0 new messages