On Wed, Jun 11, 2014 at 12:42 AM, Marc Mezzarobba <m...@mezzarobba.net> wrote:
> Robert Bradshaw wrote:
>> So you would prefer
>>
>> sage: 4/2 == 2
>> False
>> sage: 4/2 + 0/1 == 2 + 0/1
>> True
>
> Definitely.
>
>> sage: R.<x> == ZZ[]
>> sage: (x-1) * (x+1) - x^2 + 1 == 0
>> False
>
> I certainly agree that being able to use "== 0" here is convenient.
>
> But having to write, say, eq(pol, 0) instead does not seem too high a
> price for consistency with the assumptions Python makes on equality. (Do
> not misunderstand me: if Sage had its own language, I would prefer to
> use == for the richest form of equality, and some other notation for the
> version consistent with hashing.)

In Python, 2 == 2.0 returns True. Sage simply has a richer number
system, but what we do is more consistent with Python than requiring
objects to be the same type/parent to compare equal.

> And IMHO your examples are not worse than
>
> sage: x = SR.var('x')
> sage: bool(arctan(1+abs(x)) == pi/2 - arctan(1/(1+abs(x))))
> False

Better returning True when the CAS isn't strong enough to prove
equality (which may well be most of the time).

> sage: R.<y> = QQ[]
> sage: R(0) == GF(2)(0)
> False

Yeah, that's sub-optimal. I've actually thought for a while it might
make sense to use the pullback rather than pushforward as a common
parent in which to do comparisons. That would make

sage: RR(pi) == pi
False
sage: RealField(10)(pi) == RealField(100)(pi)
False

but I do find

sage: GF(5)(-1) == -1
True
sage: Qp(5)(-1) == -1
True

to be handy (though might be worth sacrificing).

> sage: R(0) == 0 and 0 == GF(2)(0)
> True
>
> sage: {t.parent() for t in {R(42), 42}}
> {Integer Ring}
> sage: {t.parent() for t in {42, R(42)}}
> {Univariate Polynomial Ring in y over Rational Field}

Totally, just like Python's

{type(t) for t in {0, 0.0}} == {float}

Can you think of any reason you'd want to do this?

> sage: {42, QQbar(42)}
> {42, 42}
> sage: {42, SR(42)}
> {42}
> sage: {2^100, SR(2^100)}
> {1267650600228229401496703205376, 1267650600228229401496703205376}

Hash is not as good as it could/should be for large symbolic integers.
And for AA/QQbar.

> sage: eq = SR(GF(2)(0)) == SR(2); eq
> 0 == 2
> sage: bool(eq)
> True

Yeah, SR is weird. Especially with elements that don't embed into CC.

>> Note also that if GF(p)(1) != 1 !=
>> int(1) and is not an error then trivial looking code like
>>
>> def order(a, p):
>> """ return x such that a^x == p, naively """
>> if a == 0:
>> return infinity
>> else:
>> x = GF(p)(a)
>> count = 1
>> while x != 1:
>> x *= a
>> count += 1
>> return count
>>
>> has a really bad bug in it.
>
> Not that bad if x != 1 throws an exception. Besides, Java programmers
> have had a similar problem forever and can apparently live with it...

Yeah, and considered one of Java's big pitfalls, though when your
language doesn't allow operator overloading I suppose that's
consistent.

I might be OK with throwing an exception between really incomparable
elements, but marring equality to blindly abide by hash's standards
isn't the right thing to do IMHO. A (bad) alternative would be to
define

class Element:
    def __hash__(self):
        try:
            return hash(float(self))
        except:
            return 5077

Also, I think the typical usecase of objects being used as keys,
including in cached_method, is for objects of the same (or similar)
type.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to