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

Reply via email to