From f3a37062a265271bbbb8900637fa22632c68ebb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 12:05:16 +0100 Subject: [PATCH 1/4] moving "is_integrally_closed" to the category setup. --- src/sage/categories/fields.py | 11 ++++--- src/sage/categories/integral_domains.py | 19 +++++++++++ src/sage/categories/rings.py | 22 +++++++++++++ src/sage/rings/integer_ring.pyx | 16 --------- src/sage/rings/number_field/order.py | 6 ++-- src/sage/rings/ring.pyx | 43 ------------------------- 6 files changed, 52 insertions(+), 65 deletions(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index e1f5c3d68f6..98251904607 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -206,11 +206,12 @@ def is_field(self, proof=True): """ return True - def is_integrally_closed(self): + def is_integrally_closed(self) -> bool: r""" - Return ``True``, as per :meth:`IntegralDomain.is_integrally_closed`: - for every field `F`, `F` is its own field of fractions, - hence every element of `F` is integral over `F`. + Return whether ``self`` is integrally closed. + + For every field `F`, `F` is its own field of fractions. + Therefore every element of `F` is integral over `F`. EXAMPLES:: @@ -222,6 +223,8 @@ def is_integrally_closed(self): Finite Field of size 5 sage: Z5.is_integrally_closed() True + sage: Frac(ZZ['x,y']).is_integrally_closed() + True """ return True diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 173a14cf25f..1a051fcd350 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -1,6 +1,25 @@ # sage_setup: distribution = sagemath-categories r""" Integral domains + +TEST: + +A few doctest for the method ``is_integrally_closed``:: + + sage: ZZ.is_integrally_closed() + True + sage: QQ.is_integrally_closed() + True + sage: QQbar.is_integrally_closed() # needs sage.rings.number_field + True + sage: GF(5).is_integrally_closed() + True + sage: Z5 = Integers(5); Z5 + Ring of integers modulo 5 + sage: Z5.is_integrally_closed() + False + +Note that this returns ``False`` is the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 8db71edfb9c..2f483fb76a4 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -423,6 +423,28 @@ def is_integral_domain(self, proof=True) -> bool: return False + def is_integrally_closed(self) -> bool: + r""" + Return whether this ring is integrally closed. + + This is the default implementation that returns ``False``. + + EXAMPLES:: + + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 + 189*x + 394) + sage: R = K.order(2*a) + sage: R.is_integrally_closed() + False + sage: R + Order of conductor 2 generated by 2*a in Number Field in a with defining polynomial x^2 + 189*x + 394 + sage: S = K.maximal_order(); S + Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 189*x + 394 + sage: S.is_integrally_closed() + True + """ + return False + def is_noetherian(self): """ Return ``True`` if this ring is Noetherian. diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 2b2ec33294c..67bcf61c3a8 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -1142,22 +1142,6 @@ cdef class IntegerRing_class(CommutativeRing): """ return 1 - def is_integrally_closed(self): - """ - Return that the integer ring is, in fact, integrally closed. - - .. NOTE:: - - This should rather be inherited from the category - of ``DedekindDomains``. - - EXAMPLES:: - - sage: ZZ.is_integrally_closed() - True - """ - return True - def completion(self, p, prec, extras = {}): r""" Return the metric completion of the integers at the prime `p`. diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 9dee6a8a481..fd5662048df 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -631,9 +631,11 @@ def is_noetherian(self): """ return True - def is_integrally_closed(self): + def is_integrally_closed(self) -> bool: r""" - Return ``True`` if this ring is integrally closed, i.e., is equal + Return whether this ring is integrally closed. + + This is true if and only if it is equal to the maximal order. EXAMPLES:: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index f92aa7c0d27..0aa79a5f80a 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -1018,37 +1018,6 @@ cdef class IntegralDomain(CommutativeRing): CommutativeRing.__init__(self, base_ring, names=names, normalize=normalize, category=category) - def is_integrally_closed(self): - r""" - Return ``True`` if this ring is integrally closed in its field of - fractions; otherwise return ``False``. - - When no algorithm is implemented for this, then this - function raises a :exc:`NotImplementedError`. - - Note that ``is_integrally_closed`` has a naive implementation - in fields. For every field `F`, `F` is its own field of fractions, - hence every element of `F` is integral over `F`. - - EXAMPLES:: - - sage: ZZ.is_integrally_closed() - True - sage: QQ.is_integrally_closed() - True - sage: QQbar.is_integrally_closed() # needs sage.rings.number_field - True - sage: GF(5).is_integrally_closed() - True - sage: Z5 = Integers(5); Z5 - Ring of integers modulo 5 - sage: Z5.is_integrally_closed() - Traceback (most recent call last): - ... - AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed'... - """ - raise NotImplementedError - def is_field(self, proof=True): r""" Return ``True`` if this ring is a field. @@ -1228,18 +1197,6 @@ cdef class Field(CommutativeRing): """ return True - def is_integrally_closed(self): - """ - Return ``True`` since fields are trivially integrally closed in - their fraction field (since they are their own fraction field). - - EXAMPLES:: - - sage: Frac(ZZ['x,y']).is_integrally_closed() - True - """ - return True - def krull_dimension(self): """ Return the Krull dimension of this field, which is 0. From 72cf71003ed49c44a4fd3cf746413bb24530350d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 13:27:20 +0100 Subject: [PATCH 2/4] fix doctest --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 5e9fcf77db6..5eeddc3a7f6 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -132,7 +132,6 @@ This base class provides a lot more methods than a general parent:: 'integral_closure', 'is_commutative', 'is_field', - 'is_integrally_closed', 'krull_dimension', 'localization', 'ngens', From 0f19b618359e77906efd16336fe18cea2ca6c039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 13:30:23 +0100 Subject: [PATCH 3/4] doc details --- src/sage/categories/integral_domains.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 1a051fcd350..c76f9f0ca00 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -4,7 +4,7 @@ TEST: -A few doctest for the method ``is_integrally_closed``:: +A few tests for the method ``is_integrally_closed``:: sage: ZZ.is_integrally_closed() True @@ -19,7 +19,7 @@ sage: Z5.is_integrally_closed() False -Note that this returns ``False`` is the answer is not known. +Note that this returns ``False`` if the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) From 7816d7a6b81ef291e6d3df25965eba4557f555b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 19:38:28 +0100 Subject: [PATCH 4/4] change the default to NotImplementedError --- src/sage/categories/integral_domains.py | 6 ++++-- src/sage/categories/rings.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index c76f9f0ca00..4dd66a9277b 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -17,9 +17,11 @@ sage: Z5 = Integers(5); Z5 Ring of integers modulo 5 sage: Z5.is_integrally_closed() - False + Traceback (most recent call last): + ... + NotImplementedError -Note that this returns ``False`` if the answer is not known. +Note that this raises a :exc:`NotImplementedError` if the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 2f483fb76a4..77894634f99 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -427,7 +427,8 @@ def is_integrally_closed(self) -> bool: r""" Return whether this ring is integrally closed. - This is the default implementation that returns ``False``. + This is the default implementation that + raises a :exc:`NotImplementedError`. EXAMPLES:: @@ -443,7 +444,7 @@ def is_integrally_closed(self) -> bool: sage: S.is_integrally_closed() True """ - return False + raise NotImplementedError def is_noetherian(self): """