passagemath-objects 10.6.41__cp312-cp312-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 (281) hide show
  1. passagemath_objects/__init__.py +3 -0
  2. passagemath_objects-10.6.41.dist-info/DELVEWHEEL +2 -0
  3. passagemath_objects-10.6.41.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.41.dist-info/RECORD +281 -0
  5. passagemath_objects-10.6.41.dist-info/WHEEL +5 -0
  6. passagemath_objects-10.6.41.dist-info/top_level.txt +3 -0
  7. passagemath_objects.libs/libgmp-10-79b4110c7ea2b760f16cfef97e8a8a34.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.cp312-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.cp312-win_amd64.pyd +0 -0
  15. sage/arith/power.pxd +31 -0
  16. sage/arith/power.pyx +127 -0
  17. sage/categories/action.cp312-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 +295 -0
  24. sage/categories/category.py +3401 -0
  25. sage/categories/category_cy_helper.cp312-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.cp312-win_amd64.pyd +0 -0
  29. sage/categories/category_singleton.pxd +3 -0
  30. sage/categories/category_singleton.pyx +342 -0
  31. sage/categories/category_types.py +637 -0
  32. sage/categories/category_with_axiom.py +2885 -0
  33. sage/categories/covariant_functorial_construction.py +703 -0
  34. sage/categories/facade_sets.py +228 -0
  35. sage/categories/functor.cp312-win_amd64.pyd +0 -0
  36. sage/categories/functor.pxd +7 -0
  37. sage/categories/functor.pyx +691 -0
  38. sage/categories/homset.py +1338 -0
  39. sage/categories/homsets.py +364 -0
  40. sage/categories/isomorphic_objects.py +73 -0
  41. sage/categories/map.cp312-win_amd64.pyd +0 -0
  42. sage/categories/map.pxd +34 -0
  43. sage/categories/map.pyx +2112 -0
  44. sage/categories/morphism.cp312-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 +1696 -0
  49. sage/categories/pushout.py +4834 -0
  50. sage/categories/quotients.py +64 -0
  51. sage/categories/realizations.py +200 -0
  52. sage/categories/sets_cat.py +3228 -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 +28 -0
  58. sage/cpython/_py2_random.py +619 -0
  59. sage/cpython/all.py +3 -0
  60. sage/cpython/atexit.cp312-win_amd64.pyd +0 -0
  61. sage/cpython/atexit.pyx +269 -0
  62. sage/cpython/builtin_types.cp312-win_amd64.pyd +0 -0
  63. sage/cpython/builtin_types.pyx +7 -0
  64. sage/cpython/cython_metaclass.cp312-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.cp312-win_amd64.pyd +0 -0
  69. sage/cpython/debug.pyx +302 -0
  70. sage/cpython/dict_del_by_value.cp312-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 +245 -0
  74. sage/cpython/getattr.cp312-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.cp312-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.cp312-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.cp312-win_amd64.pyd +0 -0
  98. sage/groups/group.pxd +14 -0
  99. sage/groups/group.pyx +322 -0
  100. sage/groups/old.cp312-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.cp312-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.cp312-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.cp312-win_amd64.pyd +0 -0
  126. sage/misc/cachefunc.pxd +43 -0
  127. sage/misc/cachefunc.pyx +3781 -0
  128. sage/misc/call.py +188 -0
  129. sage/misc/classcall_metaclass.cp312-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.cp312-win_amd64.pyd +0 -0
  133. sage/misc/constant_function.pyx +130 -0
  134. sage/misc/decorators.py +747 -0
  135. sage/misc/fast_methods.cp312-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.cp312-win_amd64.pyd +0 -0
  140. sage/misc/fpickle.pyx +177 -0
  141. sage/misc/function_mangling.cp312-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.cp312-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.cp312-win_amd64.pyd +0 -0
  148. sage/misc/instancedoc.pyx +331 -0
  149. sage/misc/lazy_attribute.cp312-win_amd64.pyd +0 -0
  150. sage/misc/lazy_attribute.pyx +607 -0
  151. sage/misc/lazy_format.py +135 -0
  152. sage/misc/lazy_import.cp312-win_amd64.pyd +0 -0
  153. sage/misc/lazy_import.pyx +1299 -0
  154. sage/misc/lazy_import_cache.py +36 -0
  155. sage/misc/lazy_list.cp312-win_amd64.pyd +0 -0
  156. sage/misc/lazy_list.pxd +19 -0
  157. sage/misc/lazy_list.pyx +1187 -0
  158. sage/misc/lazy_string.cp312-win_amd64.pyd +0 -0
  159. sage/misc/lazy_string.pxd +7 -0
  160. sage/misc/lazy_string.pyx +546 -0
  161. sage/misc/misc.py +1066 -0
  162. sage/misc/misc_c.cp312-win_amd64.pyd +0 -0
  163. sage/misc/misc_c.pxd +3 -0
  164. sage/misc/misc_c.pyx +766 -0
  165. sage/misc/namespace_package.py +37 -0
  166. sage/misc/nested_class.cp312-win_amd64.pyd +0 -0
  167. sage/misc/nested_class.pxd +3 -0
  168. sage/misc/nested_class.pyx +394 -0
  169. sage/misc/persist.cp312-win_amd64.pyd +0 -0
  170. sage/misc/persist.pyx +1251 -0
  171. sage/misc/prandom.py +418 -0
  172. sage/misc/randstate.cp312-win_amd64.pyd +0 -0
  173. sage/misc/randstate.pxd +30 -0
  174. sage/misc/randstate.pyx +1059 -0
  175. sage/misc/repr.py +203 -0
  176. sage/misc/reset.cp312-win_amd64.pyd +0 -0
  177. sage/misc/reset.pyx +196 -0
  178. sage/misc/sage_ostools.cp312-win_amd64.pyd +0 -0
  179. sage/misc/sage_ostools.pyx +323 -0
  180. sage/misc/sage_timeit.py +276 -0
  181. sage/misc/sage_timeit_class.cp312-win_amd64.pyd +0 -0
  182. sage/misc/sage_timeit_class.pyx +120 -0
  183. sage/misc/sage_unittest.py +637 -0
  184. sage/misc/sageinspect.py +2768 -0
  185. sage/misc/session.cp312-win_amd64.pyd +0 -0
  186. sage/misc/session.pyx +392 -0
  187. sage/misc/superseded.py +557 -0
  188. sage/misc/test_nested_class.py +228 -0
  189. sage/misc/timing.py +264 -0
  190. sage/misc/unknown.py +222 -0
  191. sage/misc/verbose.py +253 -0
  192. sage/misc/weak_dict.cp312-win_amd64.pyd +0 -0
  193. sage/misc/weak_dict.pxd +15 -0
  194. sage/misc/weak_dict.pyx +1231 -0
  195. sage/modules/all__sagemath_objects.py +1 -0
  196. sage/modules/module.cp312-win_amd64.pyd +0 -0
  197. sage/modules/module.pxd +5 -0
  198. sage/modules/module.pyx +329 -0
  199. sage/rings/all__sagemath_objects.py +3 -0
  200. sage/rings/integer_fake.h +22 -0
  201. sage/rings/integer_fake.pxd +55 -0
  202. sage/sets/all__sagemath_objects.py +3 -0
  203. sage/sets/pythonclass.cp312-win_amd64.pyd +0 -0
  204. sage/sets/pythonclass.pxd +9 -0
  205. sage/sets/pythonclass.pyx +247 -0
  206. sage/structure/__init__.py +13 -0
  207. sage/structure/all.py +30 -0
  208. sage/structure/category_object.cp312-win_amd64.pyd +0 -0
  209. sage/structure/category_object.pxd +28 -0
  210. sage/structure/category_object.pyx +1087 -0
  211. sage/structure/coerce.cp312-win_amd64.pyd +0 -0
  212. sage/structure/coerce.pxd +44 -0
  213. sage/structure/coerce.pyx +2107 -0
  214. sage/structure/coerce_actions.cp312-win_amd64.pyd +0 -0
  215. sage/structure/coerce_actions.pxd +27 -0
  216. sage/structure/coerce_actions.pyx +988 -0
  217. sage/structure/coerce_dict.cp312-win_amd64.pyd +0 -0
  218. sage/structure/coerce_dict.pxd +51 -0
  219. sage/structure/coerce_dict.pyx +1557 -0
  220. sage/structure/coerce_exceptions.py +23 -0
  221. sage/structure/coerce_maps.cp312-win_amd64.pyd +0 -0
  222. sage/structure/coerce_maps.pxd +28 -0
  223. sage/structure/coerce_maps.pyx +718 -0
  224. sage/structure/debug_options.cp312-win_amd64.pyd +0 -0
  225. sage/structure/debug_options.pxd +6 -0
  226. sage/structure/debug_options.pyx +54 -0
  227. sage/structure/dynamic_class.py +541 -0
  228. sage/structure/element.cp312-win_amd64.pyd +0 -0
  229. sage/structure/element.pxd +272 -0
  230. sage/structure/element.pyx +4772 -0
  231. sage/structure/element_wrapper.cp312-win_amd64.pyd +0 -0
  232. sage/structure/element_wrapper.pxd +12 -0
  233. sage/structure/element_wrapper.pyx +582 -0
  234. sage/structure/factorization.py +1422 -0
  235. sage/structure/factorization_integer.py +105 -0
  236. sage/structure/factory.cp312-win_amd64.pyd +0 -0
  237. sage/structure/factory.pyx +786 -0
  238. sage/structure/formal_sum.py +489 -0
  239. sage/structure/gens_py.py +73 -0
  240. sage/structure/global_options.py +1743 -0
  241. sage/structure/indexed_generators.py +863 -0
  242. sage/structure/list_clone.cp312-win_amd64.pyd +0 -0
  243. sage/structure/list_clone.pxd +65 -0
  244. sage/structure/list_clone.pyx +1867 -0
  245. sage/structure/list_clone_demo.cp312-win_amd64.pyd +0 -0
  246. sage/structure/list_clone_demo.pyx +248 -0
  247. sage/structure/list_clone_timings.py +179 -0
  248. sage/structure/list_clone_timings_cy.cp312-win_amd64.pyd +0 -0
  249. sage/structure/list_clone_timings_cy.pyx +86 -0
  250. sage/structure/mutability.cp312-win_amd64.pyd +0 -0
  251. sage/structure/mutability.pxd +21 -0
  252. sage/structure/mutability.pyx +348 -0
  253. sage/structure/nonexact.py +69 -0
  254. sage/structure/parent.cp312-win_amd64.pyd +0 -0
  255. sage/structure/parent.pxd +112 -0
  256. sage/structure/parent.pyx +3093 -0
  257. sage/structure/parent_base.cp312-win_amd64.pyd +0 -0
  258. sage/structure/parent_base.pxd +13 -0
  259. sage/structure/parent_base.pyx +44 -0
  260. sage/structure/parent_gens.cp312-win_amd64.pyd +0 -0
  261. sage/structure/parent_gens.pxd +22 -0
  262. sage/structure/parent_gens.pyx +377 -0
  263. sage/structure/parent_old.cp312-win_amd64.pyd +0 -0
  264. sage/structure/parent_old.pxd +25 -0
  265. sage/structure/parent_old.pyx +294 -0
  266. sage/structure/proof/__init__.py +1 -0
  267. sage/structure/proof/all.py +243 -0
  268. sage/structure/proof/proof.py +300 -0
  269. sage/structure/richcmp.cp312-win_amd64.pyd +0 -0
  270. sage/structure/richcmp.pxd +213 -0
  271. sage/structure/richcmp.pyx +495 -0
  272. sage/structure/sage_object.cp312-win_amd64.pyd +0 -0
  273. sage/structure/sage_object.pxd +3 -0
  274. sage/structure/sage_object.pyx +988 -0
  275. sage/structure/sage_object_test.py +19 -0
  276. sage/structure/sequence.py +937 -0
  277. sage/structure/set_factories.py +1178 -0
  278. sage/structure/set_factories_example.py +527 -0
  279. sage/structure/support_view.py +179 -0
  280. sage/structure/test_factory.py +56 -0
  281. sage/structure/unique_representation.py +1359 -0
