passagemath-objects 10.6.47__cp311-cp311-macosx_13_0_x86_64.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 (280) hide show
  1. passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_objects/__init__.py +3 -0
  3. passagemath_objects-10.6.47.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.47.dist-info/RECORD +280 -0
  5. passagemath_objects-10.6.47.dist-info/WHEEL +6 -0
  6. passagemath_objects-10.6.47.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_objects.py +37 -0
  8. sage/arith/all__sagemath_objects.py +5 -0
  9. sage/arith/long.pxd +411 -0
  10. sage/arith/numerical_approx.cpython-311-darwin.so +0 -0
  11. sage/arith/numerical_approx.pxd +35 -0
  12. sage/arith/numerical_approx.pyx +75 -0
  13. sage/arith/power.cpython-311-darwin.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-311-darwin.so +0 -0
  17. sage/categories/action.pxd +29 -0
  18. sage/categories/action.pyx +641 -0
  19. sage/categories/algebra_functor.py +745 -0
  20. sage/categories/all__sagemath_objects.py +33 -0
  21. sage/categories/basic.py +62 -0
  22. sage/categories/cartesian_product.py +295 -0
  23. sage/categories/category.py +3401 -0
  24. sage/categories/category_cy_helper.cpython-311-darwin.so +0 -0
  25. sage/categories/category_cy_helper.pxd +8 -0
  26. sage/categories/category_cy_helper.pyx +322 -0
  27. sage/categories/category_singleton.cpython-311-darwin.so +0 -0
  28. sage/categories/category_singleton.pxd +3 -0
  29. sage/categories/category_singleton.pyx +342 -0
  30. sage/categories/category_types.py +637 -0
  31. sage/categories/category_with_axiom.py +2876 -0
  32. sage/categories/covariant_functorial_construction.py +703 -0
  33. sage/categories/facade_sets.py +228 -0
  34. sage/categories/functor.cpython-311-darwin.so +0 -0
  35. sage/categories/functor.pxd +7 -0
  36. sage/categories/functor.pyx +691 -0
  37. sage/categories/homset.py +1338 -0
  38. sage/categories/homsets.py +364 -0
  39. sage/categories/isomorphic_objects.py +73 -0
  40. sage/categories/map.cpython-311-darwin.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2106 -0
  43. sage/categories/morphism.cpython-311-darwin.so +0 -0
  44. sage/categories/morphism.pxd +14 -0
  45. sage/categories/morphism.pyx +895 -0
  46. sage/categories/objects.py +167 -0
  47. sage/categories/primer.py +1696 -0
  48. sage/categories/pushout.py +4834 -0
  49. sage/categories/quotients.py +64 -0
  50. sage/categories/realizations.py +200 -0
  51. sage/categories/sets_cat.py +3290 -0
  52. sage/categories/sets_with_partial_maps.py +52 -0
  53. sage/categories/subobjects.py +64 -0
  54. sage/categories/subquotients.py +21 -0
  55. sage/categories/with_realizations.py +311 -0
  56. sage/cpython/__init__.py +19 -0
  57. sage/cpython/_py2_random.py +619 -0
  58. sage/cpython/all.py +3 -0
  59. sage/cpython/atexit.cpython-311-darwin.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-311-darwin.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-311-darwin.so +0 -0
  64. sage/cpython/cython_metaclass.h +117 -0
  65. sage/cpython/cython_metaclass.pxd +3 -0
  66. sage/cpython/cython_metaclass.pyx +130 -0
  67. sage/cpython/debug.cpython-311-darwin.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-311-darwin.so +0 -0
  70. sage/cpython/dict_del_by_value.pxd +9 -0
  71. sage/cpython/dict_del_by_value.pyx +191 -0
  72. sage/cpython/dict_internal.h +245 -0
  73. sage/cpython/getattr.cpython-311-darwin.so +0 -0
  74. sage/cpython/getattr.pxd +9 -0
  75. sage/cpython/getattr.pyx +439 -0
  76. sage/cpython/pycore_long.h +97 -0
  77. sage/cpython/pycore_long.pxd +10 -0
  78. sage/cpython/python_debug.h +44 -0
  79. sage/cpython/python_debug.pxd +47 -0
  80. sage/cpython/pyx_visit.h +13 -0
  81. sage/cpython/string.cpython-311-darwin.so +0 -0
  82. sage/cpython/string.pxd +76 -0
  83. sage/cpython/string.pyx +34 -0
  84. sage/cpython/string_impl.h +60 -0
  85. sage/cpython/type.cpython-311-darwin.so +0 -0
  86. sage/cpython/type.pxd +2 -0
  87. sage/cpython/type.pyx +40 -0
  88. sage/cpython/wrapperdescr.pxd +67 -0
  89. sage/ext/all__sagemath_objects.py +3 -0
  90. sage/ext/ccobject.h +64 -0
  91. sage/ext/cplusplus.pxd +17 -0
  92. sage/ext/mod_int.h +30 -0
  93. sage/ext/mod_int.pxd +24 -0
  94. sage/ext/stdsage.pxd +39 -0
  95. sage/groups/all__sagemath_objects.py +1 -0
  96. sage/groups/group.cpython-311-darwin.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-311-darwin.so +0 -0
  100. sage/groups/old.pxd +14 -0
  101. sage/groups/old.pyx +219 -0
  102. sage/libs/all__sagemath_objects.py +3 -0
  103. sage/libs/gmp/__init__.py +1 -0
  104. sage/libs/gmp/all.pxd +6 -0
  105. sage/libs/gmp/binop.pxd +23 -0
  106. sage/libs/gmp/misc.pxd +8 -0
  107. sage/libs/gmp/mpf.pxd +88 -0
  108. sage/libs/gmp/mpn.pxd +57 -0
  109. sage/libs/gmp/mpq.pxd +57 -0
  110. sage/libs/gmp/mpz.pxd +202 -0
  111. sage/libs/gmp/pylong.cpython-311-darwin.so +0 -0
  112. sage/libs/gmp/pylong.pxd +12 -0
  113. sage/libs/gmp/pylong.pyx +150 -0
  114. sage/libs/gmp/random.pxd +25 -0
  115. sage/libs/gmp/randomize.pxd +59 -0
  116. sage/libs/gmp/types.pxd +53 -0
  117. sage/libs/gmpxx.pxd +19 -0
  118. sage/misc/abstract_method.py +276 -0
  119. sage/misc/all__sagemath_objects.py +43 -0
  120. sage/misc/bindable_class.py +253 -0
  121. sage/misc/c3_controlled.cpython-311-darwin.so +0 -0
  122. sage/misc/c3_controlled.pxd +2 -0
  123. sage/misc/c3_controlled.pyx +1402 -0
  124. sage/misc/cachefunc.cpython-311-darwin.so +0 -0
  125. sage/misc/cachefunc.pxd +43 -0
  126. sage/misc/cachefunc.pyx +3781 -0
  127. sage/misc/call.py +188 -0
  128. sage/misc/classcall_metaclass.cpython-311-darwin.so +0 -0
  129. sage/misc/classcall_metaclass.pxd +14 -0
  130. sage/misc/classcall_metaclass.pyx +599 -0
  131. sage/misc/constant_function.cpython-311-darwin.so +0 -0
  132. sage/misc/constant_function.pyx +130 -0
  133. sage/misc/decorators.py +747 -0
  134. sage/misc/fast_methods.cpython-311-darwin.so +0 -0
  135. sage/misc/fast_methods.pxd +20 -0
  136. sage/misc/fast_methods.pyx +351 -0
  137. sage/misc/flatten.py +90 -0
  138. sage/misc/fpickle.cpython-311-darwin.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-311-darwin.so +0 -0
  141. sage/misc/function_mangling.pxd +11 -0
  142. sage/misc/function_mangling.pyx +308 -0
  143. sage/misc/inherit_comparison.cpython-311-darwin.so +0 -0
  144. sage/misc/inherit_comparison.pxd +5 -0
  145. sage/misc/inherit_comparison.pyx +105 -0
  146. sage/misc/instancedoc.cpython-311-darwin.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-311-darwin.so +0 -0
  149. sage/misc/lazy_attribute.pyx +607 -0
  150. sage/misc/lazy_format.py +135 -0
  151. sage/misc/lazy_import.cpython-311-darwin.so +0 -0
  152. sage/misc/lazy_import.pyx +1299 -0
  153. sage/misc/lazy_import_cache.py +36 -0
  154. sage/misc/lazy_list.cpython-311-darwin.so +0 -0
  155. sage/misc/lazy_list.pxd +19 -0
  156. sage/misc/lazy_list.pyx +1187 -0
  157. sage/misc/lazy_string.cpython-311-darwin.so +0 -0
  158. sage/misc/lazy_string.pxd +7 -0
  159. sage/misc/lazy_string.pyx +546 -0
  160. sage/misc/misc.py +1066 -0
  161. sage/misc/misc_c.cpython-311-darwin.so +0 -0
  162. sage/misc/misc_c.pxd +3 -0
  163. sage/misc/misc_c.pyx +766 -0
  164. sage/misc/namespace_package.py +37 -0
  165. sage/misc/nested_class.cpython-311-darwin.so +0 -0
  166. sage/misc/nested_class.pxd +3 -0
  167. sage/misc/nested_class.pyx +394 -0
  168. sage/misc/persist.cpython-311-darwin.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-311-darwin.so +0 -0
  172. sage/misc/randstate.pxd +30 -0
  173. sage/misc/randstate.pyx +1059 -0
  174. sage/misc/repr.py +203 -0
  175. sage/misc/reset.cpython-311-darwin.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-311-darwin.so +0 -0
  178. sage/misc/sage_ostools.pyx +323 -0
  179. sage/misc/sage_timeit.py +275 -0
  180. sage/misc/sage_timeit_class.cpython-311-darwin.so +0 -0
  181. sage/misc/sage_timeit_class.pyx +120 -0
  182. sage/misc/sage_unittest.py +637 -0
  183. sage/misc/sageinspect.py +2768 -0
  184. sage/misc/session.cpython-311-darwin.so +0 -0
  185. sage/misc/session.pyx +392 -0
  186. sage/misc/superseded.py +557 -0
  187. sage/misc/test_nested_class.py +228 -0
  188. sage/misc/timing.py +264 -0
  189. sage/misc/unknown.py +222 -0
  190. sage/misc/verbose.py +253 -0
  191. sage/misc/weak_dict.cpython-311-darwin.so +0 -0
  192. sage/misc/weak_dict.pxd +15 -0
  193. sage/misc/weak_dict.pyx +1231 -0
  194. sage/modules/all__sagemath_objects.py +1 -0
  195. sage/modules/module.cpython-311-darwin.so +0 -0
  196. sage/modules/module.pxd +5 -0
  197. sage/modules/module.pyx +329 -0
  198. sage/rings/all__sagemath_objects.py +3 -0
  199. sage/rings/integer_fake.h +22 -0
  200. sage/rings/integer_fake.pxd +55 -0
  201. sage/sets/all__sagemath_objects.py +3 -0
  202. sage/sets/pythonclass.cpython-311-darwin.so +0 -0
  203. sage/sets/pythonclass.pxd +9 -0
  204. sage/sets/pythonclass.pyx +247 -0
  205. sage/structure/__init__.py +4 -0
  206. sage/structure/all.py +30 -0
  207. sage/structure/category_object.cpython-311-darwin.so +0 -0
  208. sage/structure/category_object.pxd +28 -0
  209. sage/structure/category_object.pyx +1087 -0
  210. sage/structure/coerce.cpython-311-darwin.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-311-darwin.so +0 -0
  214. sage/structure/coerce_actions.pxd +27 -0
  215. sage/structure/coerce_actions.pyx +988 -0
  216. sage/structure/coerce_dict.cpython-311-darwin.so +0 -0
  217. sage/structure/coerce_dict.pxd +51 -0
  218. sage/structure/coerce_dict.pyx +1557 -0
  219. sage/structure/coerce_exceptions.py +23 -0
  220. sage/structure/coerce_maps.cpython-311-darwin.so +0 -0
  221. sage/structure/coerce_maps.pxd +28 -0
  222. sage/structure/coerce_maps.pyx +718 -0
  223. sage/structure/debug_options.cpython-311-darwin.so +0 -0
  224. sage/structure/debug_options.pxd +6 -0
  225. sage/structure/debug_options.pyx +54 -0
  226. sage/structure/dynamic_class.py +541 -0
  227. sage/structure/element.cpython-311-darwin.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-311-darwin.so +0 -0
  231. sage/structure/element_wrapper.pxd +12 -0
  232. sage/structure/element_wrapper.pyx +582 -0
  233. sage/structure/factorization.py +1422 -0
  234. sage/structure/factorization_integer.py +105 -0
  235. sage/structure/factory.cpython-311-darwin.so +0 -0
  236. sage/structure/factory.pyx +786 -0
  237. sage/structure/formal_sum.py +489 -0
  238. sage/structure/gens_py.py +73 -0
  239. sage/structure/global_options.py +1743 -0
  240. sage/structure/indexed_generators.py +863 -0
  241. sage/structure/list_clone.cpython-311-darwin.so +0 -0
  242. sage/structure/list_clone.pxd +65 -0
  243. sage/structure/list_clone.pyx +1867 -0
  244. sage/structure/list_clone_demo.cpython-311-darwin.so +0 -0
  245. sage/structure/list_clone_demo.pyx +248 -0
  246. sage/structure/list_clone_timings.py +179 -0
  247. sage/structure/list_clone_timings_cy.cpython-311-darwin.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-311-darwin.so +0 -0
  250. sage/structure/mutability.pxd +21 -0
  251. sage/structure/mutability.pyx +348 -0
  252. sage/structure/nonexact.py +69 -0
  253. sage/structure/parent.cpython-311-darwin.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-311-darwin.so +0 -0
  257. sage/structure/parent_base.pxd +13 -0
  258. sage/structure/parent_base.pyx +44 -0
  259. sage/structure/parent_gens.cpython-311-darwin.so +0 -0
  260. sage/structure/parent_gens.pxd +22 -0
  261. sage/structure/parent_gens.pyx +377 -0
  262. sage/structure/parent_old.cpython-311-darwin.so +0 -0
  263. sage/structure/parent_old.pxd +25 -0
  264. sage/structure/parent_old.pyx +294 -0
  265. sage/structure/proof/__init__.py +1 -0
  266. sage/structure/proof/all.py +243 -0
  267. sage/structure/proof/proof.py +300 -0
  268. sage/structure/richcmp.cpython-311-darwin.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-311-darwin.so +0 -0
  272. sage/structure/sage_object.pxd +3 -0
  273. sage/structure/sage_object.pyx +988 -0
  274. sage/structure/sage_object_test.py +19 -0
  275. sage/structure/sequence.py +937 -0
  276. sage/structure/set_factories.py +1178 -0
  277. sage/structure/set_factories_example.py +527 -0
  278. sage/structure/support_view.py +179 -0
  279. sage/structure/test_factory.py +56 -0
  280. sage/structure/unique_representation.py +1359 -0
