Skip to content

Commit 8d7107c

Browse files
author
Release Manager
committed
gh-37158: use Parent in quotient rings too instead of using the deprecated `ParentWithGens` ### 📝 Checklist - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. URL: #37158 Reported by: Frédéric Chapoton Reviewer(s):
2 parents 766c7a0 + 7cdd497 commit 8d7107c

File tree

10 files changed

+184
-144
lines changed

10 files changed

+184
-144
lines changed

src/sage/categories/commutative_rings.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ def is_commutative(self) -> bool:
140140

141141
def _ideal_class_(self, n=0):
142142
r"""
143-
Return a callable object that can be used to create ideals in this
144-
commutative ring.
143+
Return a callable object that can be used to create ideals
144+
in this commutative ring.
145145
146-
This class can depend on `n`, the number of generators of the ideal.
147-
The default input of `n=0` indicates an unspecified number of generators,
148-
in which case a class that works for any number of generators is returned.
146+
This class can depend on `n`, the number of generators of
147+
the ideal. The default input of `n=0` indicates an
148+
unspecified number of generators, in which case a class
149+
that works for any number of generators is returned.
149150
150151
EXAMPLES::
151152

src/sage/categories/finite_dimensional_algebras_with_basis.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,12 @@ def principal_ideal(self, a, side='left', *args, **opts):
504504
r"""
505505
Construct the ``side`` principal ideal generated by ``a``.
506506
507+
INPUT:
508+
509+
- ``a`` -- an element
510+
- ``side`` -- ``left`` (default) or ``right``
511+
- ``coerce`` -- ignored, for compatibility with categories
512+
507513
EXAMPLES:
508514
509515
In order to highlight the difference between left and
@@ -547,6 +553,7 @@ def principal_ideal(self, a, side='left', *args, **opts):
547553
548554
- :meth:`peirce_summand`
549555
"""
556+
opts.pop("coerce", None)
550557
return self.submodule([(a * b if side == 'right' else b * a)
551558
for b in self.basis()], *args, **opts)
552559

src/sage/categories/rings.py

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
# ****************************************************************************
66
# Copyright (C) 2005 David Kohel <[email protected]>
77
# William Stein <[email protected]>
8-
# 2008 Teresa Gomez-Diaz (CNRS) <[email protected]>
8+
# 2008 Teresa Gomez-Diaz (CNRS)
9+
910
# 2008-2011 Nicolas M. Thiery <nthiery at users.sf.net>
1011
#
1112
# Distributed under the terms of the GNU General Public License (GPL)
@@ -751,109 +752,6 @@ def __pow__(self, n):
751752
from sage.modules.free_module import FreeModule
752753
return FreeModule(self, n)
753754

754-
@cached_method
755-
def ideal_monoid(self):
756-
"""
757-
The monoid of the ideals of this ring.
758-
759-
EXAMPLES::
760-
761-
sage: # needs sage.modules
762-
sage: MS = MatrixSpace(QQ, 2, 2)
763-
sage: isinstance(MS, Ring)
764-
False
765-
sage: MS in Rings()
766-
True
767-
sage: MS.ideal_monoid()
768-
Monoid of ideals of Full MatrixSpace of 2 by 2 dense matrices
769-
over Rational Field
770-
771-
Note that the monoid is cached::
772-
773-
sage: MS.ideal_monoid() is MS.ideal_monoid() # needs sage.modules
774-
True
775-
776-
More examples::
777-
778-
sage: # needs sage.combinat sage.modules
779-
sage: F.<x,y,z> = FreeAlgebra(ZZ, 3)
780-
sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F
781-
sage: Q = F.quotient(I)
782-
sage: Q.ideal_monoid()
783-
Monoid of ideals of Quotient of Free Algebra on 3 generators (x, y, z)
784-
over Integer Ring by the ideal (x*y + y*z, x^2 + x*y - y*x - y^2)
785-
sage: F.<x,y,z> = FreeAlgebra(ZZ, implementation='letterplace')
786-
sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F
787-
sage: Q = F.quo(I)
788-
sage: Q.ideal_monoid()
789-
Monoid of ideals of Quotient of Free Associative Unital Algebra
790-
on 3 generators (x, y, z) over Integer Ring
791-
by the ideal (x*y + y*z, x*x + x*y - y*x - y*y)
792-
793-
sage: ZZ.ideal_monoid()
794-
Monoid of ideals of Integer Ring
795-
sage: R.<x> = QQ[]; R.ideal_monoid()
796-
Monoid of ideals of Univariate Polynomial Ring in x over Rational Field
797-
"""
798-
try:
799-
from sage.rings.ideal_monoid import IdealMonoid
800-
return IdealMonoid(self)
801-
except TypeError:
802-
from sage.rings.noncommutative_ideals import IdealMonoid_nc
803-
return IdealMonoid_nc(self)
804-
805-
def _ideal_class_(self, n=0):
806-
r"""
807-
Return a callable object that can be used to create ideals in this
808-
ring.
809-
810-
EXAMPLES::
811-
812-
sage: MS = MatrixSpace(QQ, 2, 2) # needs sage.modules
813-
sage: MS._ideal_class_() # needs sage.modules
814-
<class 'sage.rings.noncommutative_ideals.Ideal_nc'>
815-
816-
Since :issue:`7797`, non-commutative rings have ideals as well::
817-
818-
sage: A = SteenrodAlgebra(2) # needs sage.combinat sage.modules
819-
sage: A._ideal_class_() # needs sage.combinat sage.modules
820-
<class 'sage.rings.noncommutative_ideals.Ideal_nc'>
821-
"""
822-
from sage.rings.noncommutative_ideals import Ideal_nc
823-
return Ideal_nc
824-
825-
@cached_method
826-
def zero_ideal(self):
827-
"""
828-
Return the zero ideal of this ring (cached).
829-
830-
EXAMPLES::
831-
832-
sage: ZZ.zero_ideal()
833-
Principal ideal (0) of Integer Ring
834-
sage: QQ.zero_ideal()
835-
Principal ideal (0) of Rational Field
836-
sage: QQ['x'].zero_ideal()
837-
Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field
838-
839-
The result is cached::
840-
841-
sage: ZZ.zero_ideal() is ZZ.zero_ideal()
842-
True
843-
844-
TESTS:
845-
846-
Make sure that :issue:`13644` is fixed::
847-
848-
sage: # needs sage.rings.padics
849-
sage: K = Qp(3)
850-
sage: R.<a> = K[]
851-
sage: L.<a> = K.extension(a^2-3)
852-
sage: L.ideal(a)
853-
Principal ideal (1 + O(a^40)) of 3-adic Eisenstein Extension Field in a defined by a^2 - 3
854-
"""
855-
return self._ideal_class_(1)(self, [self.zero()])
856-
857755
@cached_method
858756
def unit_ideal(self):
859757
"""
@@ -866,21 +764,6 @@ def unit_ideal(self):
866764
"""
867765
return self._ideal_class_(1)(self, [self.one()])
868766

869-
def principal_ideal(self, gen, coerce=True):
870-
"""
871-
Return the principal ideal generated by gen.
872-
873-
EXAMPLES::
874-
875-
sage: R.<x,y> = ZZ[]
876-
sage: R.principal_ideal(x+2*y)
877-
Ideal (x + 2*y) of Multivariate Polynomial Ring in x, y over Integer Ring
878-
"""
879-
C = self._ideal_class_(1)
880-
if coerce:
881-
gen = self(gen)
882-
return C(self, [gen])
883-
884767
def characteristic(self):
885768
"""
886769
Return the characteristic of this ring.

