passagemath-objects 10.8.1a3__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. passagemath_objects/__init__.py +3 -0
  2. passagemath_objects-10.8.1a3.dist-info/DELVEWHEEL +2 -0
  3. passagemath_objects-10.8.1a3.dist-info/METADATA +114 -0
  4. passagemath_objects-10.8.1a3.dist-info/RECORD +283 -0
  5. passagemath_objects-10.8.1a3.dist-info/WHEEL +5 -0
  6. passagemath_objects-10.8.1a3.dist-info/top_level.txt +3 -0
  7. passagemath_objects.libs/libgmp-10-60021eeab4282b29024e43b2b1412b53.dll +0 -0
  8. sage/all__sagemath_objects.py +46 -0
  9. sage/arith/all__sagemath_objects.py +5 -0
  10. sage/arith/long.pxd +411 -0
  11. sage/arith/numerical_approx.cp314-win_amd64.pyd +0 -0
  12. sage/arith/numerical_approx.pxd +35 -0
  13. sage/arith/numerical_approx.pyx +75 -0
  14. sage/arith/power.cp314-win_amd64.pyd +0 -0
  15. sage/arith/power.pxd +31 -0
  16. sage/arith/power.pyx +127 -0
  17. sage/categories/action.cp314-win_amd64.pyd +0 -0
  18. sage/categories/action.pxd +29 -0
  19. sage/categories/action.pyx +641 -0
  20. sage/categories/algebra_functor.py +745 -0
  21. sage/categories/all__sagemath_objects.py +33 -0
  22. sage/categories/basic.py +71 -0
  23. sage/categories/cartesian_product.py +292 -0
  24. sage/categories/category.py +3379 -0
  25. sage/categories/category_cy_helper.cp314-win_amd64.pyd +0 -0
  26. sage/categories/category_cy_helper.pxd +8 -0
  27. sage/categories/category_cy_helper.pyx +322 -0
  28. sage/categories/category_singleton.cp314-win_amd64.pyd +0 -0
  29. sage/categories/category_singleton.pxd +3 -0
  30. sage/categories/category_singleton.pyx +343 -0
  31. sage/categories/category_types.py +637 -0
  32. sage/categories/category_with_axiom.py +2889 -0
  33. sage/categories/covariant_functorial_construction.py +700 -0
  34. sage/categories/facade_sets.py +228 -0
  35. sage/categories/functor.cp314-win_amd64.pyd +0 -0
  36. sage/categories/functor.pxd +7 -0
  37. sage/categories/functor.pyx +659 -0
  38. sage/categories/homset.py +1289 -0
  39. sage/categories/homsets.py +364 -0
  40. sage/categories/isomorphic_objects.py +73 -0
  41. sage/categories/map.cp314-win_amd64.pyd +0 -0
  42. sage/categories/map.pxd +34 -0
  43. sage/categories/map.pyx +2106 -0
  44. sage/categories/morphism.cp314-win_amd64.pyd +0 -0
  45. sage/categories/morphism.pxd +14 -0
  46. sage/categories/morphism.pyx +895 -0
  47. sage/categories/objects.py +167 -0
  48. sage/categories/primer.py +1695 -0
  49. sage/categories/pushout.py +4847 -0
  50. sage/categories/quotients.py +64 -0
  51. sage/categories/realizations.py +200 -0
  52. sage/categories/sets_cat.py +3305 -0
  53. sage/categories/sets_with_partial_maps.py +52 -0
  54. sage/categories/subobjects.py +64 -0
  55. sage/categories/subquotients.py +21 -0
  56. sage/categories/with_realizations.py +311 -0
  57. sage/cpython/__init__.py +22 -0
  58. sage/cpython/_py2_random.py +619 -0
  59. sage/cpython/all.py +3 -0
  60. sage/cpython/atexit.cp314-win_amd64.pyd +0 -0
  61. sage/cpython/atexit.pyx +269 -0
  62. sage/cpython/builtin_types.cp314-win_amd64.pyd +0 -0
  63. sage/cpython/builtin_types.pyx +7 -0
  64. sage/cpython/cython_metaclass.cp314-win_amd64.pyd +0 -0
  65. sage/cpython/cython_metaclass.h +117 -0
  66. sage/cpython/cython_metaclass.pxd +3 -0
  67. sage/cpython/cython_metaclass.pyx +130 -0
  68. sage/cpython/debug.cp314-win_amd64.pyd +0 -0
  69. sage/cpython/debug.pyx +302 -0
  70. sage/cpython/dict_del_by_value.cp314-win_amd64.pyd +0 -0
  71. sage/cpython/dict_del_by_value.pxd +9 -0
  72. sage/cpython/dict_del_by_value.pyx +191 -0
  73. sage/cpython/dict_internal.h +80 -0
  74. sage/cpython/getattr.cp314-win_amd64.pyd +0 -0
  75. sage/cpython/getattr.pxd +9 -0
  76. sage/cpython/getattr.pyx +439 -0
  77. sage/cpython/pycore_long.h +97 -0
  78. sage/cpython/pycore_long.pxd +10 -0
  79. sage/cpython/python_debug.h +44 -0
  80. sage/cpython/python_debug.pxd +47 -0
  81. sage/cpython/pyx_visit.h +13 -0
  82. sage/cpython/string.cp314-win_amd64.pyd +0 -0
  83. sage/cpython/string.pxd +76 -0
  84. sage/cpython/string.pyx +34 -0
  85. sage/cpython/string_impl.h +60 -0
  86. sage/cpython/type.cp314-win_amd64.pyd +0 -0
  87. sage/cpython/type.pxd +2 -0
  88. sage/cpython/type.pyx +40 -0
  89. sage/cpython/wrapperdescr.pxd +67 -0
  90. sage/ext/all__sagemath_objects.py +3 -0
  91. sage/ext/ccobject.h +64 -0
  92. sage/ext/cplusplus.pxd +17 -0
  93. sage/ext/mod_int.h +30 -0
  94. sage/ext/mod_int.pxd +24 -0
  95. sage/ext/stdsage.pxd +39 -0
  96. sage/groups/all__sagemath_objects.py +1 -0
  97. sage/groups/group.cp314-win_amd64.pyd +0 -0
  98. sage/groups/group.pxd +14 -0
  99. sage/groups/group.pyx +296 -0
  100. sage/groups/old.cp314-win_amd64.pyd +0 -0
  101. sage/groups/old.pxd +14 -0
  102. sage/groups/old.pyx +219 -0
  103. sage/libs/all__sagemath_objects.py +3 -0
  104. sage/libs/gmp/__init__.py +1 -0
  105. sage/libs/gmp/all.pxd +6 -0
  106. sage/libs/gmp/binop.pxd +23 -0
  107. sage/libs/gmp/misc.pxd +8 -0
  108. sage/libs/gmp/mpf.pxd +88 -0
  109. sage/libs/gmp/mpn.pxd +57 -0
  110. sage/libs/gmp/mpq.pxd +57 -0
  111. sage/libs/gmp/mpz.pxd +202 -0
  112. sage/libs/gmp/pylong.cp314-win_amd64.pyd +0 -0
  113. sage/libs/gmp/pylong.pxd +12 -0
  114. sage/libs/gmp/pylong.pyx +150 -0
  115. sage/libs/gmp/random.pxd +25 -0
  116. sage/libs/gmp/randomize.pxd +59 -0
  117. sage/libs/gmp/types.pxd +53 -0
  118. sage/libs/gmpxx.pxd +19 -0
  119. sage/misc/abstract_method.py +276 -0
  120. sage/misc/all__sagemath_objects.py +43 -0
  121. sage/misc/bindable_class.py +253 -0
  122. sage/misc/c3_controlled.cp314-win_amd64.pyd +0 -0
  123. sage/misc/c3_controlled.pxd +2 -0
  124. sage/misc/c3_controlled.pyx +1402 -0
  125. sage/misc/cachefunc.cp314-win_amd64.pyd +0 -0
  126. sage/misc/cachefunc.pxd +43 -0
  127. sage/misc/cachefunc.pyx +3801 -0
  128. sage/misc/call.py +188 -0
  129. sage/misc/classcall_metaclass.cp314-win_amd64.pyd +0 -0
  130. sage/misc/classcall_metaclass.pxd +14 -0
  131. sage/misc/classcall_metaclass.pyx +599 -0
  132. sage/misc/constant_function.cp314-win_amd64.pyd +0 -0
  133. sage/misc/constant_function.pyx +130 -0
  134. sage/misc/decorators.py +739 -0
  135. sage/misc/fast_methods.cp314-win_amd64.pyd +0 -0
  136. sage/misc/fast_methods.pxd +20 -0
  137. sage/misc/fast_methods.pyx +351 -0
  138. sage/misc/flatten.py +90 -0
  139. sage/misc/fpickle.cp314-win_amd64.pyd +0 -0
  140. sage/misc/fpickle.pyx +176 -0
  141. sage/misc/function_mangling.cp314-win_amd64.pyd +0 -0
  142. sage/misc/function_mangling.pxd +11 -0
  143. sage/misc/function_mangling.pyx +308 -0
  144. sage/misc/inherit_comparison.cp314-win_amd64.pyd +0 -0
  145. sage/misc/inherit_comparison.pxd +5 -0
  146. sage/misc/inherit_comparison.pyx +105 -0
  147. sage/misc/instancedoc.cp314-win_amd64.pyd +0 -0
  148. sage/misc/instancedoc.pyx +331 -0
  149. sage/misc/lazy_attribute.cp314-win_amd64.pyd +0 -0
  150. sage/misc/lazy_attribute.pyx +607 -0
  151. sage/misc/lazy_format.py +132 -0
  152. sage/misc/lazy_import.cp314-win_amd64.pyd +0 -0
  153. sage/misc/lazy_import.pxd +13 -0
  154. sage/misc/lazy_import.pyx +1307 -0
  155. sage/misc/lazy_import_cache.py +36 -0
  156. sage/misc/lazy_list.cp314-win_amd64.pyd +0 -0
  157. sage/misc/lazy_list.pxd +19 -0
  158. sage/misc/lazy_list.pyx +1187 -0
  159. sage/misc/lazy_string.cp314-win_amd64.pyd +0 -0
  160. sage/misc/lazy_string.pxd +7 -0
  161. sage/misc/lazy_string.pyx +546 -0
  162. sage/misc/misc.py +980 -0
  163. sage/misc/misc_c.cp314-win_amd64.pyd +0 -0
  164. sage/misc/misc_c.pxd +3 -0
  165. sage/misc/misc_c.pyx +765 -0
  166. sage/misc/namespace_package.py +37 -0
  167. sage/misc/nested_class.cp314-win_amd64.pyd +0 -0
  168. sage/misc/nested_class.pxd +3 -0
  169. sage/misc/nested_class.pyx +394 -0
  170. sage/misc/persist.cp314-win_amd64.pyd +0 -0
  171. sage/misc/persist.pyx +1279 -0
  172. sage/misc/prandom.py +418 -0
  173. sage/misc/randstate.cp314-win_amd64.pyd +0 -0
  174. sage/misc/randstate.pxd +31 -0
  175. sage/misc/randstate.pyx +1096 -0
  176. sage/misc/repr.py +203 -0
  177. sage/misc/reset.cp314-win_amd64.pyd +0 -0
  178. sage/misc/reset.pyx +196 -0
  179. sage/misc/sage_ostools.cp314-win_amd64.pyd +0 -0
  180. sage/misc/sage_ostools.pyx +323 -0
  181. sage/misc/sage_timeit.py +275 -0
  182. sage/misc/sage_timeit_class.cp314-win_amd64.pyd +0 -0
  183. sage/misc/sage_timeit_class.pyx +120 -0
  184. sage/misc/sage_unittest.py +639 -0
  185. sage/misc/sageinspect.py +2792 -0
  186. sage/misc/session.cp314-win_amd64.pyd +0 -0
  187. sage/misc/session.pyx +392 -0
  188. sage/misc/superseded.py +576 -0
  189. sage/misc/test_nested_class.py +228 -0
  190. sage/misc/timing.py +264 -0
  191. sage/misc/unknown.py +222 -0
  192. sage/misc/verbose.py +253 -0
  193. sage/misc/weak_dict.cp314-win_amd64.pyd +0 -0
  194. sage/misc/weak_dict.pxd +15 -0
  195. sage/misc/weak_dict.pyx +1197 -0
  196. sage/modules/all__sagemath_objects.py +1 -0
  197. sage/modules/module.cp314-win_amd64.pyd +0 -0
  198. sage/modules/module.pxd +5 -0
  199. sage/modules/module.pyx +329 -0
  200. sage/rings/all__sagemath_objects.py +3 -0
  201. sage/rings/integer_fake.h +22 -0
  202. sage/rings/integer_fake.pxd +55 -0
  203. sage/rings/integer_fake.pyi +8 -0
  204. sage/sets/all__sagemath_objects.py +3 -0
  205. sage/sets/pythonclass.cp314-win_amd64.pyd +0 -0
  206. sage/sets/pythonclass.pxd +9 -0
  207. sage/sets/pythonclass.pyx +247 -0
  208. sage/structure/__init__.py +13 -0
  209. sage/structure/all.py +30 -0
  210. sage/structure/category_object.cp314-win_amd64.pyd +0 -0
  211. sage/structure/category_object.pxd +28 -0
  212. sage/structure/category_object.pyx +1090 -0
  213. sage/structure/coerce.cp314-win_amd64.pyd +0 -0
  214. sage/structure/coerce.pxd +44 -0
  215. sage/structure/coerce.pyx +2113 -0
  216. sage/structure/coerce_actions.cp314-win_amd64.pyd +0 -0
  217. sage/structure/coerce_actions.pxd +27 -0
  218. sage/structure/coerce_actions.pyx +988 -0
  219. sage/structure/coerce_dict.cp314-win_amd64.pyd +0 -0
  220. sage/structure/coerce_dict.pxd +51 -0
  221. sage/structure/coerce_dict.pyx +1557 -0
  222. sage/structure/coerce_exceptions.py +23 -0
  223. sage/structure/coerce_maps.cp314-win_amd64.pyd +0 -0
  224. sage/structure/coerce_maps.pxd +24 -0
  225. sage/structure/coerce_maps.pyx +656 -0
  226. sage/structure/debug_options.cp314-win_amd64.pyd +0 -0
  227. sage/structure/debug_options.pxd +6 -0
  228. sage/structure/debug_options.pyx +54 -0
  229. sage/structure/dynamic_class.py +541 -0
  230. sage/structure/element.cp314-win_amd64.pyd +0 -0
  231. sage/structure/element.pxd +271 -0
  232. sage/structure/element.pyx +4584 -0
  233. sage/structure/element_wrapper.cp314-win_amd64.pyd +0 -0
  234. sage/structure/element_wrapper.pxd +12 -0
  235. sage/structure/element_wrapper.pyx +582 -0
  236. sage/structure/factorization.py +1457 -0
  237. sage/structure/factorization_integer.py +154 -0
  238. sage/structure/factory.cp314-win_amd64.pyd +0 -0
  239. sage/structure/factory.pyx +863 -0
  240. sage/structure/formal_sum.py +489 -0
  241. sage/structure/gens_py.py +73 -0
  242. sage/structure/global_options.py +1725 -0
  243. sage/structure/indexed_generators.py +863 -0
  244. sage/structure/list_clone.cp314-win_amd64.pyd +0 -0
  245. sage/structure/list_clone.pxd +65 -0
  246. sage/structure/list_clone.pyx +1867 -0
  247. sage/structure/list_clone_demo.cp314-win_amd64.pyd +0 -0
  248. sage/structure/list_clone_demo.pyx +248 -0
  249. sage/structure/list_clone_timings.py +179 -0
  250. sage/structure/list_clone_timings_cy.cp314-win_amd64.pyd +0 -0
  251. sage/structure/list_clone_timings_cy.pyx +86 -0
  252. sage/structure/mutability.cp314-win_amd64.pyd +0 -0
  253. sage/structure/mutability.pxd +21 -0
  254. sage/structure/mutability.pyx +346 -0
  255. sage/structure/nonexact.py +69 -0
  256. sage/structure/parent.cp314-win_amd64.pyd +0 -0
  257. sage/structure/parent.pxd +112 -0
  258. sage/structure/parent.pyx +3087 -0
  259. sage/structure/parent_base.cp314-win_amd64.pyd +0 -0
  260. sage/structure/parent_base.pxd +13 -0
  261. sage/structure/parent_base.pyx +35 -0
  262. sage/structure/parent_gens.cp314-win_amd64.pyd +0 -0
  263. sage/structure/parent_gens.pxd +22 -0
  264. sage/structure/parent_gens.pyx +374 -0
  265. sage/structure/parent_old.cp314-win_amd64.pyd +0 -0
  266. sage/structure/parent_old.pxd +24 -0
  267. sage/structure/parent_old.pyx +278 -0
  268. sage/structure/proof/__init__.py +1 -0
  269. sage/structure/proof/all.py +243 -0
  270. sage/structure/proof/proof.py +300 -0
  271. sage/structure/richcmp.cp314-win_amd64.pyd +0 -0
  272. sage/structure/richcmp.pxd +212 -0
  273. sage/structure/richcmp.pyx +494 -0
  274. sage/structure/sage_object.cp314-win_amd64.pyd +0 -0
  275. sage/structure/sage_object.pxd +3 -0
  276. sage/structure/sage_object.pyx +1088 -0
  277. sage/structure/sage_object_test.py +19 -0
  278. sage/structure/sequence.py +937 -0
  279. sage/structure/set_factories.py +1178 -0
  280. sage/structure/set_factories_example.py +527 -0
  281. sage/structure/support_view.py +164 -0
  282. sage/structure/test_factory.py +56 -0
  283. sage/structure/unique_representation.py +1443 -0
