Dear all,
I would like to make a case for the quo_rem() method to actually implement euclidean division when it makes sense, or to raise an exception when the result is not defined. After all, this is what it is **supposed** to do, at least according to the docstring in sage/ring/polynomial/polynomial_element.pyx :
"""
@coerce_binop
def quo_rem(self, other):
"""
Returns the quotient and remainder of the Euclidean division of
``self`` and ``other``.
Raises ZerodivisionError if ``other`` is zero. Raises ArithmeticError if ``other`` has
a nonunit leading coefficient.
"""
I personally think that this specification is correct and decent.
Presently, depending on the domain, quo_rem does not always behave the same, and not according to the same specification. Examples :
In ZZ[X] or ZZ[X,Y] :
-------
sage: R.<X> = ZZ[]
sage: (X^100).quo_rem(2*X+1)
(0, X^100)
---> Result is not defined, but quo_rem() does not complain. It tries to reduce "as much as possible".
in QQ[x][y] :
----------------
sage: P.<x> = QQ[]
sage: R.<y> = P[]
sage: f = R.random_element(10)
sage: g = y^5+R.random_element(5)
sage: q,r = f.quo_rem(g)
sage: f == q*g + r
True
sage: g = x*y^5
sage: f.quo_rem(g)
Traceback (most recent call last):
...
ArithmeticError: Nonunit leading coefficient
---> quo_rem() complains when result is not defined.
So, I suggest that :
a) we stick to the spec (what happens in QQ[x][y]).
b) we fix the cases like ZZ[X] that do not stick to the spec
c) we make sure, eventually by adding a "reduce" method or something like that, that the previous behavior is still available somehow.
I am willing to implement these changes. Do we agree on this?