src/sage/categories/rngs.py

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
r"""
33
Rngs
44
"""
5-
#*****************************************************************************
5+
# ****************************************************************************
66
# Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <[email protected]>
77
# 2012 Nicolas M. Thiery <nthiery at users.sf.net>
88
#
99
# Distributed under the terms of the GNU General Public License (GPL)
10-
# http://www.gnu.org/licenses/
11-
#******************************************************************************
10+
# https://www.gnu.org/licenses/
11+
# *****************************************************************************
1212

13+
from sage.misc.cachefunc import cached_method
1314
from sage.categories.category_with_axiom import CategoryWithAxiom
1415
from sage.misc.lazy_import import LazyImport
1516
from sage.categories.magmas_and_additive_magmas import MagmasAndAdditiveMagmas
@@ -49,3 +50,111 @@ class Rngs(CategoryWithAxiom):
4950
_base_category_class_and_axiom = (MagmasAndAdditiveMagmas.Distributive.AdditiveAssociative.AdditiveCommutative.AdditiveUnital.Associative, "AdditiveInverse")
5051

5152
Unital = LazyImport('sage.categories.rings', 'Rings', at_startup=True)
53+
54+
class ParentMethods:
55+
56+
@cached_method
57+
def ideal_monoid(self):
58+
"""
59+
The monoid of the ideals of this ring.
60+
61+
.. NOTE::
62+
63+
The code is copied from the base class of rings.
64+
This is since there are rings that do not inherit
65+
from that class, such as matrix algebras. See
66+
:issue:`7797`.
67+
68+
EXAMPLES::
69+
70+
sage: # needs sage.modules
71+
sage: MS = MatrixSpace(QQ, 2, 2)
72+
sage: isinstance(MS, Ring)
73+
False
74+
sage: MS in Rings()
75+
True
76+
sage: MS.ideal_monoid()
77+
Monoid of ideals of Full MatrixSpace of 2 by 2 dense matrices
78+
over Rational Field
79+
80+
Note that the monoid is cached::
81+
82+
sage: MS.ideal_monoid() is MS.ideal_monoid() # needs sage.modules
83+
True
84+
"""
85+
try:
86+
from sage.rings.ideal_monoid import IdealMonoid
87+
return IdealMonoid(self)
88+
except TypeError:
89+
from sage.rings.noncommutative_ideals import IdealMonoid_nc
90+
return IdealMonoid_nc(self)
91+
92+
def _ideal_class_(self, n=0):
93+
r"""
94+
Return a callable object that can be used to create ideals in this
95+
ring.
96+
97+
The argument `n`, standing for the number of generators
98+
of the ideal, is ignored.
99+
100+
EXAMPLES::
101+
102+
sage: MS = MatrixSpace(QQ, 2, 2) # needs sage.modules
103+
sage: MS._ideal_class_() # needs sage.modules
104+
<class 'sage.rings.noncommutative_ideals.Ideal_nc'>
105+
106+
Since :issue:`7797`, non-commutative rings have ideals as well::
107+
108+
sage: A = SteenrodAlgebra(2) # needs sage.combinat sage.modules
109+
sage: A._ideal_class_() # needs sage.combinat sage.modules
110+
<class 'sage.rings.noncommutative_ideals.Ideal_nc'>
111+
"""
112+
from sage.rings.noncommutative_ideals import Ideal_nc
113+
return Ideal_nc
114+
115+
def principal_ideal(self, gen, coerce=True):
116+
"""
117+
Return the principal ideal generated by ``gen``.
118+
119+
EXAMPLES::
120+
121+
sage: R.<x,y> = ZZ[]
122+
sage: R.principal_ideal(x+2*y)
123+
Ideal (x + 2*y) of Multivariate Polynomial Ring in x, y over Integer Ring
124+
"""
125+
C = self._ideal_class_(1)
126+
if coerce:
127+
gen = self(gen)
128+
return C(self, [gen])
129+
130+
@cached_method
131+
def zero_ideal(self):
132+
"""
133+
Return the zero ideal of this ring (cached).
134+
135+
EXAMPLES::
136+
137+
sage: ZZ.zero_ideal()
138+
Principal ideal (0) of Integer Ring
139+
sage: QQ.zero_ideal()
140+
Principal ideal (0) of Rational Field
141+
sage: QQ['x'].zero_ideal()
142+
Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field
143+
144+
The result is cached::
145+
146+
sage: ZZ.zero_ideal() is ZZ.zero_ideal()
147+
True
148+
149+
TESTS:
150+
151+
Make sure that :issue:`13644` is fixed::
152+
153+
sage: # needs sage.rings.padics
154+
sage: K = Qp(3)
155+
sage: R.<a> = K[]
156+
sage: L.<a> = K.extension(a^2-3)
157+
sage: L.ideal(a)
158+
Principal ideal (1 + O(a^40)) of 3-adic Eisenstein Extension Field in a defined by a^2 - 3
159+
"""
160+
return self._ideal_class_(1)(self, [self.zero()])

