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
> <[email protected]> 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" <[email protected]>
http://Nicolas.Thiery.name/
--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---