@@ -0,0 +1,1090 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ # cython: old_style_globals=True
3
+ r"""
4
+ Base class for objects of a category
5
+
6
+ CLASS HIERARCHY:
7
+
8
+ - :class:`~sage.structure.sage_object.SageObject`
9
+
10
+ - **CategoryObject**
11
+
12
+ - :class:`~sage.structure.parent.Parent`
13
+
14
+ Many category objects in Sage are equipped with generators, which are
15
+ usually special elements of the object. For example, the polynomial ring
16
+ `\ZZ[x,y,z]` is generated by `x`, `y`, and `z`. In Sage the ``i`` th
17
+ generator of an object ``X`` is obtained using the notation
18
+ ``X.gen(i)``. From the Sage interactive prompt, the shorthand
19
+ notation ``X.i`` is also allowed.
20
+
21
+ The following examples illustrate these functions in the context of
22
+ multivariate polynomial rings and free modules.
23
+
24
+ EXAMPLES::
25
+
26
+ sage: R = PolynomialRing(ZZ, 3, 'x')
27
+ sage: R.ngens()
28
+ 3
29
+ sage: R.gen(0)
30
+ x0
31
+ sage: R.gens()
32
+ (x0, x1, x2)
33
+ sage: R.variable_names()
34
+ ('x0', 'x1', 'x2')
35
+
36
+ This example illustrates generators for a free module over `\ZZ`.
37
+
38
+ ::
39
+
40
+ sage: # needs sage.modules
41
+ sage: M = FreeModule(ZZ, 4)
42
+ sage: M
43
+ Ambient free module of rank 4 over the principal ideal domain Integer Ring
44
+ sage: M.ngens()
45
+ 4
46
+ sage: M.gen(0)
47
+ (1, 0, 0, 0)
48
+ sage: M.gens()
49
+ ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
50
+ """
51
+
52
+ # ****************************************************************************
53
+ # This program is free software: you can redistribute it and/or modify
54
+ # it under the terms of the GNU General Public License as published by
55
+ # the Free Software Foundation, either version 2 of the License, or
56
+ # (at your option) any later version.
57
+ # https://www.gnu.org/licenses/
58
+ # ****************************************************************************
59
+
60
+ from sage.cpython.getattr import dir_with_other_class
61
+ from sage.cpython.getattr cimport getattr_from_other_class
62
+ from sage.categories.category import Category
63
+ from sage.misc.cachefunc import cached_method
64
+ from sage.structure.dynamic_class import DynamicMetaclass
65
+
66
+
67
+ cpdef inline check_default_category(default_category, category):
68
+ """
69
+ The resulting category is guaranteed to be
70
+ a sub-category of the default.
71
+ """
72
+ if category is None:
73
+ return default_category
74
+ return default_category.join([default_category, category])
75
+
76
+
77
+ cdef class CategoryObject(SageObject):
78
+ """
79
+ An object in some category.
80
+ """
81
+ def __init__(self, category=None, base=None):
82
+ """
83
+ Initialize an object in a category.
84
+
85
+ INPUT:
86
+
87
+ - ``category`` -- the category this object belongs to; if this object
88
+ belongs to multiple categories, those can be passed as a tuple
89
+ - ``base`` -- if this object has another object that should be
90
+ considered a base in its primary category, you can include that base
91
+ here
92
+
93
+ EXAMPLES::
94
+
95
+ sage: from sage.structure.category_object import CategoryObject
96
+ sage: A = CategoryObject()
97
+ sage: A.category()
98
+ Category of objects
99
+ sage: A.base()
100
+
101
+ sage: A = CategoryObject(category = Rings(), base = QQ)
102
+ sage: A.category()
103
+ Category of rings
104
+ sage: A.base()
105
+ Rational Field
106
+
107
+ sage: A = CategoryObject(category = (Semigroups(), CommutativeAdditiveSemigroups()))
108
+ sage: A.category()
109
+ Join of Category of semigroups and Category of commutative additive semigroups
110
+
111
+ FIXME: the base and generators attributes have nothing to do with categories, do they?
112
+ """
113
+ if base is not None:
114
+ self._base = base
115
+ if category is not None:
116
+ self._init_category_(category)
117
+
118
+ def __cinit__(self):
119
+ self._cached_methods = {}
120
+ self._hash_value = -1
121
+
122
+ def _init_category_(self, category):
123
+ """
124
+ Set the category or categories of this object.
125
+
126
+ INPUT:
127
+
128
+ - ``category`` -- a category, or list or tuple thereof
129
+
130
+ EXAMPLES::
131
+
132
+ sage: A = sage.structure.category_object.CategoryObject()
133
+ sage: A._init_category_(Rings())
134
+ sage: A.category()
135
+ Category of rings
136
+ sage: A._init_category_((Semigroups(), CommutativeAdditiveSemigroups()))
137
+ sage: A.category()
138
+ Join of Category of semigroups and Category of commutative additive semigroups
139
+ sage: P = Parent(category=None)
140
+ sage: P.category()
141
+ Category of sets
142
+
143
+ TESTS::
144
+
145
+ sage: A = sage.structure.category_object.CategoryObject()
146
+ sage: A._init_category_(None)
147
+ Traceback (most recent call last):
148
+ ...
149
+ TypeError: CategoryObject of type CategoryObject requires a Category, list or tuple, not NoneType
150
+ """
151
+ if isinstance(category, Category):
152
+ self._category = category
153
+ elif isinstance(category, (list, tuple)):
154
+ self._category = Category.join(category)
155
+ else:
156
+ raise TypeError(f"CategoryObject of type {type(self).__name__} requires a Category, list or tuple, not {type(category).__name__}")
157
+
158
+ def _refine_category_(self, category):
159
+ """
160
+ Change the category of ``self`` into a subcategory.
161
+
162
+ INPUT:
163
+
164
+ - ``category`` -- a category or list or tuple thereof
165
+
166
+ The new category is obtained by adjoining ``category`` to the
167
+ current one.
168
+
169
+ .. SEEALSO:: :function:`Category.join`
170
+
171
+ EXAMPLES::
172
+
173
+ sage: P = Parent()
174
+ sage: P.category()
175
+ Category of sets
176
+ sage: P._refine_category_(Magmas())
177
+ sage: P.category()
178
+ Category of magmas
179
+ sage: P._refine_category_(Magmas())
180
+ sage: P.category()
181
+ Category of magmas
182
+ sage: P._refine_category_(EnumeratedSets())
183
+ sage: P.category()
184
+ Category of enumerated magmas
185
+ sage: P._refine_category_([Semigroups(), CommutativeAdditiveSemigroups()])
186
+ sage: P.category()
187
+ Join of Category of semigroups and Category of commutative additive semigroups and Category of enumerated sets
188
+ sage: P._refine_category_((CommutativeAdditiveMonoids(), Monoids()))
189
+ sage: P.category()
190
+ Join of Category of monoids and Category of commutative additive monoids and Category of enumerated sets
191
+ """
192
+ if self._category is None:
193
+ self._init_category_(category)
194
+ return
195
+ if not isinstance(category, (tuple, list)):
196
+ category = [category]
197
+ self._category = self._category.join([self._category]+list(category))
198
+
199
+ def _is_category_initialized(self):
200
+ return self._category is not None
201
+
202
+ def category(self):
203
+ if self._category is None:
204
+ # COERCE TODO: we shouldn't need this
205
+ from sage.categories.objects import Objects
206
+ self._category = Objects()
207
+ return self._category
208
+
209
+ def categories(self):
210
+ """
211
+ Return the categories of ``self``.
212
+
213
+ EXAMPLES::
214
+
215
+ sage: ZZ.categories()
216
+ [Join of Category of Dedekind domains
217
+ and Category of euclidean domains
218
+ and Category of noetherian rings
219
+ and Category of infinite enumerated sets
220
+ and Category of metric spaces,
221
+ Category of Dedekind domains,
222
+ Category of euclidean domains,
223
+ Category of principal ideal domains,
224
+ Category of unique factorization domains,
225
+ Category of gcd domains,
226
+ Category of integral domains,
227
+ Category of domains, ...
228
+ Category of commutative rings, ...
229
+ Category of monoids, ...,
230
+ Category of commutative additive groups, ...,
231
+ Category of sets, ...,
232
+ Category of objects]
233
+ """
234
+ return self.category().all_super_categories()
235
+
236
+ def _underlying_class(self):
237
+ r"""
238
+ Return the underlying class (class without the attached
239
+ categories) of the given object.
240
+
241
+ OUTPUT: a class
242
+
243
+ EXAMPLES::
244
+
245
+ sage: type(QQ)
246
+ <class 'sage.rings.rational_field.RationalField_with_category'>
247
+ sage: QQ._underlying_class()
248
+ <class 'sage.rings.rational_field.RationalField'>
249
+ sage: type(ZZ)
250
+ <... 'sage.rings.integer_ring.IntegerRing_class'>
251
+ sage: ZZ._underlying_class()
252
+ <... 'sage.rings.integer_ring.IntegerRing_class'>
253
+ """
254
+ cls = type(self)
255
+ if isinstance(cls, DynamicMetaclass):
256
+ return cls.__bases__[0]
257
+ else:
258
+ return cls
259
+
260
+ ##############################################################################
261
+ # Generators
262
+ ##############################################################################
263
+
264
+ @cached_method
265
+ def __gens_dict(self):
266
+ cdef dict v = {}
267
+ for x in self._defining_names():
268
+ v[str(x)] = x
269
+ return v
270
+
271
+ def gens_dict(self, *, copy=True):
272
+ r"""
273
+ Return a dictionary whose entries are ``{name:variable,...}``,
274
+ where ``name`` stands for the variable names of this
275
+ object (as strings) and ``variable`` stands for the
276
+ corresponding defining generators (as elements of this object).
277
+
278
+ EXAMPLES::
279
+
280
+ sage: B.<a,b,c,d> = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori
281
+ sage: B.gens_dict() # needs sage.rings.polynomial.pbori
282
+ {'a': a, 'b': b, 'c': c, 'd': d}
283
+
284
+ TESTS::
285
+
286
+ sage: B.<a,b,c,d> = PolynomialRing(QQ)
287
+ sage: B.gens_dict(copy=False) is B.gens_dict(copy=False)
288
+ True
289
+ sage: B.gens_dict(copy=False) is B.gens_dict()
290
+ False
291
+ """
292
+ if copy:
293
+ return dict(self.__gens_dict())
294
+ else:
295
+ return self.__gens_dict()
296
+
297
+ def gens_dict_recursive(self):
298
+ r"""
299
+ Return the dictionary of generators of ``self`` and its base rings.
300
+
301
+ OUTPUT:
302
+
303
+ - a dictionary with string names of generators as keys and
304
+ generators of ``self`` and its base rings as values.
305
+
306
+ EXAMPLES::
307
+
308
+ sage: R = QQ['x,y']['z,w']
309
+ sage: sorted(R.gens_dict_recursive().items())
310
+ [('w', w), ('x', x), ('y', y), ('z', z)]
311
+ """
312
+ B = self.base_ring()
313
+ if B is self:
314
+ return {}
315
+ GDR = B.gens_dict_recursive()
316
+ GDR.update(self.gens_dict())
317
+ return GDR
318
+
319
+ def objgens(self):
320
+ """
321
+ Return the tuple ``(self, self.gens())``.
322
+
323
+ EXAMPLES::
324
+
325
+ sage: R = PolynomialRing(QQ, 3, 'x'); R
326
+ Multivariate Polynomial Ring in x0, x1, x2 over Rational Field
327
+ sage: R.objgens()
328
+ (Multivariate Polynomial Ring in x0, x1, x2 over Rational Field, (x0, x1, x2))
329
+ """
330
+ return self, self.gens()
331
+
332
+ def objgen(self):
333
+ """
334
+ Return the tuple ``(self, self.gen())``.
335
+
336
+ EXAMPLES::
337
+
338
+ sage: R, x = PolynomialRing(QQ,'x').objgen()
339
+ sage: R
340
+ Univariate Polynomial Ring in x over Rational Field
341
+ sage: x
342
+ x
343
+ """
344
+ return self, self.gen()
345
+
346
+ def _first_ngens(self, n):
347
+ """
348
+ Used by the preparser for ``R.<x> = ...``.
349
+
350
+ EXAMPLES::
351
+
352
+ sage: R.<x> = PolynomialRing(QQ)
353
+ sage: x
354
+ x
355
+ sage: parent(x)
356
+ Univariate Polynomial Ring in x over Rational Field
357
+
358
+ For orders, we correctly use the ring generator, see
359
+ :issue:`15348`::
360
+
361
+ sage: A.<i> = ZZ.extension(x^2 + 1) # needs sage.rings.number_field
362
+ sage: i # needs sage.rings.number_field
363
+ i
364
+ sage: parent(i) # needs sage.rings.number_field
365
+ Gaussian Integers generated by i
366
+ in Number Field in i with defining polynomial x^2 + 1
367
+
368
+ ::
369
+
370
+ sage: B.<z> = EquationOrder(x^2 + 3) # needs sage.rings.number_field
371
+ sage: z.minpoly() # needs sage.rings.number_field
372
+ x^2 + 3
373
+ """
374
+ names = self._defining_names()
375
+ if isinstance(names, (list, tuple)):
376
+ return names[:n]
377
+ # case of Family
378
+ it = iter(names)
379
+ return tuple(next(it) for i in range(n))
380
+
381
+ @cached_method
382
+ def _defining_names(self):
383
+ """
384
+ The elements used to "define" this object.
385
+
386
+ What this means depends on the type of object: for rings, it
387
+ usually means generators as a ring. The result of this function
388
+ is not required to generate the object, but it should contain
389
+ all named elements if the object was constructed using a
390
+ ``names'' argument.
391
+
392
+ This function is used by the preparser to implement
393
+ ``R.<x> = ...`` and it is also used by :meth:`gens_dict`.
394
+
395
+ EXAMPLES::
396
+
397
+ sage: R.<x> = PolynomialRing(QQ)
398
+ sage: R._defining_names()
399
+ (x,)
400
+
401
+ For orders, we correctly use the ring generator, see
402
+ :issue:`15348`::
403
+
404
+ sage: B.<z> = EquationOrder(x^2 + 3) # needs sage.rings.number_field
405
+ sage: B._defining_names() # needs sage.rings.number_field
406
+ (z,)
407
+
408
+ For vector spaces and free modules, we get a basis (which can
409
+ be different from the given generators)::
410
+
411
+ sage: # needs sage.modules
412
+ sage: V = ZZ^3
413
+ sage: V._defining_names()
414
+ ((1, 0, 0), (0, 1, 0), (0, 0, 1))
415
+ sage: W = V.span([(0, 1, 0), (1/2, 1, 0)])
416
+ sage: W._defining_names()
417
+ ((1/2, 0, 0), (0, 1, 0))
418
+ """
419
+ return self.gens()
420
+
421
+ #################################################################################################
422
+ # Names and Printers
423
+ #################################################################################################
424
+
425
+ def _assign_names(self, names=None, normalize=True, ngens=None):
426
+ """
427
+ Set the names of the generator of this object.
428
+
429
+ This can only be done once because objects with generators
430
+ are immutable, and is typically done during creation of the object.
431
+
432
+ EXAMPLES:
433
+ When we create this polynomial ring, self._assign_names is called by the constructor::
434
+
435
+ sage: R = QQ['x,y,abc']; R
436
+ Multivariate Polynomial Ring in x, y, abc over Rational Field
437
+ sage: R.2
438
+ abc
439
+
440
+ We can't rename the variables::
441
+
442
+ sage: R._assign_names(['a','b','c'])
443
+ Traceback (most recent call last):
444
+ ...
445
+ ValueError: variable names cannot be changed after object creation.
446
+ """
447
+ # this will eventually all be handled by the printer
448
+ if names is None: return
449
+ if normalize:
450
+ if ngens is None:
451
+ ngens = -1 # unknown
452
+ names = normalize_names(ngens, names)
453
+ if self._names is not None and names != self._names:
454
+ raise ValueError('variable names cannot be changed after object creation.')
455
+ if isinstance(names, str):
456
+ names = (names, ) # make it a tuple
457
+ elif isinstance(names, list):
458
+ names = tuple(names)
459
+ elif not isinstance(names, tuple):
460
+ raise TypeError("names must be a tuple of strings")
461
+ self._names = names
462
+
463
+ def variable_names(self):
464
+ """
465
+ Return the list of variable names corresponding to the generators.
466
+
467
+ OUTPUT: a tuple of strings
468
+
469
+ EXAMPLES::
470
+
471
+ sage: R.<z,y,a42> = QQ[]
472
+ sage: R.variable_names()
473
+ ('z', 'y', 'a42')
474
+ sage: S = R.quotient_ring(z+y)
475
+ sage: S.variable_names()
476
+ ('zbar', 'ybar', 'a42bar')
477
+
478
+ ::
479
+
480
+ sage: # needs sage.modules
481
+ sage: T.<x> = InfinitePolynomialRing(ZZ)
482
+ sage: T.variable_names()
483
+ ('x',)
484
+ """
485
+ if self._names is not None:
486
+ return self._names
487
+ raise ValueError("variable names have not yet been set using self._assign_names(...)")
488
+
489
+ def variable_name(self):
490
+ """
491
+ Return the first variable name.
492
+
493
+ OUTPUT: string
494
+
495
+ EXAMPLES::
496
+
497
+ sage: R.<z,y,a42> = ZZ[]
498
+ sage: R.variable_name()
499
+ 'z'
500
+
501
+ sage: # needs sage.modules
502
+ sage: R.<x> = InfinitePolynomialRing(ZZ)
503
+ sage: R.variable_name()
504
+ 'x'
505
+ """
506
+ return self.variable_names()[0]
507
+
508
+ def _temporarily_change_names(self, names, latex_names):
509
+ """
510
+ This is used by the variable names context manager.
511
+
512
+ TESTS:
513
+
514
+ In an old version, it was impossible to temporarily change
515
+ the names if no names were previously assigned. But if one
516
+ wants to print elements of the quotient of such an "unnamed"
517
+ ring, an error resulted. That was fixed in :issue:`11068`::
518
+
519
+ sage: # needs sage.modules
520
+ sage: MS = MatrixSpace(GF(5), 2, 2)
521
+ sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS
522
+ sage: Q.<a,b,c,d> = MS.quo(I)
523
+ sage: a #indirect doctest
524
+ [1 0]
525
+ [0 0]
526
+ """
527
+ # old = self._names, self._latex_names
528
+ # We cannot assume that self *has* _latex_variable_names.
529
+ # But there is a method that returns them and sets
530
+ # the attribute at the same time, if needed.
531
+ # Simon King: It is not necessarily the case that variable
532
+ # names are assigned. In that case, self._names is None,
533
+ # and self.variable_names() raises a ValueError
534
+ try:
535
+ old = self.variable_names(), self.latex_variable_names()
536
+ except ValueError:
537
+ old = None, None
538
+ self._names, self._latex_names = names, latex_names
539
+ return old
540
+
541
+ def inject_variables(self, scope=None, verbose=True):
542
+ """
543
+ Inject the generators of ``self`` with their names into the
544
+ namespace of the Python code from which this function is
545
+ called.
546
+
547
+ Thus, e.g., if the generators of ``self`` are labeled
548
+ 'a', 'b', and 'c', then after calling this method the
549
+ variables a, b, and c in the current scope will be set
550
+ equal to the generators of ``self``.
551
+
552
+ NOTE: If Foo is a constructor for a Sage object with generators, and
553
+ Foo is defined in Cython, then it would typically call
554
+ ``inject_variables()`` on the object it creates. E.g.,
555
+ ``PolynomialRing(QQ, 'y')`` does this so that the variable y is the
556
+ generator of the polynomial ring.
557
+ """
558
+ vs = self.variable_names()
559
+ gs = self.gens()
560
+ if scope is None:
561
+ scope = globals()
562
+ if verbose:
563
+ print("Defining %s" % (', '.join(vs)))
564
+ for v, g in zip(vs, gs):
565
+ scope[v] = g
566
+
567
+ #################################################################################################
568
+ # Bases
569
+ #################################################################################################
570
+
571
+ def base_ring(self):
572
+ """
573
+ Return the base ring of ``self``.
574
+
575
+ INPUT:
576
+
577
+ - ``self`` -- an object over a base ring; typically a module
578
+
579
+ EXAMPLES::
580
+
581
+ sage: from sage.modules.module import Module
582
+ sage: Module(ZZ).base_ring()
583
+ Integer Ring
584
+
585
+ sage: F = FreeModule(ZZ, 3) # needs sage.modules
586
+ sage: F.base_ring() # needs sage.modules
587
+ Integer Ring
588
+ sage: F.__class__.base_ring # needs sage.modules
589
+ <cyfunction CategoryObject.base_ring at ...>
590
+
591
+ Note that the coordinates of the elements of a module can lie
592
+ in a bigger ring, the ``coordinate_ring``::
593
+
594
+ sage: # needs sage.modules
595
+ sage: M = (ZZ^2) * (1/2)
596
+ sage: v = M([1/2, 0])
597
+ sage: v.base_ring()
598
+ Integer Ring
599
+ sage: parent(v[0])
600
+ Rational Field
601
+ sage: v.coordinate_ring()
602
+ Rational Field
603
+
604
+ More examples::
605
+
606
+ sage: F = FreeAlgebra(QQ, 'x') # needs sage.combinat sage.modules
607
+ sage: F.base_ring() # needs sage.combinat sage.modules
608
+ Rational Field
609
+ sage: F.__class__.base_ring # needs sage.combinat sage.modules
610
+ <cyfunction CategoryObject.base_ring at ...>
611
+
612
+ sage: # needs sage.modules
613
+ sage: E = CombinatorialFreeModule(ZZ, [1,2,3])
614
+ sage: F = CombinatorialFreeModule(ZZ, [2,3,4])
615
+ sage: H = Hom(E, F)
616
+ sage: H.base_ring()
617
+ Integer Ring
618
+ sage: H.__class__.base_ring
619
+ <cyfunction CategoryObject.base_ring at ...>
620
+
621
+ .. TODO::
622
+
623
+ Move this method elsewhere (typically in the Modules
624
+ category) so as not to pollute the namespace of all
625
+ category objects.
626
+ """
627
+ return self._base
628
+
629
+ def base(self):
630
+ return self._base
631
+
632
+ ############################################################################
633
+ # Homomorphism --
634
+ ############################################################################
635
+ def Hom(self, codomain, cat=None):
636
+ r"""
637
+ Return the homspace ``Hom(self, codomain, cat)`` of all
638
+ homomorphisms from ``self`` to ``codomain`` in the category ``cat``.
639
+
640
+ The default category is determined by ``self.category()`` and
641
+ ``codomain.category()``.
642
+
643
+ EXAMPLES::
644
+
645
+ sage: R.<x,y> = PolynomialRing(QQ, 2)
646
+ sage: R.Hom(QQ)
647
+ Set of Homomorphisms
648
+ from Multivariate Polynomial Ring in x, y over Rational Field
649
+ to Rational Field
650
+
651
+ Homspaces are defined for very general Sage objects, even elements of familiar rings.
652
+
653
+ ::
654
+
655
+ sage: n = 5; Hom(n,7)
656
+ Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
657
+ sage: z = 2/3; Hom(z, 8/1)
658
+ Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field
659
+
660
+ This example illustrates the optional third argument::
661
+
662
+ sage: QQ.Hom(ZZ, Sets())
663
+ Set of Morphisms from Rational Field to Integer Ring in Category of sets
664
+ """
665
+ try:
666
+ return self._Hom_(codomain, cat)
667
+ except (AttributeError, TypeError):
668
+ pass
669
+ from sage.categories.homset import Hom
670
+ return Hom(self, codomain, cat)
671
+
672
+ def latex_variable_names(self):
673
+ """
674
+ Return the list of variable names suitable for latex output.
675
+
676
+ All ``_SOMETHING`` substrings are replaced by ``_{SOMETHING}``
677
+ recursively so that subscripts of subscripts work.
678
+
679
+ EXAMPLES::
680
+
681
+ sage: R, x = PolynomialRing(QQ, 'x', 12).objgens()
682
+ sage: x
683
+ (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
684
+ sage: R.latex_variable_names ()
685
+ ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}',
686
+ 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}']
687
+ sage: f = x[0]^3 + 15/3 * x[1]^10
688
+ sage: print(latex(f))
689
+ 5 x_{1}^{10} + x_{0}^{3}
690
+ """
691
+ from sage.misc.latex import latex_variable_name
692
+ try:
693
+ names = self._latex_names
694
+ if names is not None:
695
+ return names
696
+ except AttributeError:
697
+ pass
698
+ # Compute the latex versions of the variable names.
699
+ self._latex_names = [latex_variable_name(x)
700
+ for x in self.variable_names()]
701
+ return self._latex_names
702
+
703
+ def latex_name(self):
704
+ return self.latex_variable_names()[0]
705
+
706
+ #################################################################################
707
+ # Give all objects with generators a dictionary, so that attribute setting
708
+ # works. It would be nice if this functionality were standard in Cython,
709
+ # i.e., just define __dict__ as an attribute and all this code gets generated.
710
+ #################################################################################
711
+ def __getstate__(self):
712
+ try:
713
+ d = self.__dict__.copy() # so we can add elements
714
+ except AttributeError:
715
+ d = {}
716
+ d['_category'] = self._category
717
+ d['_base'] = self._base
718
+ d['_names'] = self._names
719
+ ###########
720
+ # The _pickle_version ensures that the unpickling for objects created
721
+ # in different versions of sage works across versions.
722
+ # Update this integer if you change any of these attributes
723
+ ###########
724
+ d['_pickle_version'] = 1
725
+
726
+ return d
727
+
728
+ def __setstate__(self, d):
729
+ try:
730
+ version = d['_pickle_version']
731
+ except KeyError:
732
+ version = 0
733
+ try:
734
+ if version == 1:
735
+ if d['_category'] is not None:
736
+ # We must not erase the category information of
737
+ # self. Otherwise, pickles break (e.g., QQ should
738
+ # be a commutative ring, but when QQ._category is
739
+ # None then it only knows that it is a ring!
740
+ if self._category is None:
741
+ self._category = d['_category']
742
+ else:
743
+ self._category = self._category.join([self._category,d['_category']])
744
+ self._base = d['_base']
745
+ self._names = d['_names']
746
+ elif version == 0:
747
+ # In the old code, this functionality was in parent_gens,
748
+ # but there were parents that didn't inherit from parent_gens.
749
+ # If we have such, then we only need to deal with the dictionary.
750
+ try:
751
+ self._base = d['_base']
752
+ self._names = d['_names']
753
+ # We throw away d['_latex_names'] and d['_list']
754
+ except (AttributeError, KeyError):
755
+ pass
756
+ try:
757
+ self.__dict__ = d
758
+ except AttributeError:
759
+ pass
760
+ except (AttributeError, KeyError):
761
+ raise
762
+ # raise RuntimeError("If you change the pickling code in parent or category_object, you need to update the _pickle_version field")
763
+
764
+ def __hash__(self):
765
+ """
766
+ A default hash based on the string representation of ``self``.
767
+
768
+ It is cached to remain consistent throughout a session, even
769
+ if the representation changes.
770
+
771
+ EXAMPLES::
772
+
773
+ sage: bla = PolynomialRing(ZZ,"x")
774
+ sage: h1 = hash(bla)
775
+ sage: h1 # random
776
+ -5279516879544852222
777
+ sage: bla.rename('toto')
778
+ sage: h2 = hash(bla)
779
+ sage: h2 # random
780
+ -5279516879544852222
781
+ sage: h1 == h2
782
+ True
783
+ """
784
+ if self._hash_value == -1:
785
+ self._hash_value = hash(repr(self))
786
+ return self._hash_value
787
+
788
+ ##############################################################################
789
+ # Getting attributes from the category
790
+ ##############################################################################
791
+
792
+ def __getattr__(self, name):
793
+ """
794
+ Let cat be the category of ``self``. This method emulates
795
+ ``self`` being an instance of both ``CategoryObject`` and
796
+ ``cat.parent_class``, in that order, for attribute lookup.
797
+
798
+ This attribute lookup is cached for speed.
799
+
800
+ EXAMPLES:
801
+
802
+ We test that ZZ (an extension type) inherits the methods from
803
+ its categories, that is from ``EuclideanDomains().parent_class``::
804
+
805
+ sage: ZZ._test_associativity
806
+ <bound method Semigroups.ParentMethods._test_associativity of Integer Ring>
807
+ sage: ZZ._test_associativity(verbose = True)
808
+ sage: TestSuite(ZZ).run(verbose = True)
809
+ running ._test_additive_associativity() . . . pass
810
+ running ._test_an_element() . . . pass
811
+ running ._test_associativity() . . . pass
812
+ running ._test_cardinality() . . . pass
813
+ running ._test_category() . . . pass
814
+ running ._test_characteristic() . . . pass
815
+ running ._test_construction() . . . pass
816
+ running ._test_distributivity() . . . pass
817
+ running ._test_divides() . . . pass
818
+ running ._test_elements() . . .
819
+ Running the test suite of self.an_element()
820
+ running ._test_category() . . . pass
821
+ running ._test_eq() . . . pass
822
+ running ._test_new() . . . pass
823
+ running ._test_nonzero_equal() . . . pass
824
+ running ._test_not_implemented_methods() . . . pass
825
+ running ._test_pickling() . . . pass
826
+ pass
827
+ running ._test_elements_eq_reflexive() . . . pass
828
+ running ._test_elements_eq_symmetric() . . . pass
829
+ running ._test_elements_eq_transitive() . . . pass
830
+ running ._test_elements_neq() . . . pass
831
+ running ._test_enumerated_set_contains() . . . pass
832
+ running ._test_enumerated_set_iter_cardinality() . . . pass
833
+ running ._test_enumerated_set_iter_list() . . . pass
834
+ running ._test_eq() . . . pass
835
+ running ._test_euclidean_degree() . . . pass
836
+ running ._test_fraction_field() . . . pass
837
+ running ._test_gcd_vs_xgcd() . . . pass
838
+ running ._test_metric_function() . . . pass
839
+ running ._test_new() . . . pass
840
+ running ._test_not_implemented_methods() . . . pass
841
+ running ._test_one() . . . pass
842
+ running ._test_pickling() . . . pass
843
+ running ._test_prod() . . . pass
844
+ running ._test_quo_rem() . . . pass
845
+ running ._test_some_elements() . . . pass
846
+ running ._test_zero() . . . pass
847
+ running ._test_zero_divisors() . . . pass
848
+
849
+ sage: Sets().example().sadfasdf
850
+ Traceback (most recent call last):
851
+ ...
852
+ AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf'...
853
+ """
854
+ return self.getattr_from_category(name)
855
+
856
+ cdef getattr_from_category(self, name):
857
+ # Lookup a method or attribute from the category abstract classes.
858
+ # See __getattr__ above for documentation.
859
+ try:
860
+ return self._cached_methods[name]
861
+ except KeyError:
862
+ if self._category is None:
863
+ # Usually, this will just raise AttributeError in
864
+ # getattr_from_other_class().
865
+ cls = type
866
+ else:
867
+ cls = self._category.parent_class
868
+
869
+ attr = getattr_from_other_class(self, cls, name)
870
+ self._cached_methods[name] = attr
871
+ return attr
872
+
873
+ def __dir__(self):
874
+ """
875
+ Let cat be the category of ``self``. This method emulates
876
+ ``self`` being an instance of both ``CategoryObject`` and
877
+ ``cat.parent_class``, in that order, for attribute directory.
878
+
879
+ EXAMPLES::
880
+
881
+ sage: for s in dir(ZZ):
882
+ ....: if s[:6] == "_test_": print(s)
883
+ _test_additive_associativity
884
+ _test_an_element
885
+ _test_associativity
886
+ _test_cardinality
887
+ _test_category
888
+ _test_characteristic
889
+ _test_construction
890
+ _test_distributivity
891
+ _test_divides
892
+ _test_elements
893
+ _test_elements_eq_reflexive
894
+ _test_elements_eq_symmetric
895
+ _test_elements_eq_transitive
896
+ _test_elements_neq
897
+ _test_enumerated_set_contains
898
+ _test_enumerated_set_iter_cardinality
899
+ _test_enumerated_set_iter_list
900
+ _test_eq
901
+ _test_euclidean_degree
902
+ _test_fraction_field
903
+ _test_gcd_vs_xgcd
904
+ _test_metric_function
905
+ _test_new
906
+ _test_not_implemented_methods
907
+ _test_one
908
+ _test_pickling
909
+ _test_prod
910
+ _test_quo_rem
911
+ _test_some_elements
912
+ _test_zero
913
+ _test_zero_divisors
914
+ sage: F = GF(9,'a') # needs sage.rings.finite_rings
915
+ sage: dir(F) # needs sage.rings.finite_rings
916
+ [..., '__class__', ..., '_test_pickling', ..., 'extension', ...]
917
+ """
918
+ return dir_with_other_class(self, self.category().parent_class)
919
+
920
+ cpdef normalize_names(Py_ssize_t ngens, names):
921
+ r"""
922
+ Return a tuple of strings of variable names of length ngens given
923
+ the input names.
924
+
925
+ INPUT:
926
+
927
+ - ``ngens`` -- integer; number of generators. The value ``ngens=-1``
928
+ means that the number of generators is unknown a priori.
929
+
930
+ - ``names`` -- any of the following:
931
+
932
+ - a tuple or list of strings, such as ``('x', 'y')``
933
+
934
+ - a comma-separated string, such as ``x,y``
935
+
936
+ - a string prefix, such as 'alpha'
937
+
938
+ - a string of single character names, such as 'xyz'
939
+
940
+ OUTPUT: a tuple of ``ngens`` strings to be used as variable names
941
+
942
+ EXAMPLES::
943
+
944
+ sage: from sage.structure.category_object import normalize_names as nn
945
+ sage: nn(0, "")
946
+ ()
947
+ sage: nn(0, [])
948
+ ()
949
+ sage: nn(0, None)
950
+ ()
951
+ sage: nn(1, 'a')
952
+ ('a',)
953
+ sage: nn(2, 'z_z')
954
+ ('z_z0', 'z_z1')
955
+ sage: nn(3, 'x, y, z')
956
+ ('x', 'y', 'z')
957
+ sage: nn(2, 'ab')
958
+ ('a', 'b')
959
+ sage: nn(2, 'x0')
960
+ ('x00', 'x01')
961
+ sage: nn(3, (' a ', ' bb ', ' ccc '))
962
+ ('a', 'bb', 'ccc')
963
+ sage: nn(4, ['a1', 'a2', 'b1', 'b11'])
964
+ ('a1', 'a2', 'b1', 'b11')
965
+
966
+ Arguments are converted to strings::
967
+
968
+ sage: nn(1, u'a')
969
+ ('a',)
970
+ sage: var('alpha') # needs sage.symbolic
971
+ alpha
972
+ sage: nn(2, alpha) # needs sage.symbolic
973
+ ('alpha0', 'alpha1')
974
+ sage: nn(1, [alpha]) # needs sage.symbolic
975
+ ('alpha',)
976
+
977
+ With an unknown number of generators::
978
+
979
+ sage: nn(-1, 'a')
980
+ ('a',)
981
+ sage: nn(-1, 'x, y, z')
982
+ ('x', 'y', 'z')
983
+
984
+ Test errors::
985
+
986
+ sage: nn(3, ["x", "y"])
987
+ Traceback (most recent call last):
988
+ ...
989
+ IndexError: the number of names must equal the number of generators
990
+ sage: nn(None, "a")
991
+ Traceback (most recent call last):
992
+ ...
993
+ TypeError: 'NoneType' object cannot be interpreted as an integer
994
+ sage: nn(1, "")
995
+ Traceback (most recent call last):
996
+ ...
997
+ ValueError: variable name must be nonempty
998
+ sage: nn(1, "foo@")
999
+ Traceback (most recent call last):
1000
+ ...
1001
+ ValueError: variable name 'foo@' is not alphanumeric
1002
+ sage: nn(2, "_foo")
1003
+ Traceback (most recent call last):
1004
+ ...
1005
+ ValueError: variable name '_foo0' does not start with a letter
1006
+ sage: nn(1, 3/2)
1007
+ Traceback (most recent call last):
1008
+ ...
1009
+ ValueError: variable name '3/2' is not alphanumeric
1010
+ """
1011
+ if isinstance(names, (tuple, list)):
1012
+ # Convert names to strings and strip whitespace
1013
+ names = [str(x).strip() for x in names]
1014
+ else:
1015
+ # Interpret names as string and convert to tuple of strings
1016
+ names = str(names)
1017
+
1018
+ if ',' in names:
1019
+ names = [x.strip() for x in names.split(',')]
1020
+ elif ngens > 1 and len(names) == ngens:
1021
+ # Split a name like "xyz" into ("x", "y", "z")
1022
+ try:
1023
+ certify_names(names)
1024
+ names = tuple(names)
1025
+ except ValueError:
1026
+ pass
1027
+ if isinstance(names, str):
1028
+ if ngens < 0:
1029
+ names = [names]
1030
+ else:
1031
+ import sage.misc.defaults
1032
+ names = sage.misc.defaults.variable_names(ngens, names)
1033
+
1034
+ certify_names(names)
1035
+ if ngens >= 0 and len(names) != ngens:
1036
+ raise IndexError("the number of names must equal the number of generators")
1037
+ return tuple(names)
1038
+
1039
+
1040
+ cpdef bint certify_names(names) except -1:
1041
+ """
1042
+ Check that ``names`` are valid variable names.
1043
+
1044
+ INPUT:
1045
+
1046
+ - ``names`` -- an iterable with strings representing variable names
1047
+
1048
+ OUTPUT: ``True`` (for efficiency of the Cython call)
1049
+
1050
+ EXAMPLES::
1051
+
1052
+ sage: from sage.structure.category_object import certify_names as cn
1053
+ sage: cn(["a", "b", "c"])
1054
+ 1
1055
+ sage: cn("abc")
1056
+ 1
1057
+ sage: cn([])
1058
+ 1
1059
+ sage: cn([""])
1060
+ Traceback (most recent call last):
1061
+ ...
1062
+ ValueError: variable name must be nonempty
1063
+ sage: cn(["_foo"])
1064
+ Traceback (most recent call last):
1065
+ ...
1066
+ ValueError: variable name '_foo' does not start with a letter
1067
+ sage: cn(["x'"])
1068
+ Traceback (most recent call last):
1069
+ ...
1070
+ ValueError: variable name "x'" is not alphanumeric
1071
+ sage: cn(["a", "b", "b"])
1072
+ Traceback (most recent call last):
1073
+ ...
1074
+ ValueError: variable name 'b' appears more than once
1075
+ """
1076
+ cdef set s = set()
1077
+ for N in names:
1078
+ if not isinstance(N, str):
1079
+ raise TypeError("variable name {!r} must be a string, not {}".format(N, type(N)))
1080
+ if not N:
1081
+ raise ValueError("variable name must be nonempty")
1082
+ if not N.replace("_", "").isalnum():
1083
+ # We must be alphanumeric, but we make an exception for non-leading '_' characters.
1084
+ raise ValueError("variable name {!r} is not alphanumeric".format(N))
1085
+ if not N[0].isalpha():
1086
+ raise ValueError("variable name {!r} does not start with a letter".format(N))
1087
+ if N in s:
1088
+ raise ValueError("variable name {!r} appears more than once".format(N))
1089
+ s.add(N)
1090
+ return True