src/sage/rings/finite_rings/finite_field_prime_modn.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,30 @@ def gen(self, n=0):
300300
self.__gen = self.one()
301301
return self.__gen
302302

303+
def gens(self) -> tuple:
304+
r"""
305+
Return a tuple containing the generator of ``self``.
306+
307+
.. WARNING::
308+
309+
The generator is not guaranteed to be a generator for the
310+
multiplicative group. To obtain the latter, use
311+
:meth:`~sage.rings.finite_rings.finite_field_base.FiniteFields.multiplicative_generator()`
312+
or use the ``modulus="primitive"`` option when constructing
313+
the field.
314+
315+
EXAMPLES::
316+
317+
sage: k = GF(1009, modulus='primitive')
318+
sage: k.gens()
319+
(11,)
320+
321+
sage: k = GF(1009)
322+
sage: k.gens()
323+
(1,)
324+
"""
325+
return (self.gen(),)
326+
303327
def __iter__(self):
304328
"""
305329
Return an iterator over ``self``.

src/sage/rings/function_field/ideal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ def __init__(self, R):
10661066
sage: M = O.ideal_monoid()
10671067
sage: TestSuite(M).run()
10681068
"""
1069-
self.Element = R._ideal_class
1069+
self.Element = R._ideal_class_
10701070
Parent.__init__(self, category=Monoids())
10711071

