On Wed, Mar 11, 2009 at 10:07:35AM -0800, Carl Witty wrote:
> 
> On Tue, Mar 10, 2009 at 11:05 PM, Nicolas M. Thiery
> <nicolas.thi...@u-psud.fr> wrote:
> > 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.
> 
> Where did you get (2)?  That's not what the implementation in Parent
> does.  (Actually, the implementation in Parent is trying to implement
> (1), and doing a pretty good job.  It boils down to "x in ZZ" if "x ==
> ZZ(x)", where TypeError and ValueError exceptions are caught and
> translate to False.)

Oh, right. I misread the code. Good. One option that we don't have to
consider any more.

> I dislike the idea of exceptions (from (3)); I prefer the current
> situation, where there's a general rule that applies everywhere and
> is simple enough to be memorized, even if the general rule isn't
> exactly what you want always. Once you start adding exceptions "on a
> case by case basis", it would be really easy to get a rule that was
> too complicated to memorize... and if you can't remember what a
> function does, it's pretty much useless.

Yes, I also dislike exceptions. The rules should be as uniform as
possible. I was thinking really really really rare exceptions. Maybe
just that particular case 2/2 in ZZ.

> If you want (4), I think you should just write x.parent() == P (or if
> you know that P is unique, x.parent() is P).

Yup. The question is: am I allowed to do it?

> The strongly connected components in the conversion graph are huge.
> Did you mean strongly connected components in the coercion graph?

Oops, yes, sorry.

> There shouldn't be any of those; a coercion should only exist A->B
> or B->A, but not both.

See Florent's e-mail.


> Here's my best effort so far:
> 
> Coercions and conversions can be marked "safe" (need a better word for
> this).  A safe coercion/conversion does not change the mathematical or
> computational meaning (need a better definition); at a minimum, a safe
> coercion/conversion is invertible where it is defined.  A safe
> conversion need not be defined on the entire domain.
> 
> Here's some examples to hopefully clarify:
> 
> safe:
> ZZ -> QQ
> QQ -> ZZ
> RealField(20) -> RealField(50)
> ZZ -> ZZ['x']
> ZZ['x'] -> ZZ
> RealField(20) -> RealIntervalField(20)
> 
> unsafe:
> ZZ -> GF(5)
> GF(5) -> ZZ
> RealField(50) -> RealField(20)
> RealField(20) -> QQ
> QQ -> RealField(20)
> 
> Then "x in P" means that there is a safe conversion from the parent of
> x to P.  If this is actually a coercion, then you don't even have to
> run it; if it's a conversion, then you do have to run it, to test that
> the conversion is defined on x.  "x == y", "x<y" will find a safe
> coercion to a common parent if one exists; otherwise it will find a
> safe conversion.  If a conversion is used that fails, then the
> comparison is false.

Hmm. I have to think about it. For the moment, the only think I am
sure of: coercions should *always* be safe.

One use case: let S is the abstract ring of symmetric functions
(sorry, my pet example) and S.p and S.e are two concrete parents for
it (corresponding to the powersum and the elementary basis).

I certainly want coercions S.p <-> S.e, and they are safe.

On the other hand, I would not be quite convinced by:

        sage: S.p.one == S.e.one
        True
        sage: S.p.one in S.e
        True

Because S.e is mathematically defined as "the ring of symmetric
functions, expanded in the elementary basis". S.p does not match this
definition.

> I like this design better on some days than others :)  I'm not sure
> it's better than the current status (it fixes some of the annoyances
> in the current system, but I'm not sure what new annoyances would pop
> up with the new design); I'm also not convinced it's simple enough to
> memorize, and I don't know how much work it would be to change.
> (Changing the meaning of equality is a little scary; I'm not sure how
> much code might depend on subtleties of the current definition.)

Isn't it?

Thanks for your comments!

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