On Tue, Mar 10, 2009 at 06:27:41PM -0700, Robert Bradshaw wrote:
> Currently the rule is that if you can do arithmetic between two  
> elements, you can compare them. 

Ok, I am not used to it, but this seems fair enough.

> Membership code is something entirely different.
> 
> > I typically write things like:
> >
> >     class MyParent
> >        def bla(self, x)
> >            assert x in self
> >            ...
> >
> > I really mean that x should be an element of self; not something that
> > could be converted into it.
> 
> Membership is much more lenient than coercion, for example, I would  
> be more worried if the following returned False
> 
> sage: 4/2 in ZZ
> True

Good example. Yes, finding the right balance is tricky (in MuPAD 4/2
*was* an integer).

I guess it all boils down to what are the convention for membership
testing, and how much freedom one has in implementing it.

Here are some typical options:

(1) x is in P if there is an element of P that is equal to x under ==
    or if x is already an element of self (this is the doc of
    __contains__ in Parent; is this a fixed rule engraved in the
    marble for every Parent?)

(2) x is in P if P(x) raises no error (this is the current default
    implementation in Parent)

(3) x is in P if it can be coerced into P (which could be implemented
    by just testing for the existence of a coercion, without actually
    applying it).

(4) x is in P if x.parent() = P


(1) is non trivial to implement. In principle, the __contains__
    function of ZZ should be able to handle all parents, now and in
    the future, into which there is a natural embedding of ZZ.

(2) seems completely off balance to me. Being able to construct a P
    from some data does not convey any mathematical link between that
    data and P.

(3) sounds reasonable, at least as a widely used default
    implementation. And possibly with a couple well marked exceptions
    for the really common cases like 4/2 in ZZ, to be introduced on a
    case by case basis when really it feels unnatural without them.

I personally lean for (4), but am ready to call myself an extremist on
this one.


> > Just yesterday, I lost 1 hour around this because membership testing
> > for a Weyl group ultimately led to listing all the elements of the
> > group. Which is problematic for an infinite group. And it was not easy
> > to straighten this up cleanly.
> 
> I'm not sure how a more stringent default "in" or comparison operator  
> would have helped here.

It's a long a story. But to make it short, with option (3) and with
some more stringent conversion rules, Sage would not have tried to
convert my WeylGroup(["A", 4]) element into a matrix and then into W=
WeylGroup(["A", 3, 1]) to finally compare it with all elements of W.

> > In short: for < = in, if it was just me, I would only use the most
> > absolutely trivial coercions. And in particular avoid there all the
> > coercions that involve projections and not embedding (like Z -> Z/nZ)

> I would like to avoid having a whole hierarchy of coercions, some of  
> which are used in some cases, others in other cases. People have  
> enough trouble understanding the system as it is.

I definitely see your point. Well, without introducing a hierarchy,
there is this natural notion of invertible coercions (strongly
connected components in the conversion graph). But that would not have
helped anyway for 4/2 in ZZ. Here it's more about a notion of partial
inverse for the canonical coercion from ZZ into QQ. It probably would
be over engineering to introduce it.

Cheers,
                                Nicolas
--
Nicolas M. ThiƩry "Isil" <nthi...@users.sf.net>
http://Nicolas.Thiery.name/

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to