Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix comparison for divisors of curves (and FormalSum commutativity) #37972

Merged
merged 22 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 28 additions & 2 deletions src/sage/schemes/generic/divisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from sage.misc.repr import repr_lincomb
from sage.misc.search import search
from sage.rings.integer_ring import ZZ
from sage.sets.set import Set
vincentmacri marked this conversation as resolved.
Show resolved Hide resolved
from sage.structure.formal_sum import FormalSum

from .morphism import is_SchemeMorphism
Expand Down Expand Up @@ -121,6 +122,29 @@ def is_Divisor(x):
class Divisor_generic(FormalSum):
r"""
A Divisor.

TESTS::

sage: E = EllipticCurve([1, 2])
sage: P = E(-1, 0)
sage: Q = E(1, 2)
sage: Pd = E.divisor(P)
sage: Qd = E.divisor(Q)
sage: Pd + Qd == Qd + Pd
True
sage: Pd != Qd
True
sage: C = EllipticCurve([2, 1])
sage: R = C(1, 2)
sage: Rd = C.divisor(R)
sage: Qd == Rd
False
sage: Rd == Qd
False
sage: Qd == (2 * (Qd * 1/2))
True
sage: Qd == 1/2 * Qd
False
"""

def __init__(self, v, parent, check=True, reduce=True):
Expand Down Expand Up @@ -363,14 +387,15 @@ def _repr_(self):
"""
return repr_lincomb([(tuple(I.gens()), c) for c, I in self])

def support(self):
def support(self) -> list:
"""
Return the support of this divisor, which is the set of points that
occur in this divisor with nonzero coefficients.

EXAMPLES::

sage: x,y = AffineSpace(2, GF(5), names='xy').gens()
sage: A = AffineSpace(2, GF(5), names='xy')
sage: x, y = A.gens()
sage: C = Curve(y^2 - x^9 - x)
sage: pts = C.rational_points(); pts
[(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)]
Expand All @@ -384,6 +409,7 @@ def support(self):
This checks that :issue:`10732` is fixed::

sage: R.<x, y, z> = GF(5)[]
sage: PS = ProjectiveSpace(R)
vincentmacri marked this conversation as resolved.
Show resolved Hide resolved
sage: C = Curve(x^7 + y^7 + z^7)
sage: pts = C.rational_points()
sage: D = C.divisor([(2, pts[0])])
Expand Down
27 changes: 27 additions & 0 deletions src/sage/schemes/generic/divisor_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,33 @@ def _element_constructor_(self, x, check=True, reduce=True):
else:
return Divisor_generic([(self.base_ring()(1), x)], check=False, reduce=False, parent=self)

def _coerce_map_from_(self, other):
r"""
Check if there is a coercion from ``other`` to ``self``.
This is used to prevent divisors on different schemes from comparing as equal to each other.
vincentmacri marked this conversation as resolved.
Show resolved Hide resolved

TESTS::

sage: C = EllipticCurve([2, 1])
sage: E = EllipticCurve([1, 2])
sage: C.divisor_group()._coerce_map_from_(E.divisor_group())
False
sage: E.divisor_group()._coerce_map_from_(C.divisor_group())
False
sage: E.divisor_group()._coerce_map_from_(E.divisor_group())
True
sage: C.divisor_group()._coerce_map_from_(C.divisor_group())
True
sage: D = 1/2 * E.divisor(E(1, 2))
sage: D.parent()._coerce_map_from_(E.divisor_group())
True
sage: E.divisor_group()._coerce_map_from_(D.parent())
False
"""
return (isinstance(other, DivisorGroup_generic)
and self.scheme() == other.scheme()
and super()._coerce_map_from_(other))

def scheme(self):
r"""
Return the scheme supporting the divisors.
Expand Down
18 changes: 17 additions & 1 deletion src/sage/structure/formal_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def __init__(self, x, parent=None, check=True, reduce=True):
- ``reduce`` -- reduce (default: ``True``) if ``False``, do not
combine common terms

.. WARNING::

Setting ``reduce`` to ``False`` can cause issues when comparing
equal sums but with different orders and/or cancellations.

EXAMPLES::

sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)])
Expand Down Expand Up @@ -230,8 +235,19 @@ def _richcmp_(self, other, op):
True
sage: a == 0 # 0 is coerced into a.parent()(0)
False

TESTS::

sage: a = FormalSum([(1, 3), (2, 5)])
sage: b = FormalSum([(2, 5), (1, 3)])
sage: a == b
True
sage: b == a
True
"""
return richcmp(self._data, other._data, op)
self_data = [(c, x) for (x, c) in sorted(self._data, key=str)]
other_data = [(c, x) for (x, c) in sorted(other._data, key=str)]
return richcmp(self_data, other_data, op)

def _neg_(self):
"""
Expand Down