I've already been working on the issue for several days. I've created my own example:
In [9]: apart((x+y)/(2*x-y), x)
Out[9]: 0
The problem is that a domain of a fraction is identified as a ZZ[y] in this example. However it has to be QQ[y] for an apart to happen.
Generally, the division for polynomials is done using a DMP and this seems to work absolutely correct, however when the result is converted to a polynomial, non-integers (e.g. 1/2 and 3/2) are considered to be 0.
def to_field(f):
"""Make the ground domain a field. """
return f.convert(f.dom.get_field())
I'm trying to compare two different expressions: (x+1)/(2*x-4) and (x+y)/(2*x-y) and apart them on x. The differences appear while converting a Ring to a Field: `get_field(self)` is different for each class.
It simply returns QQ for the IntegerRing, which is correct, while for PolynomialRing the code is more complicated. It initializes a new PolyRing class, which preprocesses domain according to it’s options and returns a new class: Rational function field in y over ZZ with lex order. So the Ring ZZ[x] is converted to a ZZ(x) field. But this way the division will never happen correctly, if I'm right.
If I manually change the automatically detected domain to a QQ[y], apart functions works fine, however I do not pass some tests, e.g.
assert ZZ[x].get_field() == ZZ.frac_field(x)