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 -~----------~----~----~----~------~----~------~--~---