Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Add more print statements for ring extension morphisms when broken
Browse files Browse the repository at this point in the history
  • Loading branch information
roed314 committed Feb 18, 2022
1 parent 8185765 commit 7624b5d
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/sage/rings/finite_rings/finite_field_relative.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def absolute_field(self, map=False, names=None):
Ring morphism:
From: Finite Field in b6 of size 3^6
To: Finite Field in z6 of size 3^6 over its base
Defn: b6 |--> (2*z2 + 1)*z6 + (2*z2 + 2)*z6^2
Defn: b6 |--> 1 + (2*z2 + 1)*z6 + (z2 + 1)*z6^2
sage: g
Canonical morphism:
From: Finite Field in z6 of size 3^6 over its base
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/homset.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def _element_constructor_(self, x, check=True, base_map=None):
sage: R.<x> = ZZ[]
sage: K.<a> = GF(7^2)
sage: L.<u> = K.extension(x^3 - 3)
sage: L.<u> = K.extension(x^3 - 3, absolute=False)
sage: phi = L.hom([u^7], base_map=K.frobenius_endomorphism())
sage: phi(u) == u^7
True
Expand Down
18 changes: 13 additions & 5 deletions src/sage/rings/ring_extension.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ from sage.rings.ring_extension_element cimport (
RingExtensionElement, RingExtensionFractionFieldElement, RingExtensionWithBasisElement)
from sage.rings.ring_extension_morphism cimport (
RingExtensionHomomorphism, RingExtensionBackendIsomorphism, RingExtensionBackendReverseIsomorphism,
are_equal_morphisms, MapFreeModuleToRelativeRing, MapRelativeRingToFreeModule)
are_different_morphisms, MapFreeModuleToRelativeRing, MapRelativeRingToFreeModule)
from sage.rings.ring_extension_conversion cimport (
backend_parent, backend_morphism, to_backend, from_backend)

Expand Down Expand Up @@ -612,9 +612,17 @@ cdef class RingExtension_generic(CommutativeAlgebra):
backend = (<RingExtension_generic>b)._backend
else:
backend = b
if ring.has_coerce_map_from(backend) and not are_equal_morphisms(f, None):
# TODO: find a better message
raise ValueError("exotic defining morphism between two rings in the tower; consider using another variable name")
if ring.has_coerce_map_from(backend):
differing = are_different_morphisms(f, None)
if differing:
# TODO: find a better message
msg = "exotic defining morphism between two rings in the tower; consider using another variable name\n"
for x, y, z in differing:
if isinstance(x, str):
msg += f" different {x}:\n {y}\n {z}"
else:
msg += f" f({x}) = {y}\n g({x}) = {z}\n"
raise ValueError(msg)

self.register_coercion(self._defining_morphism.__copy__())

Expand Down Expand Up @@ -1082,7 +1090,7 @@ cdef class RingExtension_generic(CommutativeAlgebra):
backend = self._backend.coerce_map_from(right._backend)
f = backend * backend_morphism(right._defining_morphism)
g = backend_morphism(self._defining_morphism * self._base.coerce_map_from(right._base))
if are_equal_morphisms(f, g):
if not are_different_morphisms(f, g):
return RingExtensionHomomorphism(right.Hom(self), backend)

def base(self):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/ring_extension_morphism.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from sage.rings.morphism cimport RingMap
from sage.rings.ring_extension_element cimport RingExtensionElement


cdef are_equal_morphisms(f, g)
cdef are_different_morphisms(f, g)


cdef class RingExtensionHomomorphism(RingMap):
Expand Down
72 changes: 52 additions & 20 deletions src/sage/rings/ring_extension_morphism.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ from sage.rings.ring_extension_conversion cimport backend_parent, backend_elemen


