Hello, > So it seems that sage.categories.pushout.pushout(Zmod(m), Zmod(n)) is > > Zmod(gcd(m,n)) unless m and n are coprime, in which case it raises an > error. > > > > This looks like a rather inconsistent choice to me. > > I agree, and anyone who knows enough to ever type "pushout" will > certainly not be happy.
I agree too; I don't know why "pushout" raises an error if m, n are coprime instead of returning the zero ring (just to make Mod(1, m) == Mod(1, n) evaluate to False?), but it is inconsistent and hopefully unnecessary. The code gives no good reason, just the following comment: # quotient by gcd would result in the trivial ring/group/... # Rather than create the zero ring, we claim they can't be merged On the otherhand, will anyone be happy if for > coprime m and n, every comparison Mod(a,m)==Mod(b,n) is True since the > only place they can be compared is the trivial ring? > It is already a bit dubious to require that two ring elements be equal if there is _some_ common non-zero ring that both of them can be coerced into; I don't see why Mod(a,m) == Mod(b,n) should be True just because a and b happen to be equal mod gcd(m,n) when that gcd is smaller than both m and n. I don't know if Sage uses exactly the same rules to find a common parent for comparison as it does for arithmetic operations, but it certainly looks like that is the case. I could imagine stricter rules for finding such a parent for comparison. An algorithm that at least makes my list of examples work is the following: 1) to evaluate "a == b": if A (resp. B) is the parent of a (resp. b) and P is the push-out of A and B (tensor product in the case of rings), then "a == b" yields True if and only if the images of a, b in P are equal *and* at least one of A, B maps injectively to P >> sage: Mod(1, 3) == ZZ(1) > >> True # with P = Zmod(3) > >> sage: Mod(1, 3) == QQ(1) > >> False # P is the zero ring > >> sage: Mod(1, 3) == Mod(1, 4) > >> False # P is the zero ring > >> sage: Mod(1,3) == Mod(1, 6) > >> True # P = Zmod(3) > >> sage: Mod(2, 6)==Mod(4, 8) > >> False # P = Zmod(2) > >> sage: 2/1 in ZZ > >> True # P = QQ > 2) to evaluate "a in B": if A is the parent of a, and P is the push-out of A and B, then "a in B" yields True if and only if the following hold: -- a can be converted into an element of B, say b = B(a); -- the images of a, b in P are equal *and* B maps injectively into P (similar to rule 1 above, but asymmetric w.r.t. A, B). >> sage: Mod(3, 5) in ZZ > >> False # P = Zmod(5) > >> sage: Mod(1,3) in Zmod(6) > >> False # P = Zmod(3) > >> sage: Mod(2,4) in Zmod(6) > >> False # P = Zmod(2) > Peter -- 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/groups/opt_out.