10721072
self.__R = R

src/sage/rings/function_field/order.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal, category=None):
145145
category = IntegralDomains().or_subcategory(category).Infinite()
146146
Parent.__init__(self, category=category, facade=field)
147147

148-
self._ideal_class = ideal_class # element class for parent ideal monoid
148+
self._ideal_class_ = ideal_class # element class for parent ideal monoid
149149
self._field = field
150150

151151
def is_field(self, proof=True):

src/sage/rings/function_field/order_polymod.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,7 @@ def decomposition(self, ideal):
649649
# algebra O mod pO.
650650
matrices_reduced = [M.mod(p) for M in matrices]
651651
cat = CommutativeAlgebras(k).FiniteDimensional().WithBasis()
652-
A = FiniteDimensionalAlgebra(k, matrices_reduced,
653-
assume_associative=True,
654-
category=cat)
652+
A = FiniteDimensionalAlgebra(k, matrices_reduced, category=cat)
655653

656654
# Each prime ideal of the algebra A corresponds to a prime ideal of O,
657655
# and since the algebra is an Artinian ring, all of its prime ideals

src/sage/rings/morphism.pyx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ from sage.rings import ideal
409409
import sage.structure.all
410410
from sage.structure.richcmp cimport (richcmp, rich_to_bool)
411411
from sage.misc.cachefunc import cached_method
412+
from sage.categories.rings import Rings
412413
from sage.categories.facade_sets import FacadeSets
413414

414415

@@ -1288,7 +1289,8 @@ cdef class RingHomomorphism(RingMap):
12881289
from sage.rings.ideal import Ideal_generic
12891290
A = self.domain()
12901291
B = self.codomain()
1291-
if not (A.is_commutative() and B.is_commutative()):
1292+
Comm = Rings().Commutative()
1293+
if not (A in Comm and B in Comm):
12921294
raise NotImplementedError("rings are not commutative")
12931295
if A.base_ring() != B.base_ring():
12941296
raise NotImplementedError("base rings must be equal")

0 commit comments

Comments
 (0)