# I don't trust the operator ==
cdef are_equal_morphisms(f, g):
cdef are_different_morphisms(f, g):
r"""
Return ``True`` if ``f`` and ``g`` coincide on the
generators of the domain, ``False`` otherwise.
Return a list of triples encoding how ``f`` and ``g`` differ.
If they have different domains, return ``[("domain", domain(f), domain(g))]``
Otherwise, if they have different codomains, return ``[("codomain", codomain(f), codomain(g))]``.
Otherwise, return the list of triples ``(x, f(x), g(x))``
where `x` varies over the generators of the domain so that ``f(x) != g(x)``.
INPUT:
Expand Down Expand Up @@ -61,21 +65,26 @@ cdef are_equal_morphisms(f, g):
cdef CommutativeRing b
cdef tuple gens
if f is None and g is None:
return True
if f is None:
f, g = g, f
return []
elif f is None:
b = g.domain()
f = g.codomain().coerce_map_from(b)
else:
b = f.domain()
if g is None:
g = f.codomain().coerce_map_from(b)
else:
if b is not g.domain():
return [("domain", f.domain(), g.domain())]
elif f.codomain() is not g.codomain():
return [("codomain", f.codomain(), g.codomain())]
gens = tuple()
b = f.domain()
while b is not b._base:
gens += b.gens()
b = b._base
if g is None:
for x in gens:
if f(x) != x: return False
else:
for x in gens:
if f(x) != g(x): return False
return True
fvalues = [f(x) for x in gens]
gvalues = [g(x) for x in gens]
return [(x, y, z) for x, y, z in zip(gens, fvalues, gvalues) if y != z]


cdef class RingExtensionHomomorphism(RingMap):
Expand Down Expand Up @@ -203,9 +212,32 @@ cdef class RingExtensionHomomorphism(RingMap):
backend_base_map = coercion_morphism
else:
backend_base_map = backend_morphism(base_map)
if backend_base_map.domain() is not current_morphism.domain():
phi = backend_base_map.domain().coerce_map_from(current_morphism.domain())
if phi is None:
msg = "Cannot coerce base map into correct domain:\n"
msg += f" Domain is {backend_base_map.domain()}\n"
msg += f" Needs to be {current_morphism.domain()}"
raise ValueError(msg)
backend_base_map = backend_base_map * phi
if backend_base_map.codomain() is not current_morphism.codomain():
phi = current_morphism.codomain().coerce_map_from(backend_base_map.codomain())
if phi is None:
msg = "Cannot coerce base map into correct codomain:\n"
msg += f" Domain is {backend_base_map.codomain()}\n"
msg += f" Needs to be {current_morphism.codomain()}"
raise ValueError(msg)
backend_base_map = phi * backend_base_map
restriction_current_morphism = current_morphism * coercion_morphism
if not are_equal_morphisms(restriction_current_morphism, backend_base_map):
raise ValueError("images do not define a valid homomorphism")
differing = are_different_morphisms(restriction_current_morphism, backend_base_map)
if differing:
msg = "images do not define a valid homomorphism:\n"
for x, y, z in differing:
if isinstance(x, str):
msg += f" different {x}:\n {y}\n {z}"
else:
msg += f" f({x}) = {y}\n g({x}) = {z}\n"
raise ValueError(msg)
self._backend = current_morphism
self._im_gens = im_gens[:domain.ngens()]
if base is domain.base_ring():
Expand Down Expand Up @@ -334,8 +366,8 @@ cdef class RingExtensionHomomorphism(RingMap):
if base_map is None:
return None
if (codomain.has_coerce_map_from(base) and
are_equal_morphisms(backend_morphism(base_map),
backend_morphism(codomain.coerce_map_from(base)))):
not are_different_morphisms(backend_morphism(base_map),
backend_morphism(codomain.coerce_map_from(base)))):
return None
if base_map.codomain() is not self.codomain():
base_map = base_map.extend_codomain(self.codomain())
Expand Down Expand Up @@ -365,7 +397,7 @@ cdef class RingExtensionHomomorphism(RingMap):
sage: FrobL^6 == End(L).identity()
True
"""
eq = are_equal_morphisms(self._backend, backend_morphism(other))
eq = not are_different_morphisms(self._backend, backend_morphism(other))
if op == op_EQ:
return eq
if op == op_NE:
Expand Down Expand Up @@ -399,7 +431,7 @@ cdef class RingExtensionHomomorphism(RingMap):
"""
if self.domain() is not self.codomain():
return False
return are_equal_morphisms(self._backend, None)
return not are_different_morphisms(self._backend, None)

def is_injective(self):
r"""
Expand Down

0 comments on commit 7624b5d

Please sign in to comment.