@@ -0,0 +1,29 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ from sage.structure.element cimport Element
3
+ from sage.categories.morphism cimport Morphism
4
+ from sage.categories.map cimport Map
5
+ from sage.categories.functor cimport Functor
6
+
7
+ cdef class Action(Functor):
8
+ cdef readonly G
9
+ cdef readonly op
10
+ cdef readonly bint _is_left
11
+ cdef US
12
+ cdef underlying_set(self)
13
+
14
+ cdef _act_convert(self, g, x)
15
+ cpdef _act_(self, g, x)
16
+
17
+
18
+ cdef class InverseAction(Action):
19
+ cdef Action _action
20
+ cdef Map S_precomposition
21
+
22
+ cdef class PrecomposedAction(Action):
23
+ cdef Action _action
24
+ cdef Map G_precomposition
25
+ cdef Map S_precomposition
26
+
27
+ cdef class ActionEndomorphism(Morphism):
28
+ cdef Action _action
29
+ cdef Element _g
@@ -0,0 +1,641 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ r"""
3
+ Group, ring, etc. actions on objects
4
+
5
+ The terminology and notation used is suggestive of groups acting on sets,
6
+ but this framework can be used for modules, algebras, etc.
7
+
8
+ A group action `G \times S \rightarrow S` is a functor from `G` to Sets.
9
+
10
+ .. WARNING::
11
+
12
+ An :class:`Action` object only keeps a weak reference to the underlying set
13
+ which is acted upon. This decision was made in :issue:`715` in order to
14
+ allow garbage collection within the coercion framework (this is where
15
+ actions are mainly used) and avoid memory leaks.
16
+
17
+ ::
18
+
19
+ sage: from sage.categories.action import Action
20
+ sage: class P: pass
21
+ sage: A = Action(P(),P())
22
+ sage: import gc
23
+ sage: _ = gc.collect()
24
+ sage: A
25
+ <repr(<sage.categories.action.Action at 0x...>) failed:
26
+ RuntimeError: This action acted on a set that became garbage collected>
27
+
28
+ To avoid garbage collection of the underlying set, it is sufficient to
29
+ create a strong reference to it before the action is created.
30
+
31
+ ::
32
+
33
+ sage: _ = gc.collect()
34
+ sage: from sage.categories.action import Action
35
+ sage: class P: pass
36
+ sage: q = P()
37
+ sage: A = Action(P(),q)
38
+ sage: gc.collect()
39
+ 0
40
+ sage: A
41
+ Left action by <__main__.P ... at ...> on <__main__.P ... at ...>
42
+
43
+ AUTHOR:
44
+
45
+ - Robert Bradshaw: initial version
46
+ """
47
+
48
+ # ****************************************************************************
49
+ # Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu>
50
+ #
51
+ # This program is free software: you can redistribute it and/or modify
52
+ # it under the terms of the GNU General Public License as published by
53
+ # the Free Software Foundation, either version 2 of the License, or
54
+ # (at your option) any later version.
55
+ # https://www.gnu.org/licenses/
56
+ # ****************************************************************************
57
+
58
+ from cpython.tuple cimport PyTuple_GET_ITEM
59
+
60
+ from sage.categories.functor cimport Functor
61
+ from sage.categories.morphism cimport Morphism
62
+ from sage.categories.map cimport Map
63
+ from sage.structure.element cimport parent
64
+ from sage.structure.parent cimport Parent
65
+
66
+ from sage.categories import homset
67
+ from weakref import ref
68
+
69
+
70
+ cdef inline category(x):
71
+ try:
72
+ return x.category()
73
+ except AttributeError:
74
+ from sage.categories.objects import Objects
75
+ return Objects()
76
+
77
+
78
+ cdef class Action(Functor):
79
+ """
80
+ The action of ``G`` on ``S``.
81
+
82
+ INPUT:
83
+
84
+ - ``G`` -- a parent or Python type
85
+
86
+ - ``S`` -- a parent or Python type
87
+
88
+ - ``is_left`` -- boolean (default: ``True``); whether elements of
89
+ ``G`` are on the left
90
+
91
+ - ``op`` -- (default: ``None``) operation. This is not used by
92
+ :class:`Action` itself, but other classes may use it
93
+ """
94
+ def __init__(self, G, S, is_left=True, op=None):
95
+ from sage.categories.groupoid import Groupoid
96
+ Functor.__init__(self, Groupoid(G), category(S))
97
+ self.G = G
98
+ self.US = ref(S)
99
+ self._is_left = is_left
100
+ self.op = op
101
+
102
+ def _apply_functor(self, x):
103
+ return self(x)
104
+
105
+ def __reduce__(self):
106
+ """
107
+ Used in pickling.
108
+
109
+ .. WARNING::
110
+
111
+ If you change the signature of the ``__init__`` for a subclass,
112
+ you must override this method as well.
113
+
114
+ TESTS:
115
+
116
+ Check that this action can be pickled (:issue:`29031`)::
117
+
118
+ sage: P = QQ['x']
119
+ sage: R = (ZZ['x'])['y']
120
+ sage: A = R.get_action(P, operator.mul, True)
121
+ sage: loads(dumps(A)) is not None
122
+ True
123
+ """
124
+ return (type(self), (self.G, self.underlying_set(), self._is_left, self.op))
125
+
126
+ def __call__(self, *args):
127
+ """
128
+ Let this action act.
129
+
130
+ For a left action, ``action(a, b)`` lets ``a`` act on ``b``.
131
+ For a right action, ``action(a, b)`` lets ``b`` act on ``a``.
132
+
133
+ If needed, ``a`` and ``b`` are converted to the correct parent.
134
+
135
+ .. SEEALSO::
136
+
137
+ :meth:`act` which lets you pass the acting and acted-on
138
+ elements directly.
139
+
140
+ EXAMPLES::
141
+
142
+ sage: R.<x> = ZZ []
143
+ sage: from sage.structure.coerce_actions import IntegerMulAction
144
+ sage: A = IntegerMulAction(ZZ, R, True) # Left action
145
+ sage: A(5, x)
146
+ 5*x
147
+ sage: A(int(5), x)
148
+ 5*x
149
+ sage: A(x, 5)
150
+ Traceback (most recent call last):
151
+ ...
152
+ TypeError: x is not a constant polynomial
153
+ sage: A = IntegerMulAction(ZZ, R, False) # Right action
154
+ sage: A(x, 5)
155
+ 5*x
156
+ sage: A(x, int(5))
157
+ 5*x
158
+ sage: A(5, x)
159
+ Traceback (most recent call last):
160
+ ...
161
+ TypeError: x is not a constant polynomial
162
+ """
163
+ if len(args) == 2:
164
+ # Normal case, called with (g, x) or (x, g) as arguments
165
+ #
166
+ # For a left action: g = args[0] and x = args[1]
167
+ # For a right action: g = args[1] and x = args[0]
168
+ g = <object>PyTuple_GET_ITEM(args, 1 - self._is_left)
169
+ x = <object>PyTuple_GET_ITEM(args, self._is_left)
170
+ return self._act_convert(g, x)
171
+ elif len(args) == 1:
172
+ g = <object>PyTuple_GET_ITEM(args, 0)
173
+ if g in self.G:
174
+ return ActionEndomorphism(self, self.G(g))
175
+ elif g == self.G:
176
+ return self.underlying_set()
177
+ else:
178
+ raise TypeError("%s not an element of %s" % (g, self.G))
179
+ else:
180
+ raise TypeError("actions should be called with 1 or 2 arguments")
181
+
182
+ cdef _act_convert(self, g, x):
183
+ """
184
+ Let ``g`` act on ``x`` under this action, converting ``g``
185
+ and ``x`` to the correct parents first.
186
+ """
187
+ U = self.underlying_set()
188
+ if parent(g) is not self.G:
189
+ g = self.G(g)
190
+ if parent(x) is not U:
191
+ x = U(x)
192
+ return self._act_(g, x)
193
+
194
+ cpdef _act_(self, g, x):
195
+ """
196
+ Let ``g`` act on ``x`` under this action.
197
+
198
+ Regardless of whether this is a left or right action, the acting
199
+ element comes first.
200
+
201
+ INPUT:
202
+
203
+ - ``g`` -- an object with parent ``self.G``
204
+
205
+ - ``x`` -- an object with parent ``self.US()``
206
+
207
+ .. WARNING::
208
+
209
+ This is meant to be a fast internal function, so the
210
+ conditions on the input are not checked!
211
+ """
212
+ raise NotImplementedError(f"action for {type(self)} not implemented")
213
+
214
+ def act(self, g, x):
215
+ """
216
+ This is a consistent interface for acting on ``x`` by ``g``,
217
+ regardless of whether it's a left or right action.
218
+
219
+ If needed, ``g`` and ``x`` are converted to the correct parent.
220
+
221
+ EXAMPLES::
222
+
223
+ sage: R.<x> = ZZ []
224
+ sage: from sage.structure.coerce_actions import IntegerMulAction
225
+ sage: A = IntegerMulAction(ZZ, R, True) # Left action
226
+ sage: A.act(5, x)
227
+ 5*x
228
+ sage: A.act(int(5), x)
229
+ 5*x
230
+ sage: A = IntegerMulAction(ZZ, R, False) # Right action
231
+ sage: A.act(5, x)
232
+ 5*x
233
+ sage: A.act(int(5), x)
234
+ 5*x
235
+ """
236
+ return self._act_convert(g, x)
237
+
238
+ def __invert__(self):
239
+ return InverseAction(self)
240
+
241
+ def is_left(self):
242
+ return self._is_left
243
+
244
+ def _repr_(self):
245
+ side = "Left" if self._is_left else "Right"
246
+ return "%s %s by %r on %r" % (side, self._repr_name_(), self.G,
247
+ self.underlying_set())
248
+
249
+ def _repr_name_(self):
250
+ return "action"
251
+
252
+ def actor(self):
253
+ return self.G
254
+
255
+ cdef underlying_set(self):
256
+ """
257
+ The set on which the actor acts (it is not necessarily the codomain of
258
+ the action).
259
+
260
+ .. NOTE::
261
+
262
+ Since this is a cdef'ed method, we can only provide an indirect doctest.
263
+
264
+ EXAMPLES::
265
+
266
+ sage: P = QQ['x']
267
+ sage: R = (ZZ['x'])['y']
268
+ sage: A = R.get_action(P,operator.mul,True)
269
+ sage: A # indirect doctest
270
+ Right scalar multiplication
271
+ by Univariate Polynomial Ring in x over Rational Field
272
+ on Univariate Polynomial Ring in y over
273
+ Univariate Polynomial Ring in x over Integer Ring
274
+
275
+ In this example, the underlying set is the ring ``R``. This is the same
276
+ as the left domain, which is different from the codomain of the action::
277
+
278
+ sage: A.codomain()
279
+ Univariate Polynomial Ring in y
280
+ over Univariate Polynomial Ring in x over Rational Field
281
+ sage: A.codomain() == R
282
+ False
283
+ sage: A.left_domain() is R
284
+ True
285
+
286
+ By :issue:`715`, there is only a weak reference to the underlying set.
287
+ Hence, the underlying set may be garbage collected, even when the
288
+ action is still alive. This may result in a runtime error, as follows::
289
+
290
+ sage: from sage.categories.action import Action
291
+ sage: class P: pass
292
+ sage: p = P()
293
+ sage: q = P()
294
+ sage: A = Action(p,q)
295
+ sage: A
296
+ Left action by <__main__.P ... at ...> on <__main__.P ... at ...>
297
+ sage: del q
298
+ sage: import gc
299
+ sage: _ = gc.collect()
300
+ sage: A
301
+ <repr(<sage.categories.action.Action at 0x...>) failed:
302
+ RuntimeError: This action acted on a set that became garbage collected>
303
+ """
304
+ S = self.US()
305
+ if S is None:
306
+ raise RuntimeError("This action acted on a set that became garbage collected")
307
+ return S
308
+
309
+ def codomain(self):
310
+ return self.underlying_set()
311
+
312
+ def domain(self):
313
+ return self.underlying_set()
314
+
315
+ def left_domain(self):
316
+ if self._is_left:
317
+ return self.G
318
+ else:
319
+ return self.domain()
320
+
321
+ def right_domain(self):
322
+ if self._is_left:
323
+ return self.domain()
324
+ else:
325
+ return self.G
326
+
327
+ def operation(self):
328
+ return self.op
329
+
330
+
331
+ cdef class InverseAction(Action):
332
+ """
333
+ An action that acts as the inverse of the given action.
334
+
335
+ EXAMPLES::
336
+
337
+ sage: V = QQ^3 # needs sage.modules
338
+ sage: v = V((1, 2, 3)) # needs sage.modules
339
+ sage: cm = get_coercion_model()
340
+
341
+ sage: # needs sage.modules
342
+ sage: a = cm.get_action(V, QQ, operator.mul)
343
+ sage: a
344
+ Right scalar multiplication by Rational Field
345
+ on Vector space of dimension 3 over Rational Field
346
+ sage: ~a
347
+ Right inverse action by Rational Field
348
+ on Vector space of dimension 3 over Rational Field
349
+ sage: (~a)(v, 1/3)
350
+ (3, 6, 9)
351
+
352
+ sage: # needs sage.modules
353
+ sage: b = cm.get_action(QQ, V, operator.mul)
354
+ sage: b
355
+ Left scalar multiplication by Rational Field
356
+ on Vector space of dimension 3 over Rational Field
357
+ sage: ~b
358
+ Left inverse action by Rational Field
359
+ on Vector space of dimension 3 over Rational Field
360
+ sage: (~b)(1/3, v)
361
+ (3, 6, 9)
362
+
363
+ sage: c = cm.get_action(ZZ, list, operator.mul)
364
+ sage: c
365
+ Left action by Integer Ring on <... 'list'>
366
+ sage: ~c
367
+ Traceback (most recent call last):
368
+ ...
369
+ TypeError: no inverse defined for Left action by Integer Ring on <... 'list'>
370
+
371
+ TESTS:
372
+
373
+ sage: x = polygen(QQ,'x')
374
+ sage: a = 2*x^2+2; a
375
+ 2*x^2 + 2
376
+ sage: a / 2
377
+ x^2 + 1
378
+ sage: a /= 2
379
+ sage: a
380
+ x^2 + 1
381
+ """
382
+ def __init__(self, Action action):
383
+ G = action.G
384
+ try:
385
+ from sage.groups.group import Group
386
+ # We must be in the case that parent(~a) == parent(a)
387
+ # so we can invert in _call_ code below.
388
+ if (isinstance(G, Group) and G.is_multiplicative()) or G.is_field():
389
+ Action.__init__(self, G, action.underlying_set(), action._is_left)
390
+ self._action = action
391
+ return
392
+ except (AttributeError, NotImplementedError):
393
+ pass
394
+ raise TypeError(f"no inverse defined for {action!r}")
395
+
396
+ def __reduce__(self):
397
+ """
398
+ Used in pickling.
399
+
400
+ TESTS:
401
+
402
+ Check that this action can be pickled (:issue:`29031`)::
403
+
404
+ sage: # needs sage.modules
405
+ sage: V = QQ^3
406
+ sage: v = V((1, 2, 3))
407
+ sage: cm = get_coercion_model()
408
+ sage: a = cm.get_action(V, QQ, operator.mul)
409
+ sage: loads(dumps(~a)) is not None
410
+ True
411
+ """
412
+ return (type(self), (self._action,))
413
+
414
+ cpdef _act_(self, g, x):
415
+ if self.S_precomposition is not None:
416
+ x = self.S_precomposition(x)
417
+ return self._action._act_(~g, x)
418
+
419
+ def codomain(self):
420
+ return self._action.codomain()
421
+
422
+ def __invert__(self):
423
+ return self._action
424
+
425
+ def _repr_name_(self):
426
+ return "inverse action"
427
+
428
+
429
+ cdef class PrecomposedAction(Action):
430
+ """
431
+ A precomposed action first applies given maps, and then applying an action
432
+ to the return values of the maps.
433
+
434
+ EXAMPLES:
435
+
436
+ We demonstrate that an example discussed on :issue:`14711` did not become a
437
+ problem::
438
+
439
+ sage: # needs sage.libs.flint sage.modular
440
+ sage: E = ModularSymbols(11).2
441
+ sage: s = E.modular_symbol_rep()
442
+ sage: del E,s
443
+ sage: import gc
444
+ sage: _ = gc.collect()
445
+ sage: E = ModularSymbols(11).2
446
+ sage: v = E.manin_symbol_rep()
447
+ sage: c,x = v[0]
448
+ sage: y = x.modular_symbol_rep()
449
+ sage: coercion_model.get_action(QQ, parent(y), op=operator.mul)
450
+ Left scalar multiplication by Rational Field
451
+ on Abelian Group of all Formal Finite Sums over Rational Field
452
+ with precomposition on right by Coercion map:
453
+ From: Abelian Group of all Formal Finite Sums over Integer Ring
454
+ To: Abelian Group of all Formal Finite Sums over Rational Field
455
+ """
456
+ def __init__(self, Action action, Map left_precomposition, Map right_precomposition):
457
+ left = action.left_domain()
458
+ right = action.right_domain()
459
+ US = action.underlying_set()
460
+ cdef Parent lco, rco
461
+ if left_precomposition is not None:
462
+ lco = left_precomposition._codomain
463
+ if lco is not left:
464
+ left_precomposition = homset.Hom(lco, left).natural_map() * left_precomposition
465
+ left = left_precomposition.domain()
466
+ if right_precomposition is not None:
467
+ rco = right_precomposition._codomain
468
+ if rco is not right:
469
+ right_precomposition = homset.Hom(rco, right).natural_map() * right_precomposition
470
+ right = right_precomposition.domain()
471
+ if action._is_left:
472
+ Action.__init__(self, left, US, 1)
473
+ else:
474
+ Action.__init__(self, right, US, 0)
475
+ self._action = action
476
+ if self._is_left:
477
+ self.G_precomposition = left_precomposition
478
+ self.S_precomposition = right_precomposition
479
+ else:
480
+ self.G_precomposition = right_precomposition
481
+ self.S_precomposition = left_precomposition
482
+
483
+ def __reduce__(self):
484
+ """
485
+ Used in pickling.
486
+
487
+ TESTS:
488
+
489
+ Check that this action can be pickled (:issue:`29031`)::
490
+
491
+ sage: # needs sage.libs.flint sage.modular
492
+ sage: E = ModularSymbols(11).2
493
+ sage: v = E.manin_symbol_rep()
494
+ sage: c,x = v[0]
495
+ sage: y = x.modular_symbol_rep()
496
+ sage: act = coercion_model.get_action(QQ, parent(y), op=operator.mul)
497
+ sage: loads(dumps(act)) is not None
498
+ True
499
+ """
500
+ return (type(self), (self._action, self.G_precomposition, self.S_precomposition))
501
+
502
+ cpdef _act_(self, g, x):
503
+ if self.G_precomposition is not None:
504
+ g = self.G_precomposition._call_(g)
505
+ if self.S_precomposition is not None:
506
+ x = self.S_precomposition._call_(x)
507
+ return self._action._act_(g, x)
508
+
509
+ def domain(self):
510
+ if self.S_precomposition is not None:
511
+ return self.S_precomposition.domain()
512
+ else:
513
+ return self._action.domain()
514
+
515
+ def codomain(self):
516
+ return self._action.codomain()
517
+
518
+ @property
519
+ def left_precomposition(self):
520
+ """
521
+ The left map to precompose with, or ``None`` if there is no
522
+ left precomposition map.
523
+ """
524
+ if self._is_left:
525
+ return self.G_precomposition
526
+ else:
527
+ return self.S_precomposition
528
+
529
+ @property
530
+ def right_precomposition(self):
531
+ """
532
+ The right map to precompose with, or ``None`` if there is no
533
+ right precomposition map.
534
+ """
535
+ if self._is_left:
536
+ return self.S_precomposition
537
+ else:
538
+ return self.G_precomposition
539
+
540
+ def __invert__(self):
541
+ return PrecomposedAction(~self._action, self.left_precomposition, self.right_precomposition)
542
+
543
+ def _repr_(self):
544
+ s = repr(self._action)
545
+ if self.left_precomposition is not None:
546
+ s += "\nwith precomposition on left by %s" % self.left_precomposition._default_repr_()
547
+ if self.right_precomposition is not None:
548
+ s += "\nwith precomposition on right by %s" % self.right_precomposition._default_repr_()
549
+ return s
550
+
551
+
552
+ cdef class ActionEndomorphism(Morphism):
553
+ """
554
+ The endomorphism defined by the action of one element.
555
+
556
+ EXAMPLES::
557
+
558
+ sage: A = ZZ['x'].get_action(QQ, self_on_left=False, op=operator.mul)
559
+ sage: A
560
+ Left scalar multiplication by Rational Field
561
+ on Univariate Polynomial Ring in x over Integer Ring
562
+ sage: A(1/2)
563
+ Action of 1/2 on Univariate Polynomial Ring in x over Integer Ring
564
+ under Left scalar multiplication by Rational Field on Univariate
565
+ Polynomial Ring in x over Integer Ring.
566
+ """
567
+ def __init__(self, Action action, g):
568
+ Morphism.__init__(self, homset.Hom(action.underlying_set(),
569
+ action.underlying_set()))
570
+ self._action = action
571
+ self._g = g
572
+
573
+ cdef dict _extra_slots(self):
574
+ """
575
+ Helper for pickling and copying.
576
+
577
+ TESTS::
578
+
579
+ sage: P.<x> = ZZ[]
580
+ sage: A = P.get_action(QQ, self_on_left=False, op=operator.mul)
581
+ sage: phi = A(1/2)
582
+ sage: psi = copy(phi) # indirect doctest
583
+ sage: psi
584
+ Action of 1/2 on Univariate Polynomial Ring in x over
585
+ Integer Ring under Left scalar multiplication by Rational
586
+ Field on Univariate Polynomial Ring in x over Integer Ring.
587
+ sage: psi(x) == phi(x)
588
+ True
589
+ """
590
+ slots = Morphism._extra_slots(self)
591
+ slots['_action'] = self._action
592
+ slots['_g'] = self._g
593
+ return slots
594
+
595
+ cdef _update_slots(self, dict _slots):
596
+ """
597
+ Helper for pickling and copying.
598
+
599
+ TESTS::
600
+
601
+ sage: P.<x> = ZZ[]
602
+ sage: A = P.get_action(QQ, self_on_left=False, op=operator.mul)
603
+ sage: phi = A(1/2)
604
+ sage: psi = copy(phi) # indirect doctest
605
+ sage: psi
606
+ Action of 1/2 on Univariate Polynomial Ring in x over
607
+ Integer Ring under Left scalar multiplication by Rational
608
+ Field on Univariate Polynomial Ring in x over Integer Ring.
609
+ sage: psi(x) == phi(x)
610
+ True
611
+ """
612
+ self._action = _slots['_action']
613
+ self._g = _slots['_g']
614
+ Morphism._update_slots(self, _slots)
615
+
616
+ cpdef Element _call_(self, x):
617
+ return self._action._act_(self._g, x)
618
+
619
+ def _repr_(self):
620
+ return "Action of %s on %s under %s." % (self._g,
621
+ self._action.underlying_set(),
622
+ self._action)
623
+
624
+ def __mul__(left, right):
625
+ cdef ActionEndomorphism left_c, right_c
626
+ if isinstance(left, ActionEndomorphism) and isinstance(right, ActionEndomorphism):
627
+ left_c = left
628
+ right_c = right
629
+ if left_c._action is right_c._action:
630
+ if left_c._action._is_left:
631
+ return ActionEndomorphism(left_c._action, left_c._g * right_c._g)
632
+ else:
633
+ return ActionEndomorphism(left_c._action, right_c._g * left_c._g)
634
+ return Morphism.__mul__(left, right)
635
+
636
+ def __invert__(self):
637
+ inv_g = ~self._g
638
+ if parent(inv_g) is parent(self._g):
639
+ return ActionEndomorphism(self._action, inv_g)
640
+ else:
641
+ return (~self._action)(self._g)