Hi!

I have a question on the coercion model. Assume that we have  two
rings R1,R2, so that there is no coercion from R1 to R2 and no
coercion from R2 to R1. The classical example is R1=QQ and R2=ZZ['t'].

Now let p1,p2 be an element of R1,R2, respectively. I want to multiply
them, the result living in a ring that has coercion maps from both R1
and R2 (in the classical  example, it is QQ['t']).

I read the relevant chapter in the reference manual and understood
that it suffices to provide p2 with a _r_action_ method to make p1*p2
work, and to provide p2 with a _l_action_ method to make p2*p1 work.
But apparently I am wrong, since I met an example where neither method
is called and an error is raised.

See below for an example.

So, what else is needed to achieve that _r_action_ and _l_action_ are
called?

Best regards,
Simon

Here is a small example session (sage-4.2.1), where the content of
test.py is below

sage: attach test.py
sage: R.<x,y,z> = FakeRing(ZZ)
sage: x*y
(x)*(y)
sage: R('bla')*x
(bla)*(x)
sage: R('bla')*x-y
((bla)*(x))-(y)
sage: 2*x
(2)*(x)
sage: x*2
(x)*(2)
sage: (1/2)*x
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for '*': 'Rational Field' and
'Fake ring over Integer Ring with generators x,y,z'

test.py:
from sage.all import CommutativeRing, CommutativeRingElement,
SageObject

class FakeElement(CommutativeRingElement):
    def __init__(self,parent,name):
        self._name = name
        CommutativeRingElement.__init__(self,parent)
    def __repr__(self):
        return self._name
    def _cmp_(self,other):
        return cmp(self._name,other._name)
    def _add_(self,other):
        return FakeElement(self.parent(), '('+self._name+')+
('+other._name+')')
    def _mul_(self,other):
        return FakeElement(self.parent(), '('+self._name+')*
('+other._name+')')
    def _sub_(self,other):
        return FakeElement(self.parent(), '('+self._name+')-
('+other._name+')')
    def _r_action_(self,other):
        print self,'acting on',other
        print other.parent()
        OUTP = FakeRing(other.base_ring(),self.parent()._names)
        return FakeElement(OUTP, '('+self._name+')*('+repr(other)+')')
    def _l_action_(self,other):
        print self,'acting on',other
        print other.parent()
        OUTP = FakeRing(other.base_ring(),self.parent()._names)
        return FakeElement(OUTP, '('+repr(other)+')*('+self._name+')')

class FakeRing(CommutativeRing):
    def __init__(self, R, names):
        CommutativeRing.__init__(self,base=R)
        self._names = names
        self._gens = [FakeElement(self, n) for n in names]
        self._populate_coercion_lists_()
    def __repr__(self):
        return 'Fake ring over %s with generators %s'%(repr
(self.base_ring()),','.join(self._names))

    def _element_constructor_(self, r):
        return FakeElement(self, str(r))

    def _coerce_map_from_(self, R):
        return self.base_ring().has_coerce_map_from(R)

    def an_element(self):
        return self.gen()

    def gen(self,i=None):
        if i is not None:
            return self._gens[i]
        return self._gens[0]

-- 
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to 
sage-support-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sage-support
URL: http://www.sagemath.org

Reply via email to