# HG changeset patch
# User Julian Rueth <julian.rueth@gmail.com>
Trac 12988: move characteristic() to the category of rings and check that it is in ZZ
diff --git a/sage/categories/algebras_with_basis.py b/sage/categories/algebras_with_basis.py
index b36808c..88d4fd9 100644
a
|
b
|
class AlgebrasWithBasis(Category_over_base_ring): |
62 | 62 | running ._test_an_element() . . . pass |
63 | 63 | running ._test_associativity() . . . pass |
64 | 64 | running ._test_category() . . . pass |
| 65 | running ._test_characteristic() . . . pass |
65 | 66 | running ._test_distributivity() . . . pass |
66 | 67 | running ._test_elements() . . . |
67 | 68 | Running the test suite of self.an_element() |
diff --git a/sage/categories/fields.py b/sage/categories/fields.py
index 8759b37..dde4419 100644
a
|
b
|
class Fields(Category_singleton): |
181 | 181 | """ |
182 | 182 | return True |
183 | 183 | |
| 184 | def _test_characteristic_fields(self, **options): |
| 185 | """ |
| 186 | Run generic tests on the method :meth:`.characteristic`. |
| 187 | |
| 188 | EXAMPLES:: |
| 189 | |
| 190 | sage: QQ._test_characteristic_fields() |
| 191 | |
| 192 | .. NOTE:: |
| 193 | |
| 194 | We cannot call this method ``_test_characteristic`` since that |
| 195 | would overwrite the method in the super category, and for |
| 196 | cython classes just calling |
| 197 | ``super(sage.categories.fields.Fields().parent_class, |
| 198 | self)._test_characteristic`` doesn't have the desired effect. |
| 199 | |
| 200 | .. SEEALSO:: |
| 201 | |
| 202 | :meth:`sage.categories.rings.Rings.ParentMethods._test_characteristic` |
| 203 | """ |
| 204 | tester = self._tester(**options) |
| 205 | try: |
| 206 | char = self.characteristic() |
| 207 | tester.assertTrue(char.is_zero() or char.is_prime()) |
| 208 | except AttributeError: |
| 209 | return |
| 210 | # raised when self.one() does not have a additive_order() [or when char is an int and not an Integer which is already checked by _test_characteristic for rings] |
| 211 | except NotImplementedError: |
| 212 | return |
| 213 | |
184 | 214 | class ElementMethods: |
185 | 215 | # Fields are unique factorization domains, so, there is gcd and lcm |
186 | 216 | # Of course, in general gcd and lcm in a field are not very interesting. |
diff --git a/sage/categories/hopf_algebras_with_basis.py b/sage/categories/hopf_algebras_with_basis.py
index e4c170f..ba5f464 100644
a
|
b
|
class HopfAlgebrasWithBasis(Category_over_base_ring): |
71 | 71 | running ._test_an_element() . . . pass |
72 | 72 | running ._test_associativity() . . . pass |
73 | 73 | running ._test_category() . . . pass |
| 74 | running ._test_characteristic() . . . pass |
74 | 75 | running ._test_distributivity() . . . pass |
75 | 76 | running ._test_elements() . . . |
76 | 77 | Running the test suite of self.an_element() |
diff --git a/sage/categories/rings.py b/sage/categories/rings.py
index 4dd2eea..8ea5be3 100644
a
|
b
|
class Rings(Category_singleton): |
216 | 216 | from sage.rings.noncommutative_ideals import IdealMonoid_nc |
217 | 217 | return IdealMonoid_nc(self) |
218 | 218 | |
| 219 | def characteristic(self): |
| 220 | """ |
| 221 | Return the characteristic of this ring. |
| 222 | |
| 223 | EXAMPLES:: |
| 224 | |
| 225 | sage: QQ.characteristic() |
| 226 | 0 |
| 227 | sage: GF(19).characteristic() |
| 228 | 19 |
| 229 | sage: Integers(8).characteristic() |
| 230 | 8 |
| 231 | sage: Zp(5).characteristic() |
| 232 | 0 |
| 233 | """ |
| 234 | from sage.rings.infinity import infinity |
| 235 | from sage.rings.integer_ring import ZZ |
| 236 | order_1 = self.one().additive_order() |
| 237 | return ZZ.zero() if order_1 is infinity else order_1 |
| 238 | |
| 239 | def _test_characteristic(self, **options): |
| 240 | """ |
| 241 | Run generic tests on the method :meth:`characteristic`. |
| 242 | |
| 243 | See also: :class:`TestSuite`. |
| 244 | |
| 245 | EXAMPLES:: |
| 246 | |
| 247 | sage: ZZ._test_characteristic() |
| 248 | """ |
| 249 | tester = self._tester(**options) |
| 250 | try: |
| 251 | characteristic = self.characteristic() |
| 252 | except AttributeError: |
| 253 | return # raised when self.one() does not have a additive_order() |
| 254 | except NotImplementedError: |
| 255 | return |
| 256 | |
| 257 | # test that #12988 is fixed |
| 258 | tester.assertEqual(type(characteristic),sage.rings.integer.Integer) |
| 259 | |
219 | 260 | def ideal(self, *args, **kwds): |
220 | 261 | """ |
221 | 262 | Create an ideal of this ring. |
diff --git a/sage/rings/integer_ring.pyx b/sage/rings/integer_ring.pyx
index 303bc47..90cdac5 100644
a
|
b
|
cdef class IntegerRing_class(PrincipalIdealDomain): |
230 | 230 | 19 |
231 | 231 | sage: ZZ(2 + 3*5 + O(5^3)) |
232 | 232 | 17 |
| 233 | |
| 234 | TESTS:: |
| 235 | |
| 236 | sage: TestSuite(ZZ).run() |
233 | 237 | """ |
234 | 238 | |
235 | 239 | def __init__(self): |
… |
… |
cdef class IntegerRing_class(PrincipalIdealDomain): |
883 | 887 | |
884 | 888 | def characteristic(self): |
885 | 889 | """ |
886 | | Return the characteristic of the integers, which is 0 |
| 890 | Return the characteristic of the integers, which is 0. |
887 | 891 | |
888 | 892 | EXAMPLE:: |
889 | 893 | |
890 | 894 | sage: ZZ.characteristic() |
891 | 895 | 0 |
892 | 896 | """ |
893 | | return 0 |
| 897 | return ZZ.zero() |
894 | 898 | |
895 | 899 | def krull_dimension(self): |
896 | 900 | """ |
diff --git a/sage/rings/number_field/number_field.py b/sage/rings/number_field/number_field.py
index 9a084b8..afef188 100644
a
|
b
|
class NumberField_generic(number_field_base.NumberField): |
2867 | 2867 | sage: k.characteristic() |
2868 | 2868 | 0 |
2869 | 2869 | """ |
2870 | | return 0 |
| 2870 | return ZZ.zero() |
2871 | 2871 | |
2872 | 2872 | def class_group(self, proof=None, names='c'): |
2873 | 2873 | r""" |
diff --git a/sage/rings/real_double.pyx b/sage/rings/real_double.pyx
index b1de83f..b5459d2 100644
a
|
b
|
cdef class RealDoubleField_class(Field): |
395 | 395 | sage: RDF.characteristic() |
396 | 396 | 0 |
397 | 397 | """ |
398 | | return 0 |
| 398 | return Integer(0) |
399 | 399 | |
400 | 400 | cdef _new_c(self, double value): |
401 | 401 | cdef RealDoubleElement x |
diff --git a/sage/rings/real_mpfi.pyx b/sage/rings/real_mpfi.pyx
index 631225a..01035f2 100644
a
|
b
|
cdef class RealIntervalField_class(sage.rings.ring.Field): |
754 | 754 | sage: RealIntervalField(10).characteristic() |
755 | 755 | 0 |
756 | 756 | """ |
757 | | return 0 |
| 757 | return Integer(0) |
758 | 758 | |
759 | 759 | def name(self): |
760 | 760 | return "IntervalRealIntervalField%s"%(self.__prec) |
diff --git a/sage/rings/real_mpfr.pyx b/sage/rings/real_mpfr.pyx
index 582a9e6..d80b202 100644
a
|
b
|
cdef class RealField_class(sage.rings.ring.Field): |
719 | 719 | sage: RealField(10).characteristic() |
720 | 720 | 0 |
721 | 721 | """ |
722 | | return 0 |
| 722 | return Integer(0) |
723 | 723 | |
724 | 724 | def name(self): |
725 | 725 | """ |
diff --git a/sage/rings/ring.pyx b/sage/rings/ring.pyx
index 2d24c9c..1c0e55f 100644
a
|
b
|
cdef class Ring(ParentWithGens): |
109 | 109 | running ._test_an_element() . . . pass |
110 | 110 | running ._test_associativity() . . . pass |
111 | 111 | running ._test_category() . . . pass |
| 112 | running ._test_characteristic() . . . pass |
112 | 113 | running ._test_distributivity() . . . pass |
113 | 114 | running ._test_elements() . . . |
114 | 115 | Running the test suite of self.an_element() |
… |
… |
cdef class Ring(ParentWithGens): |
1142 | 1143 | """ |
1143 | 1144 | raise NotImplementedError |
1144 | 1145 | |
1145 | | def characteristic(self): |
1146 | | """ |
1147 | | Return the characteristic of this ring. |
1148 | | |
1149 | | EXAMPLES:: |
1150 | | |
1151 | | sage: QQ.characteristic() |
1152 | | 0 |
1153 | | sage: GF(19).characteristic() |
1154 | | 19 |
1155 | | sage: Integers(8).characteristic() |
1156 | | 8 |
1157 | | sage: Zp(5).characteristic() |
1158 | | 0 |
1159 | | """ |
1160 | | from sage.rings.infinity import infinity |
1161 | | from sage.rings.integer_ring import ZZ |
1162 | | order_1 = self.one_element().additive_order() |
1163 | | return ZZ.zero_element() if order_1 is infinity else order_1 |
1164 | | |
1165 | 1146 | def order(self): |
1166 | 1147 | """ |
1167 | 1148 | The number of elements of self. |
diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
index fc21077..05a1db4 100644
a
|
b
|
cdef class Parent(category_object.CategoryObject): |
832 | 832 | running ._test_an_element() . . . pass |
833 | 833 | running ._test_associativity() . . . pass |
834 | 834 | running ._test_category() . . . pass |
| 835 | running ._test_characteristic() . . . pass |
835 | 836 | running ._test_distributivity() . . . pass |
836 | 837 | running ._test_elements() . . . |
837 | 838 | Running the test suite of self.an_element() |
… |
… |
cdef class Parent(category_object.CategoryObject): |
894 | 895 | _test_an_element |
895 | 896 | _test_associativity |
896 | 897 | _test_category |
| 898 | _test_characteristic |
897 | 899 | _test_distributivity |
898 | 900 | _test_elements |
899 | 901 | _test_elements_eq |