@@ -0,0 +1,703 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ r"""
3
+ Covariant Functorial Constructions
4
+
5
+ A *functorial construction* is a collection of functors
6
+ `(F_{Cat})_{Cat}` (indexed by a collection of categories) which associate
7
+ to a sequence of parents `(A, B, ...)` in a category `Cat` a parent
8
+ `F_{Cat}(A, B, ...)`. Typical examples of functorial
9
+ constructions are :obj:`cartesian_product` and :obj:`tensor_product`.
10
+
11
+ The category of `F_{Cat}(A, B, ...)`, which only depends on `Cat`, is
12
+ called the (functorial) construction category.
13
+
14
+ A functorial construction is *(category)-covariant* if for every
15
+ categories `Cat` and `SuperCat`, the category of `F_{Cat}(A, B, ...)`
16
+ is a subcategory of the category of `F_{SuperCat}(A, B, ...)` whenever
17
+ `Cat` is a subcategory of `SuperCat`. A functorial construction is
18
+ *(category)-regressive* if the category of `F_{Cat}(A, B, ...)` is a
19
+ subcategory of `Cat`.
20
+
21
+ The goal of this module is to provide generic support for covariant
22
+ functorial constructions. In particular, given some parents `A`, `B`,
23
+ ..., in respective categories `Cat_A`, `Cat_B`, ..., it provides tools
24
+ for calculating the best known category for the parent
25
+ `F(A,B,...)`. For examples, knowing that Cartesian products of
26
+ semigroups (resp. monoids, groups) have a semigroup (resp. monoid,
27
+ group) structure, and given a group `B` and two monoids `A` and `C` it
28
+ can calculate that `A \times B \times C` is naturally endowed with a
29
+ monoid structure.
30
+
31
+ See :class:`CovariantFunctorialConstruction`,
32
+ :class:`CovariantConstructionCategory` and
33
+ :class:`RegressiveCovariantConstructionCategory` for more details.
34
+
35
+ AUTHORS:
36
+
37
+ - Nicolas M. Thiery (2010): initial revision
38
+ """
39
+ #*****************************************************************************
40
+ # Copyright (C) 2010 Nicolas M. Thiery <nthiery at users.sf.net>
41
+ #
42
+ # Distributed under the terms of the GNU General Public License (GPL)
43
+ # http://www.gnu.org/licenses/
44
+ #******************************************************************************
45
+ try:
46
+ from typing import Self # type: ignore (Python >= 3.11)
47
+ except ImportError:
48
+ from typing_extensions import Self # type: ignore (Python 3.10)
49
+
50
+ from sage.categories.category import Category
51
+ from sage.misc.cachefunc import cached_function, cached_method
52
+ from sage.misc.lazy_attribute import lazy_class_attribute
53
+ from sage.misc.lazy_import import LazyImport
54
+ from sage.structure.dynamic_class import DynamicMetaclass
55
+ from sage.structure.sage_object import SageObject
56
+ from sage.structure.unique_representation import UniqueRepresentation
57
+
58
+
59
+ class CovariantFunctorialConstruction(UniqueRepresentation, SageObject):
60
+ r"""
61
+ An abstract class for construction functors `F` (eg `F` = Cartesian
62
+ product, tensor product, `\QQ`-algebra, ...) such that:
63
+
64
+ - Each category `Cat` (eg `Cat=` ``Groups()``) can provide a category
65
+ `F_{Cat}` for parents constructed via this functor (e.g.
66
+ `F_{Cat} =` ``CartesianProductsOf(Groups())``).
67
+
68
+ - For every category `Cat`, `F_{Cat}` is a subcategory of
69
+ `F_{SuperCat}` for every super category `SuperCat` of
70
+ `Cat` (the functorial construction is (category)-covariant).
71
+
72
+ - For parents `A`, `B`, ..., respectively in the categories
73
+ `Cat_A`, `Cat_B`, ..., the category of `F(A,B,...)` is
74
+ `F_{Cat}` where `Cat` is the meet of the categories `Cat_A`,
75
+ `Cat_B`, ...,.
76
+
77
+ This covers two slightly different use cases:
78
+
79
+ - In the first use case, one uses directly the construction
80
+ functor to create new parents::
81
+
82
+ sage: tensor() # todo: not implemented (add an example)
83
+
84
+ or even new elements, which indirectly constructs the
85
+ corresponding parent::
86
+
87
+ sage: tensor(...) # todo: not implemented
88
+
89
+ - In the second use case, one implements a parent, and then put
90
+ it in the category `F_{Cat}` to specify supplementary
91
+ mathematical information about that parent.
92
+
93
+ The main purpose of this class is to handle automatically the
94
+ trivial part of the category hierarchy. For example,
95
+ ``CartesianProductsOf(Groups())`` is set automatically as a
96
+ subcategory of ``CartesianProductsOf(Monoids())``.
97
+
98
+ In practice, each subclass of this class should provide the
99
+ following attributes:
100
+
101
+ - ``_functor_category`` -- string which should match the name of
102
+ the nested category class to be used in each category to
103
+ specify information and generic operations for elements of this
104
+ category
105
+
106
+ - ``_functor_name`` -- string which specifies the name of the
107
+ functor, and also (when relevant) of the method on parents and
108
+ elements used for calling the construction
109
+
110
+ TODO: What syntax do we want for `F_{Cat}`? For example, for the
111
+ tensor product construction, which one do we want among (see
112
+ chat on IRC, on 07/12/2009):
113
+
114
+ - ``tensor(Cat)``
115
+ - ``tensor((Cat, Cat))``
116
+ - ``tensor.of((Cat, Cat))``
117
+ - ``tensor.category_from_categories((Cat, Cat, Cat))``
118
+ - ``Cat.TensorProducts()``
119
+
120
+ The syntax ``Cat.TensorProducts()`` does not supports well multivariate
121
+ constructions like ``tensor.of([Algebras(), HopfAlgebras(), ...])``.
122
+ Also it forces every category to be (somehow) aware of all the
123
+ tensorial construction that could apply to it, even those which
124
+ are only induced from super categories.
125
+
126
+ Note: for each functorial construction, there probably is one (or several)
127
+ largest categories on which it applies. For example, the
128
+ :func:`~sage.categories.cartesian_product.CartesianProducts` construction makes
129
+ only sense for concrete categories, that is subcategories of
130
+ ``Sets()``. Maybe we want to model this one way or the other.
131
+ """
132
+
133
+ def category_from_parents(self, parents):
134
+ """
135
+ Return the category of `F(A,B,...)` for `A,B,...` parents.
136
+
137
+ INPUT:
138
+
139
+ - ``self`` -- a functor `F`
140
+ - ``parents`` -- a list (or iterable) of parents
141
+
142
+ EXAMPLES::
143
+
144
+ sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]) # needs sage.modules
145
+ sage: tensor.category_from_parents((E, E, E)) # needs sage.modules
146
+ Category of tensor products of
147
+ finite dimensional vector spaces with basis over Rational Field
148
+ """
149
+ from sage.structure.parent import Parent
150
+ assert all(isinstance(parent, Parent) for parent in parents)
151
+ # Should we pass a set of categories to reduce the cache size?
152
+ # But then this would impose that, for any constructor, the
153
+ # category of the result does not depend on the order/repetition
154
+ # of the categories of the parents
155
+ return self.category_from_categories(tuple({parent.category() for parent in parents}))
156
+
157
+ @cached_method
158
+ def category_from_categories(self, categories):
159
+ """
160
+ Return the category of `F(A,B,...)` for `A,B,...` parents in
161
+ the given categories.
162
+
163
+ INPUT:
164
+
165
+ - ``self`` -- a functor `F`
166
+ - ``categories`` -- a non empty tuple of categories
167
+
168
+ EXAMPLES::
169
+
170
+ sage: Cat1 = Rings()
171
+ sage: Cat2 = Groups()
172
+ sage: cartesian_product.category_from_categories((Cat1, Cat1, Cat1))
173
+ Join of Category of rings and ...
174
+ and Category of Cartesian products of monoids
175
+ and Category of Cartesian products of commutative additive groups
176
+
177
+ sage: cartesian_product.category_from_categories((Cat1, Cat2))
178
+ Category of Cartesian products of monoids
179
+ """
180
+ assert len(categories) > 0
181
+ return self.category_from_category(Category.meet(categories))
182
+
183
+ def category_from_category(self, category):
184
+ """
185
+ Return the category of `F(A,B,...)` for `A,B,...` parents in
186
+ ``category``.
187
+
188
+ INPUT:
189
+
190
+ - ``self`` -- a functor `F`
191
+ - ``category`` -- a category
192
+
193
+ EXAMPLES::
194
+
195
+ sage: tensor.category_from_category(ModulesWithBasis(QQ))
196
+ Category of tensor products of vector spaces with basis over Rational Field
197
+
198
+ # TODO: add support for parametrized functors
199
+ """
200
+ return getattr(category, self._functor_category)()
201
+
202
+ def _repr_(self):
203
+ """
204
+ EXAMPLES::
205
+
206
+ sage: tensor # indirect doctest
207
+ The tensor functorial construction
208
+ """
209
+ return "The %s functorial construction" % self._functor_name
210
+
211
+ def __call__(self, args, **kwargs):
212
+ """
213
+ Functorial construction application.
214
+
215
+ INPUT:
216
+
217
+ - ``self`` -- a covariant functorial construction `F`
218
+ - ``args`` -- a tuple (or iterable) of parents or elements
219
+
220
+ Returns `F(args)`
221
+
222
+ EXAMPLES::
223
+
224
+ sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]); E.rename('E') # needs sage.modules
225
+ sage: tensor((E, E, E)) # needs sage.modules
226
+ E # E # E
227
+ """
228
+ args = tuple(args) # a bit brute force; let's see if this becomes a bottleneck later
229
+ assert all(hasattr(arg, self._functor_name) for arg in args)
230
+ assert len(args) > 0
231
+ return getattr(args[0], self._functor_name)(*args[1:], **kwargs)
232
+
233
+
234
+ class FunctorialConstructionCategory(Category): # Should this be CategoryWithBase?
235
+ """
236
+ Abstract class for categories `F_{Cat}` obtained through a
237
+ functorial construction
238
+ """
239
+
240
+ @lazy_class_attribute
241
+ def _base_category_class(cls):
242
+ """
243
+ Recover the class of the base category.
244
+
245
+ OUTPUT: a *tuple* whose single entry is the base category class
246
+
247
+ .. WARNING::
248
+
249
+ This is only used for functorial construction categories
250
+ that are not implemented as nested classes, and won't work
251
+ otherwise.
252
+
253
+ .. SEEALSO:: :meth:`__classcall__`
254
+
255
+ EXAMPLES::
256
+
257
+ sage: GradedModules._base_category_class
258
+ (<class 'sage.categories.modules.Modules'>,)
259
+ sage: GradedAlgebrasWithBasis._base_category_class
260
+ (<class 'sage.categories.algebras_with_basis.AlgebrasWithBasis'>,)
261
+
262
+ The reason for wrapping the base category class in a tuple is
263
+ that, often, the base category class implements a
264
+ :meth:`__classget__` method which would get in the way upon
265
+ attribute access::
266
+
267
+ sage: F = GradedAlgebrasWithBasis
268
+ sage: F._foo = F._base_category_class[0]
269
+ sage: F._foo
270
+ Traceback (most recent call last):
271
+ ...
272
+ AssertionError: base category class for <...AlgebrasWithBasis'>
273
+ mismatch; expected <...Algebras'>,
274
+ got <...GradedAlgebrasWithBasis'>
275
+
276
+ We note that because ``Algebras.WithBasis`` is not lazily imported
277
+ on startup (see :issue:`22955`), the test fails at a different
278
+ point in the code. However, if this import becomes lazy again, then
279
+ the following error will be generated and can replace the above::
280
+
281
+ sage: F._foo # not tested
282
+ Traceback (most recent call last):
283
+ ...
284
+ ValueError: could not infer axiom for the nested class
285
+ <...AlgebrasWithBasis'> of <...GradedAlgebrasWithBasis'>
286
+
287
+ .. TODO::
288
+
289
+ The logic is very similar to that implemented in
290
+ :class:`CategoryWithAxiom._base_category_class`. Find a
291
+ way to refactor this to avoid the duplication.
292
+ """
293
+ module_name = cls.__module__.replace(cls._functor_category.lower() + "_","")
294
+ import sys
295
+ name = cls.__name__.replace(cls._functor_category, "")
296
+ __import__(module_name)
297
+ module = sys.modules[module_name]
298
+ return (module.__dict__[name],)
299
+
300
+ @staticmethod
301
+ def __classcall__(cls, category=None, *args):
302
+ """
303
+ Make ``XXXCat(**)`` a shorthand for ``Cat(**).XXX()``.
304
+
305
+ EXAMPLES::
306
+
307
+ sage: GradedModules(ZZ) # indirect doctest
308
+ Category of graded modules over Integer Ring
309
+ sage: Modules(ZZ).Graded()
310
+ Category of graded modules over Integer Ring
311
+ sage: Modules.Graded(ZZ)
312
+ Category of graded modules over Integer Ring
313
+ sage: GradedModules(ZZ) is Modules(ZZ).Graded()
314
+ True
315
+
316
+ .. SEEALSO:: :meth:`_base_category_class`
317
+
318
+ .. TODO::
319
+
320
+ The logic is very similar to that implemented in
321
+ :class:`CategoryWithAxiom.__classcall__`. Find a way to
322
+ refactor this to avoid the duplication.
323
+ """
324
+ base_category_class = cls._base_category_class[0]
325
+ if isinstance(category, base_category_class):
326
+ return super().__classcall__(cls, category, *args)
327
+ else:
328
+ return cls.category_of(base_category_class(category, *args))
329
+
330
+ @staticmethod
331
+ def __classget__(cls, base_category, base_category_class):
332
+ r"""
333
+ Special binding for covariant constructions.
334
+
335
+ This implements a hack allowing e.g. ``category.Subquotients``
336
+ to recover the default ``Subquotients`` method defined in
337
+ ``Category``, even if it has been overridden by a
338
+ ``Subquotients`` class.
339
+
340
+ EXAMPLES::
341
+
342
+ sage: Sets.Subquotients
343
+ <class 'sage.categories.sets_cat.Sets.Subquotients'>
344
+ sage: Sets().Subquotients
345
+ Cached version of <function ...Subquotients at ...>
346
+
347
+ This method also initializes the attribute
348
+ ``_base_category_class`` if not already set::
349
+
350
+ sage: Sets.Subquotients._base_category_class
351
+ (<class 'sage.categories.sets_cat.Sets'>,)
352
+
353
+ It also forces the resolution of lazy imports (see :issue:`15648`)::
354
+
355
+ sage: type(Algebras.__dict__["Graded"])
356
+ <class 'sage.misc.lazy_import.LazyImport'>
357
+ sage: Algebras.Graded
358
+ <class 'sage.categories.graded_algebras.GradedAlgebras'>
359
+ sage: type(Algebras.__dict__["Graded"])
360
+ <class 'sage.misc.classcall_metaclass.ClasscallMetaclass'>
361
+
362
+ .. TODO::
363
+
364
+ The logic is very similar to that implemented in
365
+ :class:`CategoryWithAxiom.__classget__`. Find a way to
366
+ refactor this to avoid the duplication.
367
+ """
368
+ if base_category is not None:
369
+ assert base_category.__class__ is base_category_class
370
+ assert isinstance(base_category_class, DynamicMetaclass)
371
+ if isinstance(base_category_class, DynamicMetaclass):
372
+ base_category_class = base_category_class.__base__
373
+ if "_base_category_class" not in cls.__dict__:
374
+ cls._base_category_class = (base_category_class,)
375
+ else:
376
+ assert cls._base_category_class[0] is base_category_class, \
377
+ "base category class for {} mismatch; expected {}, got {}".format(
378
+ cls, cls._base_category_class[0], base_category_class)
379
+
380
+ # Workaround #15648: if Sets.Subquotients is a LazyImport object,
381
+ # this forces the substitution of the object back into Sets
382
+ # to avoid resolving the lazy import over and over
383
+ if isinstance(base_category_class.__dict__[cls._functor_category], LazyImport):
384
+ setattr(base_category_class, cls._functor_category, cls)
385
+ if base_category is None:
386
+ return cls
387
+ return getattr(super(base_category.__class__.__base__, base_category),
388
+ cls._functor_category)
389
+
390
+ @classmethod
391
+ @cached_function
392
+ def category_of(cls, category, *args):
393
+ """
394
+ Return the image category of the functor `F_{Cat}`.
395
+
396
+ This is the main entry point for constructing the category
397
+ `F_{Cat}` of parents `F(A,B,...)` constructed from parents
398
+ `A,B,...` in `Cat`.
399
+
400
+ INPUT:
401
+
402
+ - ``cls`` -- the category class for the functorial construction `F`
403
+ - ``category`` -- a category `Cat`
404
+ - ``*args`` -- further arguments for the functor
405
+
406
+ EXAMPLES::
407
+
408
+ sage: C = sage.categories.tensor.TensorProductsCategory
409
+ sage: C.category_of(ModulesWithBasis(QQ))
410
+ Category of tensor products of vector spaces with basis over Rational Field
411
+
412
+ sage: C = sage.categories.algebra_functor.AlgebrasCategory
413
+ sage: C.category_of(FiniteMonoids(), QQ)
414
+ Join of Category of finite dimensional algebras with basis over Rational Field
415
+ and Category of monoid algebras over Rational Field
416
+ and Category of finite set algebras over Rational Field
417
+ """
418
+ # TODO: find a better test
419
+ # the purpose is to test whether ``category`` implements that functor
420
+ functor_category = getattr(category.__class__, cls._functor_category)
421
+ if isinstance(functor_category, type) and issubclass(functor_category, Category):
422
+ return functor_category(category, *args)
423
+ else:
424
+ return cls.default_super_categories(category, *args)
425
+
426
+ def __init__(self, category, *args):
427
+ r"""
428
+ TESTS::
429
+
430
+ sage: from sage.categories.covariant_functorial_construction import CovariantConstructionCategory
431
+ sage: class FooBars(CovariantConstructionCategory):
432
+ ....: _functor_category = "FooBars"
433
+ ....: _base_category_class = (Category,)
434
+ sage: Category.FooBars = lambda self: FooBars.category_of(self)
435
+ sage: C = FooBars(ModulesWithBasis(ZZ))
436
+ sage: C
437
+ Category of foo bars of modules with basis over Integer Ring
438
+ sage: C.base_category()
439
+ Category of modules with basis over Integer Ring
440
+ sage: latex(C)
441
+ \mathbf{FooBars}(\mathbf{ModulesWithBasis}_{\Bold{Z}})
442
+ sage: import __main__; __main__.FooBars = FooBars # Fake FooBars being defined in a python module
443
+ sage: TestSuite(C).run()
444
+ """
445
+ assert isinstance(category, Category)
446
+ self._base_category = category
447
+ self._args = args
448
+ super().__init__(*args)
449
+
450
+ def base_category(self):
451
+ """
452
+ Return the base category of the category ``self``.
453
+
454
+ For any category ``B`` = `F_{Cat}` obtained through a functorial
455
+ construction `F`, the call ``B.base_category()`` returns the
456
+ category `Cat`.
457
+
458
+ EXAMPLES::
459
+
460
+ sage: Semigroups().Quotients().base_category()
461
+ Category of semigroups
462
+ """
463
+ return self._base_category
464
+
465
+ def extra_super_categories(self):
466
+ """
467
+ Return the extra super categories of a construction category.
468
+
469
+ Default implementation which returns ``[]``.
470
+
471
+ EXAMPLES::
472
+
473
+ sage: Sets().Subquotients().extra_super_categories()
474
+ []
475
+ sage: Semigroups().Quotients().extra_super_categories()
476
+ []
477
+ """
478
+ return []
479
+
480
+ def super_categories(self):
481
+ """
482
+ Return the super categories of a construction category.
483
+
484
+ EXAMPLES::
485
+
486
+ sage: Sets().Subquotients().super_categories()
487
+ [Category of sets]
488
+ sage: Semigroups().Quotients().super_categories()
489
+ [Category of subquotients of semigroups, Category of quotients of sets]
490
+ """
491
+ return Category.join([self.__class__.default_super_categories(self.base_category(), *self._args)] +
492
+ self.extra_super_categories(),
493
+ as_list=True)
494
+
495
+ def _repr_object_names(self):
496
+ """
497
+ EXAMPLES::
498
+
499
+ sage: Semigroups().Subquotients() # indirect doctest
500
+ Category of subquotients of semigroups
501
+ """
502
+ return "%s of %s" % (Category._repr_object_names(self), self.base_category()._repr_object_names())
503
+
504
+ def _latex_(self):
505
+ r"""
506
+ EXAMPLES::
507
+
508
+ sage: latex(Semigroups().Subquotients()) # indirect doctest
509
+ \mathbf{Subquotients}(\mathbf{Semigroups})
510
+ sage: latex(ModulesWithBasis(QQ).TensorProducts())
511
+ \mathbf{TensorProducts}(\mathbf{WithBasis}_{\Bold{Q}})
512
+ sage: latex(Semigroups().Algebras(QQ))
513
+ \mathbf{Algebras}(\mathbf{Semigroups})
514
+ """
515
+ from sage.misc.latex import latex
516
+ return "\\mathbf{%s}(%s)" % (self._short_name(), latex(self.base_category()))
517
+
518
+
519
+ class CovariantConstructionCategory(FunctorialConstructionCategory):
520
+ """
521
+ Abstract class for categories `F_{Cat}` obtained through a
522
+ covariant functorial construction
523
+ """
524
+
525
+ @classmethod
526
+ def default_super_categories(cls, category, *args):
527
+ r"""
528
+ Return the default super categories of `F_{Cat}(A,B,...)` for
529
+ `A,B,...` parents in `Cat`.
530
+
531
+ INPUT:
532
+
533
+ - ``cls`` -- the category class for the functor `F`
534
+ - ``category`` -- a category `Cat`
535
+ - ``*args`` -- further arguments for the functor
536
+
537
+ OUTPUT: a (join) category
538
+
539
+ The default implementation is to return the join of the
540
+ categories of `F(A,B,...)` for `A,B,...` in turn in each of
541
+ the super categories of ``category``.
542
+
543
+ This is implemented as a class method, in order to be able to
544
+ reconstruct the functorial category associated to each of the
545
+ super categories of ``category``.
546
+
547
+ EXAMPLES:
548
+
549
+ Bialgebras are both algebras and coalgebras::
550
+
551
+ sage: Bialgebras(QQ).super_categories()
552
+ [Category of algebras over Rational Field,
553
+ Category of coalgebras over Rational Field]
554
+
555
+ Hence tensor products of bialgebras are tensor products of
556
+ algebras and tensor products of coalgebras::
557
+
558
+ sage: Bialgebras(QQ).TensorProducts().super_categories()
559
+ [Category of tensor products of algebras over Rational Field,
560
+ Category of tensor products of coalgebras over Rational Field]
561
+
562
+ Here is how :meth:`default_super_categories` was called internally::
563
+
564
+ sage: C = sage.categories.tensor.TensorProductsCategory
565
+ sage: C.default_super_categories(Bialgebras(QQ))
566
+ Join of Category of tensor products of algebras over Rational Field
567
+ and Category of tensor products of coalgebras over Rational Field
568
+
569
+ We now show a similar example, with the ``Algebra`` functor
570
+ which takes a parameter `\QQ`::
571
+
572
+ sage: FiniteMonoids().super_categories()
573
+ [Category of monoids, Category of finite semigroups]
574
+ sage: sorted(FiniteMonoids().Algebras(QQ).super_categories(), key=str)
575
+ [Category of finite dimensional algebras with basis over Rational Field,
576
+ Category of finite set algebras over Rational Field,
577
+ Category of monoid algebras over Rational Field]
578
+
579
+ Note that neither the category of *finite* semigroup algebras
580
+ nor that of monoid algebras appear in the result; this is
581
+ because there is currently nothing specific implemented about them.
582
+
583
+ Here is how :meth:`default_super_categories` was called internally::
584
+
585
+ sage: C = sage.categories.algebra_functor.AlgebrasCategory
586
+ sage: C.default_super_categories(FiniteMonoids(), QQ)
587
+ Join of Category of finite dimensional algebras with basis over Rational Field
588
+ and Category of monoid algebras over Rational Field
589
+ and Category of finite set algebras over Rational Field
590
+ """
591
+ return Category.join([getattr(cat, cls._functor_category)(*args)
592
+ for cat in category._super_categories
593
+ if hasattr(cat, cls._functor_category)])
594
+
595
+ def is_construction_defined_by_base(self):
596
+ r"""
597
+ Return whether the construction is defined by the base of ``self``.
598
+
599
+ EXAMPLES:
600
+
601
+ The graded functorial construction is defined by the modules
602
+ category. Hence this method returns ``True`` for graded
603
+ modules and ``False`` for other graded xxx categories::
604
+
605
+ sage: Modules(ZZ).Graded().is_construction_defined_by_base()
606
+ True
607
+ sage: Algebras(QQ).Graded().is_construction_defined_by_base()
608
+ False
609
+ sage: Modules(ZZ).WithBasis().Graded().is_construction_defined_by_base()
610
+ False
611
+
612
+ This is implemented as follows: given the base category `A`
613
+ and the construction `F` of ``self``, that is ``self=A.F()``,
614
+ check whether no super category of `A` has `F` defined.
615
+
616
+ .. NOTE::
617
+
618
+ Recall that, when `A` does not implement the construction
619
+ ``F``, a join category is returned. Therefore, in such
620
+ cases, this method is not available::
621
+
622
+ sage: Bialgebras(QQ).Graded().is_construction_defined_by_base()
623
+ Traceback (most recent call last):
624
+ ...
625
+ AttributeError: 'JoinCategory_with_category' object has
626
+ no attribute 'is_construction_defined_by_base'
627
+ """
628
+ base = self.base_category()
629
+ f = self._functor_category
630
+ return not any(hasattr(C, f) for C in base.super_categories())
631
+
632
+ def additional_structure(self) -> Self | None:
633
+ r"""
634
+ Return the additional structure defined by ``self``.
635
+
636
+ By default, a functorial construction category ``A.F()``
637
+ defines additional structure if and only if `A` is the
638
+ category defining `F`. The rationale is that, for a
639
+ subcategory `B` of `A`, the fact that `B.F()` morphisms shall
640
+ preserve the `F`-specific structure is already imposed by
641
+ `A.F()`.
642
+
643
+ .. SEEALSO::
644
+
645
+ - :meth:`Category.additional_structure`.
646
+ - :meth:`is_construction_defined_by_base`.
647
+
648
+ EXAMPLES::
649
+
650
+ sage: Modules(ZZ).Graded().additional_structure()
651
+ Category of graded modules over Integer Ring
652
+ sage: Algebras(ZZ).Graded().additional_structure()
653
+
654
+ TESTS::
655
+
656
+ sage: Modules(ZZ).Graded().additional_structure.__module__
657
+ 'sage.categories.covariant_functorial_construction'
658
+ """
659
+ if self.is_construction_defined_by_base():
660
+ return self
661
+ else:
662
+ return None
663
+
664
+
665
+ class RegressiveCovariantConstructionCategory(CovariantConstructionCategory):
666
+ """
667
+ Abstract class for categories `F_{Cat}` obtained through a
668
+ regressive covariant functorial construction
669
+ """
670
+
671
+ @classmethod
672
+ def default_super_categories(cls, category, *args):
673
+ """
674
+ Return the default super categories of `F_{Cat}(A,B,...)` for
675
+ `A,B,...` parents in `Cat`.
676
+
677
+ INPUT:
678
+
679
+ - ``cls`` -- the category class for the functor `F`
680
+ - ``category`` -- a category `Cat`
681
+ - ``*args`` -- further arguments for the functor
682
+
683
+ OUTPUT: a join category
684
+
685
+ This implements the property that an induced subcategory is a
686
+ subcategory.
687
+
688
+ EXAMPLES:
689
+
690
+ A subquotient of a monoid is a monoid, and a subquotient of
691
+ semigroup::
692
+
693
+ sage: Monoids().Subquotients().super_categories()
694
+ [Category of monoids, Category of subquotients of semigroups]
695
+
696
+ TESTS::
697
+
698
+ sage: C = Monoids().Subquotients()
699
+ sage: C.__class__.default_super_categories(C.base_category(), *C._args)
700
+ Category of unital subquotients of semigroups
701
+ """
702
+ return Category.join([category,
703
+ super().default_super_categories(category, *args)])