Hi William,

On 7 Sep., 22:27, William Stein <wst...@gmail.com> wrote:
> > In other words, I and J are equal, but have different hash. Actually,
> > I think it is a bug that hash(I) does not result in a TypeError.
>
> It's a bug that hash isn't canonical.    One should compute a standard
> form for I before hashing it.   At least this is what happens with
> ideals of rings of integers of number fields.  (I'm not claiming that
> hash is good -- it's something dumb like hashing the Pari HNF string,
> but still it is well defined.)
> ...
> I good compromise may be the following.  When creating a quotient
> ring, compute a standard form for the ideal.  Then when testing
> equality of two quotient rings, the whole issue we're talking about
> vanishes.  If you're going to do any nontrivial arithmetic in the
> quotient ring, you'll *need* this standard form anyways.

That's a good point. But:...

>  So just
> compute it up front.  In a multivariate poly ring it would be computed
> via something like his:
>
>         self.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
>
> (code copied from the __cmp__ method.)  The point is that degrevlex
> GB's are faster to compute than wrt other term orders... and for our
> purposes a GB wrt any term order suffices.

... if you want to do any nontrivial arithmetic in the quotient ring,
you are likely to want to work with a Gröbner basis *for the given
term order of the polynomial ring*. And even degrevlex Gröbner bases
are often enough difficult to compute.

Moreover, one must not forget that we want to create quotient rings
not only for ideals in polynomial rings. See #11068: Technically, we
can do computations in the quotient ring as soon as the ideal has a
method I.reduce(x) that returns a normal form of x with respect to I.

But in addition to I.reduce(x), we may consider to request another
method:
 * We could introduce a new method of ideals called, say,
I.normal_form(), returning some hashable object.
 * Comparison of ideals I,J should be reduced to I.ring()==J.ring()
and I.normal_form()==J.normal_form().
 * hash(I) should return hash(I.normal_form()).
 * By default, I.normal_form() just returns the given generators of I
as a tuple (or polynomial sequence?). Hence, for general ideals
(without the possibility to compute Gröbner bases), equality of ideals
becomes equality of generator lists
 * For some types of ideals, I.normal_form() returns a "proper" normal
form. So, for polynomial ideals, it returns an ordered reduced Gröbner
basis. In rings of integers of number fields, it returns the pari HNF
string.

It seems better to me to have a general __cmp__ method for *all*
ideals and implement a normal_form method, than to have different
__cmp__ for all types of ideals.

And then, uniqueness of quotient rings could easily be implemented,
based on R.quo(I,names1)==S.quo(J,names2) <=> R==S and I==J and
names1==names2.

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