Hi Mark! Some of the problems are addressed at #8972, which needs work, but I have no time to work on it, I am afraid.
On 29 Mrz., 21:52, Mark Shimozono <msh...@math.vt.edu> wrote: > I encountered some weird behavior in LaurentPolynomialRing, such as > the nontransitivity of the '==' relation. Note that it is virtually impossible to have a transitive ==-relation that at the same time provides certain mathematical features that are wanted by most people. In the following explanations, I am talking about ring elements, not about symbolic expressions (if a and b are symbolic expressions, then a==b is a symbolic expression as well, i.e., no comparison is actually done in this case). If I recall correctly, a==b defaults to the following, where a is an element in some ring R and b is an element in some ring S, in general with R!=S: * Try to find a canonical ring X (call it the "pushout" of R and S) such that both R and S coerce into X, and X coerces into any ring Y into which R and S coerce. If Sage can not find such pushout, "a==b" returns False. * If X can be found, then "a==b" is exactly the same as "X(a)==X(b)". Examples: 2/1==2: 2/1 is a rational (R is QQ), 2 is an integer (S is ZZ). Both QQ and ZZ canonically coerce into QQ. hence, it is now tested whether 2/1==QQ(2), which is true. GF(3)(1)==1: The left argument is an element of the finite field R=GF(3), the right operand is an element of ZZ. ZZ canonically coerces into GF(3), and thus GF(3)==1 returns True. GF(2)(1)==1 returns True for the same reason. 1/1==ZZ['x'](1): Returns true, since Sage finds the pushout QQ['x'] for QQ and ZZ['x']. However, GF(2)(1)==GF(3)(1) returns False, because there is no pushout for R=GF(2) and S=GF(3). Conclusion: We have GF(2)(1)==1 and 1==GF(3)(1), but GF(2)(1)!=GF(3) (1). I think the general experience is that it is very useful to be able to compare elements of *different* rings, and we are willing to accept a lack of transitivity for comparisons in different rings (but we would not accept a lack of transitivity for comparisons in a *single* ring!). > Also, factoring in the fraction field caused an error. It is implemented by factoring numerator and denominator, see below; the problem is in factoring Laurent series. > I would like elements of the fraction field F of a Laurent polynomial > ring S > (say with base ring a field) to be able to tell if they are actually > in S. They should be. I guess it is addressed at #8972. > If R is the polynomial ring underlying S > then there should be a canonical isomorphism installed between F and > the fraction field K > of R. There *is* a coercion from K to F, but of course not in the opposite direction: sage: S.<x> = LaurentPolynomialRing(QQ) sage: F = S.fraction_field() sage: F Fraction Field of Univariate Laurent Polynomial Ring in x over Rational Field sage: R = S.polynomial_ring() sage: K = R.fraction_field() sage: F.has_coerce_map_from(K) True > sage: R.gen(0) == S.gen(0) > True ... because there is a coercion from R to S: sage: S.has_coerce_map_from(R) True > sage: 1/R.gen(0) == 1/S.gen(0) > True ... because there is a coercion from K to F (as above), and: sage: (1/R.gen(0)).parent() is K True sage: (1/S.gen(0)).parent() is F True > sage: 1/R.gen(0) == (S.gen(0))^(-1) > False Someone implemented 1/S.gen(0) different from (S.gen(0)^-1: sage: (S.gen(0)^-1).parent() is F False sage: (S.gen(0)^-1).parent() is S True In other words, if x in S and x^-1 can be interpreted as an element of S, then x^-1 returns an element of S (a Laurent polynomial) and not an element of the fraction field of S; but 1/x always belongs to the fraction field of S. That is one of the bugs addressed at #8972. Note that there is a coercion from S to F -- but: sage: F(S.gen(0)^-1) x^-1 sage: F(S.gen(0))^-1 1/x So, the two look different. However: sage: F(S.gen(0)^-1)==F(S.gen(0))^-1 True Hence, the default way of comparison of ring elements would imply that 1/R.gen(0) and (S.gen(0))^(-1) are equal -- but apparently someone overrode the default -- which I agree is a bug. > sage: R.gen(0)^(-1) in S > False There is no coercion from the fraction field of R into S: sage: S.has_coerce_map_from(FractionField(R)) False and also Sage can not find the pushout: sage: pushout(S, FractionField(R)) Traceback (most recent call last): ... CoercionException: ... Hence, the answer must be "False". > sage: S.gen(0)^(-1) in S > True Sure, since sage: (S.gen(0)^(-1)).parent() is S True by my remark above. > sage: 1/S.gen(0) in S > False Again, see above. > sage: (1/S.gen(0)).factor() > Traceback (most recent call last) > ... > AttributeError: 'sage.rings.integer.Integer' object has no attribute > 'dict' Strange. Have a look at the source code of the factor method of general fraction field elements: sage: s = (1/S.gen(0)) sage: s.parent() Fraction Field of Univariate Laurent Polynomial Ring in x over Rational Field sage: s.factor?? The last line will show you the source code, and you will see that it is attempted to factor numerator and denominator. As it turns out, the problem lies in the factorisation of Laurent series. Best regards, Simon -- To post to this group, send an email to sage-devel@googlegroups.com To unsubscribe from this group, send an email to sage-devel+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URL: http://www.sagemath.org