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,3228 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ r"""
3
+ Sets
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu>
7
+ # William Stein <wstein@math.ucsd.edu>
8
+ # 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr>
9
+ # 2008-2017 Nicolas M. Thiery <nthiery at users.sf.net>
10
+ # 2009 Mike Hansen
11
+ # 2010 Florent Hivert
12
+ # 2010 William Laffin
13
+ # 2012 Franco Saliola
14
+ # 2013 Sara Billey
15
+ # 2013 Simon King
16
+ # 2013-2016 Julian Rüth
17
+ # 2014 Darij Grinberg
18
+ # 2014 Peter Bruin
19
+ # 2014-2021 Frédéric Chapoton
20
+ # 2014-2021 Travis Scrimshaw
21
+ # 2015 Daniel Krenn
22
+ # 2015 Vincent Delecroix
23
+ # 2015-2016 Jori Mäntysalo
24
+ # 2016 Kwankyu Lee
25
+ # 2018 Vincent Klein
26
+ # 2019 Markus Wageringel
27
+ # 2020-2021 Matthias Koeppe
28
+ #
29
+ # Distributed under the terms of the GNU General Public License (GPL)
30
+ # https://www.gnu.org/licenses/
31
+ # *****************************************************************************
32
+
33
+ from sage.misc.cachefunc import cached_method
34
+ from sage.misc.sage_unittest import TestSuite
35
+ from sage.misc.abstract_method import abstract_method
36
+ from sage.misc.lazy_attribute import lazy_attribute
37
+ from sage.misc.lazy_import import lazy_import, LazyImport
38
+ from sage.misc.lazy_format import LazyFormat
39
+ from sage.categories.category import Category
40
+ from sage.categories.category_singleton import Category_singleton
41
+ # Do not use sage.categories.all here to avoid initialization loop
42
+ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
43
+ from sage.categories.subquotients import SubquotientsCategory
44
+ from sage.categories.quotients import QuotientsCategory
45
+ from sage.categories.subobjects import SubobjectsCategory
46
+ from sage.categories.isomorphic_objects import IsomorphicObjectsCategory
47
+ from sage.categories.algebra_functor import AlgebrasCategory
48
+ from sage.categories.cartesian_product import CartesianProductsCategory, CartesianProductFunctor
49
+ from sage.categories.realizations import RealizationsCategory, Category_realization_of_parent
50
+ from sage.categories.with_realizations import WithRealizationsCategory
51
+ from sage.categories.category_with_axiom import CategoryWithAxiom
52
+ lazy_import('sage.sets.cartesian_product', 'CartesianProduct')
53
+
54
+
55
+ def print_compare(x, y):
56
+ """
57
+ Helper method used in
58
+ :meth:`Sets.ParentMethods._test_elements_eq_symmetric`,
59
+ :meth:`Sets.ParentMethods._test_elements_eq_tranisitive`.
60
+
61
+ INPUT:
62
+
63
+ - ``x`` -- an element
64
+
65
+ - ``y`` -- an element
66
+
67
+ EXAMPLES::
68
+
69
+ sage: from sage.categories.sets_cat import print_compare
70
+ sage: print_compare(1,2)
71
+ 1 != 2
72
+ sage: print_compare(1,1)
73
+ 1 == 1
74
+ """
75
+ if x == y:
76
+ return LazyFormat("%s == %s") % (x, y)
77
+ else:
78
+ return LazyFormat("%s != %s") % (x, y)
79
+
80
+
81
+ class EmptySetError(ValueError):
82
+ """
83
+ Exception raised when some operation can't be performed on the empty set.
84
+
85
+ EXAMPLES::
86
+
87
+ sage: def first_element(st):
88
+ ....: if not st: raise EmptySetError("no elements")
89
+ ....: else: return st[0]
90
+ sage: first_element(Set((1,2,3)))
91
+ 1
92
+ sage: first_element(Set([]))
93
+ Traceback (most recent call last):
94
+ ...
95
+ EmptySetError: no elements
96
+ """
97
+ pass
98
+
99
+
100
+ class Sets(Category_singleton):
101
+ r"""
102
+ The category of sets.
103
+
104
+ The base category for collections of elements with = (equality).
105
+
106
+ This is also the category whose objects are all parents.
107
+
108
+ EXAMPLES::
109
+
110
+ sage: Sets()
111
+ Category of sets
112
+ sage: Sets().super_categories()
113
+ [Category of sets with partial maps]
114
+ sage: Sets().all_super_categories()
115
+ [Category of sets, Category of sets with partial maps, Category of objects]
116
+
117
+ Let us consider an example of set::
118
+
119
+ sage: P = Sets().example("inherits")
120
+ sage: P
121
+ Set of prime numbers
122
+
123
+ See ``P??`` for the code.
124
+
125
+
126
+ P is in the category of sets::
127
+
128
+ sage: P.category()
129
+ Category of sets
130
+
131
+ and therefore gets its methods from the following classes::
132
+
133
+ sage: for cl in P.__class__.mro(): print(cl)
134
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Inherits_with_category'>
135
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Inherits'>
136
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Abstract'>
137
+ <class 'sage.structure.unique_representation.UniqueRepresentation'>
138
+ <class 'sage.misc.fast_methods.WithEqualityById'>
139
+ <class 'sage.structure.unique_representation.CachedRepresentation'>
140
+ <class 'sage.structure.unique_representation.WithPicklingByInitArgs'>
141
+ <class 'sage.structure.parent.Parent'>
142
+ <class 'sage.structure.category_object.CategoryObject'>
143
+ <class 'sage.structure.sage_object.SageObject'>
144
+ <class 'sage.categories.sets_cat.Sets.parent_class'>
145
+ <class 'sage.categories.sets_with_partial_maps.SetsWithPartialMaps.parent_class'>
146
+ <class 'sage.categories.objects.Objects.parent_class'>
147
+ <class 'object'>
148
+
149
+ We run some generic checks on P::
150
+
151
+ sage: TestSuite(P).run(verbose=True) # needs sage.libs.pari
152
+ running ._test_an_element() . . . pass
153
+ running ._test_cardinality() . . . pass
154
+ running ._test_category() . . . pass
155
+ running ._test_construction() . . . pass
156
+ running ._test_elements() . . .
157
+ Running the test suite of self.an_element()
158
+ running ._test_category() . . . pass
159
+ running ._test_eq() . . . pass
160
+ running ._test_new() . . . pass
161
+ running ._test_not_implemented_methods() . . . pass
162
+ running ._test_pickling() . . . pass
163
+ pass
164
+ running ._test_elements_eq_reflexive() . . . pass
165
+ running ._test_elements_eq_symmetric() . . . pass
166
+ running ._test_elements_eq_transitive() . . . pass
167
+ running ._test_elements_neq() . . . pass
168
+ running ._test_eq() . . . pass
169
+ running ._test_new() . . . pass
170
+ running ._test_not_implemented_methods() . . . pass
171
+ running ._test_pickling() . . . pass
172
+ running ._test_some_elements() . . . pass
173
+
174
+ Now, we manipulate some elements of P::
175
+
176
+ sage: P.an_element()
177
+ 47
178
+ sage: x = P(3)
179
+ sage: x.parent()
180
+ Set of prime numbers
181
+ sage: x in P, 4 in P
182
+ (True, False)
183
+ sage: x.is_prime()
184
+ True
185
+
186
+ They get their methods from the following classes::
187
+
188
+ sage: for cl in x.__class__.mro(): print(cl)
189
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Inherits_with_category.element_class'>
190
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Inherits.Element'>
191
+ <class 'sage.rings.integer.IntegerWrapper'>
192
+ <class 'sage.rings.integer.Integer'>
193
+ <class 'sage.structure.element.EuclideanDomainElement'>
194
+ <class 'sage.structure.element.PrincipalIdealDomainElement'>
195
+ <class 'sage.structure.element.DedekindDomainElement'>
196
+ <class 'sage.structure.element.IntegralDomainElement'>
197
+ <class 'sage.structure.element.CommutativeRingElement'>
198
+ <class 'sage.structure.element.RingElement'>
199
+ <class 'sage.structure.element.ModuleElement'>
200
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Abstract.Element'>
201
+ <class 'sage.structure.element.Element'>
202
+ <class 'sage.structure.sage_object.SageObject'>
203
+ <class 'sage.categories.sets_cat.Sets.element_class'>
204
+ <class 'sage.categories.sets_with_partial_maps.SetsWithPartialMaps.element_class'>
205
+ <class 'sage.categories.objects.Objects.element_class'>
206
+ <... 'object'>
207
+
208
+ FIXME: Objects.element_class is not very meaningful ...
209
+
210
+
211
+ TESTS::
212
+
213
+ sage: TestSuite(Sets()).run()
214
+ """
215
+
216
+ def super_categories(self):
217
+ r"""
218
+ We include SetsWithPartialMaps between Sets and Objects so that we
219
+ can define morphisms between sets that are only partially defined.
220
+ This is also to have the Homset constructor not complain that
221
+ SetsWithPartialMaps is not a supercategory of Fields, for example.
222
+
223
+ EXAMPLES::
224
+
225
+ sage: Sets().super_categories()
226
+ [Category of sets with partial maps]
227
+ """
228
+ return [SetsWithPartialMaps()]
229
+
230
+ def _call_(self, X, enumerated_set=False):
231
+ r"""
232
+ Construct an object in this category from the data ``X``.
233
+
234
+ INPUT:
235
+
236
+ - ``X`` -- an object to be converted into a set
237
+
238
+ - ``enumerated_set`` -- if set to ``True`` and the input is either a
239
+ Python tuple or a Python list then the output will be a finite
240
+ enumerated set.
241
+
242
+ EXAMPLES::
243
+
244
+ sage: Sets()(ZZ)
245
+ Integer Ring
246
+ sage: Sets()([1, 2, 3])
247
+ {1, 2, 3}
248
+
249
+ sage: S = Sets()([1, 2, 3]); S.category()
250
+ Category of finite enumerated sets
251
+ sage: S = Sets()([1, 2, 3], enumerated_set=True); S.category()
252
+ Category of facade finite enumerated sets
253
+
254
+ .. NOTE::
255
+
256
+ Using ``Sets()(A)`` used to implement some sort of forgetful functor
257
+ into the ``Sets()`` category. This feature has been removed, because
258
+ it was not consistent with the semantic of :meth:`Category.__call__`.
259
+ Proper forgetful functors will eventually be implemented, with
260
+ another syntax.
261
+ """
262
+ if enumerated_set and type(X) in (tuple, list, range):
263
+ from sage.categories.enumerated_sets import EnumeratedSets
264
+ return EnumeratedSets()(X)
265
+ from sage.sets.set import Set
266
+ return Set(X)
267
+
268
+ def example(self, choice=None):
269
+ """
270
+ Return examples of objects of ``Sets()``, as per
271
+ :meth:`Category.example()
272
+ <sage.categories.category.Category.example>`.
273
+
274
+ EXAMPLES::
275
+
276
+ sage: Sets().example()
277
+ Set of prime numbers (basic implementation)
278
+
279
+ sage: Sets().example("inherits")
280
+ Set of prime numbers
281
+
282
+ sage: Sets().example("facade")
283
+ Set of prime numbers (facade implementation)
284
+
285
+ sage: Sets().example("wrapper")
286
+ Set of prime numbers (wrapper implementation)
287
+ """
288
+ if choice is None:
289
+ from sage.categories.examples.sets_cat import PrimeNumbers
290
+ return PrimeNumbers()
291
+ elif choice == "inherits":
292
+ from sage.categories.examples.sets_cat import PrimeNumbers_Inherits
293
+ return PrimeNumbers_Inherits()
294
+ elif choice == "facade":
295
+ from sage.categories.examples.sets_cat import PrimeNumbers_Facade
296
+ return PrimeNumbers_Facade()
297
+ elif choice == "wrapper":
298
+ from sage.categories.examples.sets_cat import PrimeNumbers_Wrapper
299
+ return PrimeNumbers_Wrapper()
300
+ else:
301
+ raise ValueError("unknown choice")
302
+
303
+ class SubcategoryMethods:
304
+
305
+ @cached_method
306
+ def CartesianProducts(self):
307
+ r"""
308
+ Return the full subcategory of the objects of ``self``
309
+ constructed as Cartesian products.
310
+
311
+ .. SEEALSO::
312
+
313
+ - :class:`.cartesian_product.CartesianProductFunctor`
314
+ - :class:`~.covariant_functorial_construction.RegressiveCovariantFunctorialConstruction`
315
+
316
+ EXAMPLES::
317
+
318
+ sage: Sets().CartesianProducts()
319
+ Category of Cartesian products of sets
320
+ sage: Semigroups().CartesianProducts()
321
+ Category of Cartesian products of semigroups
322
+ sage: EuclideanDomains().CartesianProducts()
323
+ Category of Cartesian products of commutative rings
324
+ """
325
+ return CartesianProductsCategory.category_of(self)
326
+
327
+ @cached_method
328
+ def Subquotients(self):
329
+ r"""
330
+ Return the full subcategory of the objects of ``self``
331
+ constructed as subquotients.
332
+
333
+ Given a concrete category ``self == As()`` (i.e. a subcategory
334
+ of ``Sets()``), ``As().Subquotients()`` returns the category
335
+ of objects of ``As()`` endowed with a distinguished
336
+ description as subquotient of some other object of ``As()``.
337
+
338
+ EXAMPLES::
339
+
340
+ sage: Monoids().Subquotients()
341
+ Category of subquotients of monoids
342
+
343
+ A parent `A` in ``As()`` is further in
344
+ ``As().Subquotients()`` if there is a distinguished parent
345
+ `B` in ``As()``, called the *ambient set*, a subobject
346
+ `B'` of `B`, and a pair of maps:
347
+
348
+ .. MATH::
349
+
350
+ l: A \to B' \text{ and } r: B' \to A
351
+
352
+ called respectively the *lifting map* and *retract map*
353
+ such that `r \circ l` is the identity of `A` and `r` is a
354
+ morphism in ``As()``.
355
+
356
+ .. TODO:: Draw the typical commutative diagram.
357
+
358
+ It follows that, for each operation `op` of the category,
359
+ we have some property like:
360
+
361
+ .. MATH::
362
+
363
+ op_A(e) = r(op_B(l(e))), \text{ for all } e\in A
364
+
365
+ This allows for implementing the operations on `A` from
366
+ those on `B`.
367
+
368
+ The two most common use cases are:
369
+
370
+ - *homomorphic images* (or *quotients*), when `B'=B`,
371
+ `r` is an homomorphism from `B` to `A` (typically a
372
+ canonical quotient map), and `l` a section of it (not
373
+ necessarily a homomorphism); see :meth:`Quotients`;
374
+
375
+ - *subobjects* (up to an isomorphism), when `l` is an
376
+ embedding from `A` into `B`; in this case, `B'` is
377
+ typically isomorphic to `A` through the inverse
378
+ isomorphisms `r` and `l`; see :meth:`Subobjects`;
379
+
380
+ .. NOTE::
381
+
382
+ - The usual definition of "subquotient"
383
+ (:wikipedia:`Subquotient`) does not involve the
384
+ lifting map `l`. This map is required in Sage's
385
+ context to make the definition constructive. It is
386
+ only used in computations and does not affect their
387
+ results. This is relatively harmless since the
388
+ category is a concrete category (i.e., its objects
389
+ are sets and its morphisms are set maps).
390
+
391
+ - In mathematics, especially in the context of
392
+ quotients, the retract map `r` is often referred to
393
+ as a *projection map* instead.
394
+
395
+ - Since `B'` is not specified explicitly, it is
396
+ possible to abuse the framework with situations
397
+ where `B'` is not quite a subobject and `r` not
398
+ quite a morphism, as long as the lifting and retract
399
+ maps can be used as above to compute all the
400
+ operations in `A`. Use at your own risk!
401
+
402
+ Assumptions:
403
+
404
+ - For any category ``As()``, ``As().Subquotients()`` is a
405
+ subcategory of ``As()``.
406
+
407
+ Example: a subquotient of a group is a group (e.g., a left
408
+ or right quotient of a group by a non-normal subgroup is
409
+ not in this category).
410
+
411
+ - This construction is covariant: if ``As()`` is a
412
+ subcategory of ``Bs()``, then ``As().Subquotients()`` is a
413
+ subcategory of ``Bs().Subquotients()``.
414
+
415
+ Example: if `A` is a subquotient of `B` in the category of
416
+ groups, then it is also a subquotient of `B` in the category
417
+ of monoids.
418
+
419
+ - If the user (or a program) calls ``As().Subquotients()``,
420
+ then it is assumed that subquotients are well defined in
421
+ this category. This is not checked, and probably never will
422
+ be. Note that, if a category ``As()`` does not specify
423
+ anything about its subquotients, then its subquotient
424
+ category looks like this::
425
+
426
+ sage: EuclideanDomains().Subquotients()
427
+ Join of Category of euclidean domains
428
+ and Category of subquotients of monoids
429
+
430
+ Interface: the ambient set `B` of `A` is given by
431
+ ``A.ambient()``. The subset `B'` needs not be specified, so
432
+ the retract map is handled as a partial map from `B` to `A`.
433
+
434
+ The lifting and retract map are implemented
435
+ respectively as methods ``A.lift(a)`` and ``A.retract(b)``.
436
+ As a shorthand for the former, one can use alternatively
437
+ ``a.lift()``::
438
+
439
+ sage: S = Semigroups().Subquotients().example(); S
440
+ An example of a (sub)quotient semigroup: a quotient of the left zero semigroup
441
+ sage: S.ambient()
442
+ An example of a semigroup: the left zero semigroup
443
+ sage: S(3).lift().parent()
444
+ An example of a semigroup: the left zero semigroup
445
+ sage: S(3) * S(1) == S.retract( S(3).lift() * S(1).lift() )
446
+ True
447
+
448
+ See ``S?`` for more.
449
+
450
+ .. TODO:: use a more interesting example, like `\ZZ/n\ZZ`.
451
+
452
+ .. SEEALSO::
453
+
454
+ - :meth:`Quotients`, :meth:`Subobjects`, :meth:`IsomorphicObjects`
455
+ - :class:`.subquotients.SubquotientsCategory`
456
+ - :class:`~.covariant_functorial_construction.RegressiveCovariantFunctorialConstruction`
457
+
458
+ TESTS::
459
+
460
+ sage: TestSuite(Sets().Subquotients()).run()
461
+ """
462
+ return SubquotientsCategory.category_of(self)
463
+
464
+ @cached_method
465
+ def Quotients(self):
466
+ r"""
467
+ Return the full subcategory of the objects of ``self``
468
+ constructed as quotients.
469
+
470
+ Given a concrete category ``As()`` (i.e. a subcategory of
471
+ ``Sets()``), ``As().Quotients()`` returns the category of
472
+ objects of ``As()`` endowed with a distinguished
473
+ description as quotient (in fact homomorphic image) of
474
+ some other object of ``As()``.
475
+
476
+ Implementing an object of ``As().Quotients()`` is done in
477
+ the same way as for ``As().Subquotients()``; namely by
478
+ providing an ambient space and a lift and a retract
479
+ map. See :meth:`Subquotients` for detailed instructions.
480
+
481
+ .. SEEALSO::
482
+
483
+ - :meth:`Subquotients` for background
484
+ - :class:`.quotients.QuotientsCategory`
485
+ - :class:`~.covariant_functorial_construction.RegressiveCovariantFunctorialConstruction`
486
+
487
+ EXAMPLES::
488
+
489
+ sage: C = Semigroups().Quotients(); C
490
+ Category of quotients of semigroups
491
+ sage: C.super_categories()
492
+ [Category of subquotients of semigroups, Category of quotients of sets]
493
+ sage: C.all_super_categories()
494
+ [Category of quotients of semigroups,
495
+ Category of subquotients of semigroups,
496
+ Category of semigroups,
497
+ Category of subquotients of magmas,
498
+ Category of magmas,
499
+ Category of quotients of sets,
500
+ Category of subquotients of sets,
501
+ Category of sets,
502
+ Category of sets with partial maps,
503
+ Category of objects]
504
+
505
+ The caller is responsible for checking that the given category
506
+ admits a well defined category of quotients::
507
+
508
+ sage: EuclideanDomains().Quotients()
509
+ Join of Category of euclidean domains
510
+ and Category of subquotients of monoids
511
+ and Category of quotients of semigroups
512
+
513
+ TESTS::
514
+
515
+ sage: TestSuite(C).run()
516
+ """
517
+ return QuotientsCategory.category_of(self)
518
+
519
+ @cached_method
520
+ def Subobjects(self):
521
+ r"""
522
+ Return the full subcategory of the objects of ``self``
523
+ constructed as subobjects.
524
+
525
+ Given a concrete category ``As()`` (i.e. a subcategory of
526
+ ``Sets()``), ``As().Subobjects()`` returns the category of
527
+ objects of ``As()`` endowed with a distinguished embedding
528
+ into some other object of ``As()``.
529
+
530
+ Implementing an object of ``As().Subobjects()`` is done in
531
+ the same way as for ``As().Subquotients()``; namely by
532
+ providing an ambient space and a lift and a retract
533
+ map. In the case of a trivial embedding, the two maps will
534
+ typically be identity maps that just change the parent of
535
+ their argument. See :meth:`Subquotients` for detailed
536
+ instructions.
537
+
538
+ .. SEEALSO::
539
+
540
+ - :meth:`Subquotients` for background
541
+ - :class:`.subobjects.SubobjectsCategory`
542
+ - :class:`~.covariant_functorial_construction.RegressiveCovariantFunctorialConstruction`
543
+
544
+ EXAMPLES::
545
+
546
+ sage: C = Sets().Subobjects(); C
547
+ Category of subobjects of sets
548
+
549
+ sage: C.super_categories()
550
+ [Category of subquotients of sets]
551
+
552
+ sage: C.all_super_categories()
553
+ [Category of subobjects of sets,
554
+ Category of subquotients of sets,
555
+ Category of sets,
556
+ Category of sets with partial maps,
557
+ Category of objects]
558
+
559
+ Unless something specific about subobjects is implemented for this
560
+ category, one actually gets an optimized super category::
561
+
562
+ sage: C = Semigroups().Subobjects(); C
563
+ Join of Category of subquotients of semigroups
564
+ and Category of subobjects of sets
565
+
566
+ The caller is responsible for checking that the given category
567
+ admits a well defined category of subobjects.
568
+
569
+ TESTS::
570
+
571
+ sage: Semigroups().Subobjects().is_subcategory(Semigroups().Subquotients())
572
+ True
573
+ sage: TestSuite(C).run()
574
+ """
575
+ return SubobjectsCategory.category_of(self)
576
+
577
+ @cached_method
578
+ def IsomorphicObjects(self):
579
+ r"""
580
+ Return the full subcategory of the objects of ``self``
581
+ constructed by isomorphism.
582
+
583
+ Given a concrete category ``As()`` (i.e. a subcategory of
584
+ ``Sets()``), ``As().IsomorphicObjects()`` returns the category of
585
+ objects of ``As()`` endowed with a distinguished description as
586
+ the image of some other object of ``As()`` by an isomorphism in
587
+ this category.
588
+
589
+ See :meth:`Subquotients` for background.
590
+
591
+ EXAMPLES:
592
+
593
+ In the following example, `A` is defined as the image by `x\mapsto
594
+ x^2` of the finite set `B = \{1,2,3\}`::
595
+
596
+ sage: A = FiniteEnumeratedSets().IsomorphicObjects().example(); A
597
+ The image by some isomorphism of An example of a finite enumerated set: {1,2,3}
598
+
599
+ Since `B` is a finite enumerated set, so is `A`::
600
+
601
+ sage: A in FiniteEnumeratedSets()
602
+ True
603
+ sage: A.cardinality()
604
+ 3
605
+ sage: A.list()
606
+ [1, 4, 9]
607
+
608
+ The isomorphism from `B` to `A` is available as::
609
+
610
+ sage: A.retract(3)
611
+ 9
612
+
613
+ and its inverse as::
614
+
615
+ sage: A.lift(9)
616
+ 3
617
+
618
+ It often is natural to declare those morphisms as coercions so
619
+ that one can do ``A(b)`` and ``B(a)`` to go back and forth between
620
+ `A` and `B` (TODO: refer to a category example where the maps are
621
+ declared as a coercion). This is not done by default. Indeed, in
622
+ many cases one only wants to transport part of the structure of
623
+ `B` to `A`. Assume for example, that one wants to construct the
624
+ set of integers `B=ZZ`, endowed with ``max`` as addition, and
625
+ ``+`` as multiplication instead of the usual ``+`` and ``*``. One
626
+ can construct `A` as isomorphic to `B` as an infinite enumerated
627
+ set. However `A` is *not* isomorphic to `B` as a ring; for
628
+ example, for `a\in A` and `a\in B`, the expressions `a+A(b)` and
629
+ `B(a)+b` give completely different results; hence we would not want
630
+ the expression `a+b` to be implicitly resolved to any one of above
631
+ two, as the coercion mechanism would do.
632
+
633
+ Coercions also cannot be used with facade parents (see
634
+ :class:`Sets.Facade`) like in the example above.
635
+
636
+
637
+ We now look at a category of isomorphic objects::
638
+
639
+ sage: C = Sets().IsomorphicObjects(); C
640
+ Category of isomorphic objects of sets
641
+
642
+ sage: C.super_categories()
643
+ [Category of subobjects of sets, Category of quotients of sets]
644
+
645
+ sage: C.all_super_categories()
646
+ [Category of isomorphic objects of sets,
647
+ Category of subobjects of sets,
648
+ Category of quotients of sets,
649
+ Category of subquotients of sets,
650
+ Category of sets,
651
+ Category of sets with partial maps,
652
+ Category of objects]
653
+
654
+ Unless something specific about isomorphic objects is implemented
655
+ for this category, one actually get an optimized super category::
656
+
657
+ sage: C = Semigroups().IsomorphicObjects(); C
658
+ Join of Category of quotients of semigroups
659
+ and Category of isomorphic objects of sets
660
+
661
+ .. SEEALSO::
662
+
663
+ - :meth:`Subquotients` for background
664
+ - :class:`.isomorphic_objects.IsomorphicObjectsCategory`
665
+ - :class:`~.covariant_functorial_construction.RegressiveCovariantFunctorialConstruction`
666
+
667
+ TESTS::
668
+
669
+ sage: TestSuite(Sets().IsomorphicObjects()).run()
670
+ """
671
+ return IsomorphicObjectsCategory.category_of(self)
672
+
673
+ @cached_method
674
+ def Topological(self):
675
+ """
676
+ Return the subcategory of the topological objects of ``self``.
677
+
678
+ TESTS::
679
+
680
+ sage: TestSuite(Sets().Topological()).run()
681
+ """
682
+ from sage.categories.topological_spaces import TopologicalSpacesCategory
683
+ return TopologicalSpacesCategory.category_of(self)
684
+
685
+ @cached_method
686
+ def Metric(self):
687
+ """
688
+ Return the subcategory of the metric objects of ``self``.
689
+
690
+ TESTS::
691
+
692
+ sage: TestSuite(Sets().Metric()).run()
693
+ """
694
+ from sage.categories.metric_spaces import MetricSpacesCategory
695
+ return MetricSpacesCategory.category_of(self)
696
+
697
+ @cached_method
698
+ def Algebras(self, base_ring):
699
+ """
700
+ Return the category of objects constructed as algebras of
701
+ objects of ``self`` over ``base_ring``.
702
+
703
+ INPUT:
704
+
705
+ - ``base_ring`` -- a ring
706
+
707
+ See :meth:`Sets.ParentMethods.algebra` for the precise
708
+ meaning in Sage of the *algebra of an object*.
709
+
710
+ EXAMPLES::
711
+
712
+ sage: Monoids().Algebras(QQ)
713
+ Category of monoid algebras over Rational Field
714
+
715
+ sage: Groups().Algebras(QQ)
716
+ Category of group algebras over Rational Field
717
+
718
+ sage: AdditiveMagmas().AdditiveAssociative().Algebras(QQ)
719
+ Category of additive semigroup algebras over Rational Field
720
+
721
+ sage: Monoids().Algebras(Rings())
722
+ Category of monoid algebras over Category of rings
723
+
724
+ .. SEEALSO::
725
+
726
+ - :class:`.algebra_functor.AlgebrasCategory`
727
+ - :class:`~.covariant_functorial_construction.CovariantFunctorialConstruction`
728
+
729
+ TESTS::
730
+
731
+ sage: TestSuite(Groups().Finite().Algebras(QQ)).run()
732
+ """
733
+ from sage.categories.rings import Rings
734
+ assert base_ring in Rings() or (isinstance(base_ring, Category)
735
+ and base_ring.is_subcategory(Rings()))
736
+ return AlgebrasCategory.category_of(self, base_ring)
737
+
738
+ @cached_method
739
+ def Finite(self):
740
+ """
741
+ Return the full subcategory of the finite objects of ``self``.
742
+
743
+ EXAMPLES::
744
+
745
+ sage: Sets().Finite()
746
+ Category of finite sets
747
+ sage: Rings().Finite()
748
+ Category of finite rings
749
+
750
+ TESTS::
751
+
752
+ sage: TestSuite(Sets().Finite()).run()
753
+ sage: Rings().Finite.__module__
754
+ 'sage.categories.sets_cat'
755
+ """
756
+ return self._with_axiom('Finite')
757
+
758
+ @cached_method
759
+ def Infinite(self):
760
+ """
761
+ Return the full subcategory of the infinite objects of ``self``.
762
+
763
+ EXAMPLES::
764
+
765
+ sage: Sets().Infinite()
766
+ Category of infinite sets
767
+ sage: Rings().Infinite()
768
+ Category of infinite rings
769
+
770
+ TESTS::
771
+
772
+ sage: TestSuite(Sets().Infinite()).run()
773
+ sage: Rings().Infinite.__module__
774
+ 'sage.categories.sets_cat'
775
+ """
776
+ return self._with_axiom('Infinite')
777
+
778
+ @cached_method
779
+ def Enumerated(self):
780
+ """
781
+ Return the full subcategory of the enumerated objects of ``self``.
782
+
783
+ An enumerated object can be iterated to get its elements.
784
+
785
+ EXAMPLES::
786
+
787
+ sage: Sets().Enumerated()
788
+ Category of enumerated sets
789
+ sage: Rings().Finite().Enumerated()
790
+ Category of finite enumerated rings
791
+ sage: Rings().Infinite().Enumerated()
792
+ Category of infinite enumerated rings
793
+
794
+ TESTS::
795
+
796
+ sage: TestSuite(Sets().Enumerated()).run()
797
+ sage: Rings().Enumerated.__module__
798
+ 'sage.categories.sets_cat'
799
+ """
800
+ return self._with_axiom('Enumerated')
801
+
802
+ def Facade(self):
803
+ r"""
804
+ Return the full subcategory of the facade objects of ``self``.
805
+
806
+ .. _facade-sets:
807
+
808
+ .. RUBRIC:: What is a facade set?
809
+
810
+ Recall that, in Sage, :ref:`sets are modelled by *parents*
811
+ <category-primer-parents-elements-categories>`, and their
812
+ elements know which distinguished set they belong to. For
813
+ example, the ring of integers `\ZZ` is modelled by the
814
+ parent :obj:`ZZ`, and integers know that they belong to
815
+ this set::
816
+
817
+ sage: ZZ
818
+ Integer Ring
819
+ sage: 42.parent()
820
+ Integer Ring
821
+
822
+ Sometimes, it is convenient to represent the elements of a
823
+ parent ``P`` by elements of some other parent. For
824
+ example, the elements of the set of prime numbers are
825
+ represented by plain integers::
826
+
827
+ sage: Primes()
828
+ Set of all prime numbers: 2, 3, 5, 7, ...
829
+ sage: p = Primes().an_element(); p
830
+ 43
831
+ sage: p.parent()
832
+ Integer Ring
833
+
834
+ In this case, ``P`` is called a *facade set*.
835
+
836
+ This feature is advertised through the category of `P`::
837
+
838
+ sage: Primes().category()
839
+ Category of facade infinite enumerated sets
840
+ sage: Sets().Facade()
841
+ Category of facade sets
842
+
843
+ Typical use cases include modeling a subset of an existing
844
+ parent::
845
+
846
+ sage: Set([4,6,9]) # random
847
+ {4, 6, 9}
848
+ sage: Sets().Facade().example()
849
+ An example of facade set: the monoid of positive integers
850
+
851
+ or the union of several parents::
852
+
853
+ sage: Sets().Facade().example("union")
854
+ An example of a facade set: the integers completed by +-infinity
855
+
856
+ or endowing an existing parent with more (or less!)
857
+ structure::
858
+
859
+ sage: Posets().example("facade")
860
+ An example of a facade poset: the positive integers ordered by divisibility
861
+
862
+ Let us investigate in detail a close variant of this last
863
+ example: let `P` be set of divisors of `12` partially
864
+ ordered by divisibility. There are two options for
865
+ representing its elements:
866
+
867
+ 1. as plain integers::
868
+
869
+ sage: P = Poset((divisors(12), attrcall("divides")), facade=True) # needs sage.graphs
870
+
871
+ 2. as integers, modified to be aware that their parent is `P`::
872
+
873
+ sage: Q = Poset((divisors(12), attrcall("divides")), facade=False) # needs sage.graphs
874
+
875
+ The advantage of option 1. is that one needs not do
876
+ conversions back and forth between `P` and `\ZZ`. The
877
+ disadvantage is that this introduces an ambiguity when
878
+ writing `2 < 3`: does this compare `2` and `3` w.r.t. the
879
+ natural order on integers or w.r.t. divisibility?::
880
+
881
+ sage: 2 < 3
882
+ True
883
+
884
+ To raise this ambiguity, one needs to explicitly specify
885
+ the underlying poset as in `2 <_P 3`::
886
+
887
+ sage: P = Posets().example("facade")
888
+ sage: P.lt(2,3)
889
+ False
890
+
891
+ On the other hand, with option 2. and once constructed,
892
+ the elements know unambiguously how to compare
893
+ themselves::
894
+
895
+ sage: Q(2) < Q(3) # needs sage.graphs
896
+ False
897
+ sage: Q(2) < Q(6) # needs sage.graphs
898
+ True
899
+
900
+ Beware that ``P(2)`` is still the integer `2`. Therefore
901
+ ``P(2) < P(3)`` still compares `2` and `3` as integers!::
902
+
903
+ sage: P(2) < P(3)
904
+ True
905
+
906
+ In short `P` being a facade parent is one of the programmatic
907
+ counterparts (with e.g. coercions) of the usual mathematical idiom:
908
+ "for ease of notation, we identify an element of `P` with the
909
+ corresponding integer". Too many identifications lead to
910
+ confusion; the lack thereof leads to heavy, if not obfuscated,
911
+ notations. Finding the right balance is an art, and even though
912
+ there are common guidelines, it is ultimately up to the writer to
913
+ choose which identifications to do. This is no different in code.
914
+
915
+ .. SEEALSO::
916
+
917
+ The following examples illustrate various ways to
918
+ implement subsets like the set of prime numbers; look
919
+ at their code for details::
920
+
921
+ sage: Sets().example("facade")
922
+ Set of prime numbers (facade implementation)
923
+ sage: Sets().example("inherits")
924
+ Set of prime numbers
925
+ sage: Sets().example("wrapper")
926
+ Set of prime numbers (wrapper implementation)
927
+
928
+ .. RUBRIC:: Specifications
929
+
930
+ A parent which is a facade must either:
931
+
932
+ - call :meth:`Parent.__init__` using the ``facade`` parameter to
933
+ specify a parent, or tuple thereof.
934
+ - overload the method :meth:`~Sets.Facade.ParentMethods.facade_for`.
935
+
936
+ .. NOTE::
937
+
938
+ The concept of facade parents was originally introduced
939
+ in the computer algebra system MuPAD.
940
+
941
+ TESTS:
942
+
943
+ Check that multiple categories initialisation
944
+ works (:issue:`13801`)::
945
+
946
+ sage: class A(Parent):
947
+ ....: def __init__(self):
948
+ ....: Parent.__init__(self, category=(FiniteEnumeratedSets(),Monoids()), facade=True)
949
+ sage: a = A()
950
+
951
+ sage: Posets().Facade()
952
+ Category of facade posets
953
+ sage: Posets().Facade().Finite() is Posets().Finite().Facade()
954
+ True
955
+ """
956
+ return self._with_axiom('Facade')
957
+
958
+ class ParentMethods:
959
+ # TODO: simplify the _element_constructor_ definition logic
960
+ # TODO: find a nicer mantra for conditionally defined methods
961
+ @lazy_attribute
962
+ def _element_constructor_(self):
963
+ r"""
964
+ TESTS::
965
+
966
+ sage: S = Sets().example()
967
+ sage: S._element_constructor_(17)
968
+ 17
969
+ sage: S(17) # indirect doctest
970
+ 17
971
+
972
+ sage: A = FreeModule(QQ, 3) # needs sage.modules
973
+ sage: A.element_class # needs sage.modules
974
+ <class 'sage.modules.vector_rational_dense.Vector_rational_dense'>
975
+ sage: A._element_constructor_ # needs sage.modules
976
+ <bound method FreeModule_ambient_field._element_constructor_
977
+ of Vector space of dimension 3 over Rational Field>
978
+
979
+ sage: B = SymmetricGroup(3).algebra(ZZ) # needs sage.combinat sage.groups sage.modules
980
+ sage: B.element_class # needs sage.combinat sage.groups sage.modules
981
+ <...SymmetricGroupAlgebra_n_with_category.element_class'>
982
+ sage: B._element_constructor_ # needs sage.combinat sage.groups sage.modules
983
+ <bound method SymmetricGroupAlgebra_n._element_constructor_
984
+ of Symmetric group algebra of order 3 over Integer Ring>
985
+ """
986
+ if hasattr(self, "element_class"):
987
+ return self._element_constructor_from_element_class
988
+ else:
989
+ return NotImplemented
990
+
991
+ def _element_constructor_from_element_class(self, *args, **keywords):
992
+ """
993
+ The default constructor for elements of this parent ``self``.
994
+
995
+ Among other things, it is called upon ``self(data)`` when
996
+ the coercion model did not find a way to coerce ``data`` into
997
+ this parent.
998
+
999
+ This default implementation for
1000
+ :meth:`_element_constructor_` calls the constructor of the
1001
+ element class, passing ``self`` as first argument.
1002
+
1003
+ EXAMPLES::
1004
+
1005
+ sage: S = Sets().example("inherits")
1006
+ sage: s = S._element_constructor_from_element_class(17); s
1007
+ 17
1008
+ sage: type(s)
1009
+ <class 'sage.categories.examples.sets_cat.PrimeNumbers_Inherits_with_category.element_class'>
1010
+ """
1011
+ return self.element_class(self, *args, **keywords)
1012
+
1013
+ def is_parent_of(self, element):
1014
+ """
1015
+ Return whether ``self`` is the parent of ``element``.
1016
+
1017
+ INPUT:
1018
+
1019
+ - ``element`` -- any object
1020
+
1021
+ EXAMPLES::
1022
+
1023
+ sage: S = ZZ
1024
+ sage: S.is_parent_of(1)
1025
+ True
1026
+ sage: S.is_parent_of(2/1)
1027
+ False
1028
+
1029
+ This method differs from :meth:`__contains__` because it
1030
+ does not attempt any coercion::
1031
+
1032
+ sage: 2/1 in S, S.is_parent_of(2/1)
1033
+ (True, False)
1034
+ sage: int(1) in S, S.is_parent_of(int(1))
1035
+ (True, False)
1036
+ """
1037
+ from sage.structure.element import parent
1038
+ return parent(element) == self
1039
+
1040
+ @abstract_method
1041
+ def __contains__(self, x):
1042
+ """
1043
+ Test whether the set ``self`` contains the object ``x``.
1044
+
1045
+ All parents in the category ``Sets()`` should implement this method.
1046
+
1047
+ EXAMPLES::
1048
+
1049
+ sage: P = Sets().example(); P
1050
+ Set of prime numbers (basic implementation)
1051
+ sage: 12 in P
1052
+ False
1053
+ sage: P(5) in P
1054
+ True
1055
+ """
1056
+
1057
+ @cached_method
1058
+ def an_element(self):
1059
+ r"""
1060
+ Return a (preferably typical) element of this parent.
1061
+
1062
+ This is used both for illustration and testing purposes. If the
1063
+ set ``self`` is empty, :meth:`an_element` should raise the exception
1064
+ :exc:`EmptySetError`.
1065
+
1066
+ This default implementation calls :meth:`_an_element_` and
1067
+ caches the result. Any parent should implement either
1068
+ :meth:`an_element` or :meth:`_an_element_`.
1069
+
1070
+ EXAMPLES::
1071
+
1072
+ sage: CDF.an_element() # needs sage.rings.complex_double
1073
+ 1.0*I
1074
+ sage: ZZ[['t']].an_element()
1075
+ t
1076
+ """
1077
+ return self._an_element_()
1078
+
1079
+ def _test_an_element(self, **options):
1080
+ """
1081
+ Run generic tests on the method :meth:`.an_element`.
1082
+
1083
+ See also: :class:`TestSuite`.
1084
+
1085
+ EXAMPLES::
1086
+
1087
+ sage: C = Sets().example()
1088
+ sage: C._test_an_element()
1089
+
1090
+ Let us now write a broken :meth:`.an_element` method::
1091
+
1092
+ sage: from sage.categories.examples.sets_cat import PrimeNumbers
1093
+ sage: class CCls(PrimeNumbers):
1094
+ ....: def an_element(self):
1095
+ ....: return 18
1096
+ sage: CC = CCls()
1097
+ sage: CC._test_an_element()
1098
+ Traceback (most recent call last):
1099
+ ...
1100
+ AssertionError: self.an_element() is not in self
1101
+
1102
+ TESTS::
1103
+
1104
+ sage: FiniteEnumeratedSet([])._test_an_element()
1105
+ """
1106
+ tester = self._tester(**options)
1107
+ try:
1108
+ an_element = self.an_element()
1109
+ except EmptySetError:
1110
+ return
1111
+ tester.assertIn(an_element, self, "self.an_element() is not in self")
1112
+ # tester.assertTrue(self.is_parent_of(an_element), "self is not the parent of self.an_element()")
1113
+ # tester.assertEqual(self(an_element), an_element, "element construction is not idempotent")
1114
+ if self.is_parent_of(an_element):
1115
+ tester.assertEqual(self(an_element), an_element, "element construction is not idempotent")
1116
+ else: # Allows self(an_element) to fails for facade parent.
1117
+ try:
1118
+ rebuilt_element = self(an_element)
1119
+ except NotImplementedError:
1120
+ tester.info("\n The set doesn't seems to implement __call__; skipping test of construction idempotency")
1121
+ else:
1122
+ tester.assertEqual(rebuilt_element, an_element, "element construction is not idempotent")
1123
+
1124
+ def _test_elements(self, tester=None, **options):
1125
+ """
1126
+ Run generic tests on element(s) of ``self``.
1127
+
1128
+ See also: :class:`TestSuite`.
1129
+
1130
+ EXAMPLES::
1131
+
1132
+ sage: C = Sets().example()
1133
+ sage: C._test_elements(verbose = True)
1134
+ <BLANKLINE>
1135
+ Running the test suite of self.an_element()
1136
+ running ._test_category() . . . pass
1137
+ running ._test_eq() . . . pass
1138
+ running ._test_new() . . . pass
1139
+ running ._test_nonzero_equal() . . . pass
1140
+ running ._test_not_implemented_methods() . . . pass
1141
+ running ._test_pickling() . . . pass
1142
+ <BLANKLINE>
1143
+
1144
+ Debugging tip: in case of failure of this test, run instead::
1145
+
1146
+ sage: TestSuite(C.an_element()).run()
1147
+
1148
+ Let us now implement a parent whose elements cannot be pickled::
1149
+
1150
+ sage: from sage.categories.examples.sets_cat import PrimeNumbers
1151
+ sage: class Bla(SageObject): pass
1152
+ sage: class CCls(PrimeNumbers):
1153
+ ....: def an_element(self):
1154
+ ....: return Bla()
1155
+ sage: CC = CCls()
1156
+ sage: CC._test_elements()
1157
+ Failure in _test_pickling:
1158
+ ...
1159
+ The following tests failed: _test_pickling
1160
+ """
1161
+ # TODO: add native support for nested test suites to TestSuite
1162
+
1163
+ # The intention is to raise an exception only if this is
1164
+ # run as a sub-testsuite of a larger testsuite.
1165
+ is_sub_testsuite = (tester is not None)
1166
+ tester = self._tester(tester=tester, **options)
1167
+ # Or do we want to run the test on some_elements?
1168
+ try:
1169
+ an_element = self.an_element()
1170
+ except EmptySetError:
1171
+ return
1172
+ tester.info("\n Running the test suite of self.an_element()")
1173
+ TestSuite(an_element).run(verbose=tester._verbose,
1174
+ prefix=tester._prefix + " ",
1175
+ raise_on_failure=is_sub_testsuite)
1176
+ tester.info(tester._prefix + " ", newline=False)
1177
+
1178
+ def _test_elements_eq_reflexive(self, **options):
1179
+ """
1180
+ Run generic tests on the equality of elements.
1181
+
1182
+ Test that ``==`` is reflexive.
1183
+
1184
+ See also: :class:`TestSuite`.
1185
+
1186
+ EXAMPLES::
1187
+
1188
+ sage: C = Sets().example()
1189
+ sage: C._test_elements_eq_reflexive()
1190
+
1191
+ We try a non-reflexive equality::
1192
+
1193
+ sage: P = Sets().example("wrapper")
1194
+ sage: P._test_elements_eq_reflexive() # needs sage.libs.pari
1195
+ sage: eq = P.element_class.__eq__
1196
+
1197
+ sage: P.element_class.__eq__ = (lambda x, y:
1198
+ ....: False if eq(x, P(47)) and eq(y, P(47)) else eq(x, y))
1199
+ sage: P._test_elements_eq_reflexive() # needs sage.libs.pari
1200
+ Traceback (most recent call last):
1201
+ ...
1202
+ AssertionError: 47 != 47
1203
+
1204
+ We restore ``P.element_class`` in a proper state for further tests::
1205
+
1206
+ sage: P.element_class.__eq__ = eq
1207
+ """
1208
+ tester = self._tester(**options)
1209
+ S = list(tester.some_elements()) + [None, 0]
1210
+ for x in S:
1211
+ tester.assertEqual(x, x)
1212
+
1213
+ def _test_elements_eq_symmetric(self, **options):
1214
+ """
1215
+ Run generic tests on the equality of elements.
1216
+
1217
+ This tests that ``==`` is symmetric.
1218
+
1219
+ See also: :class:`TestSuite`.
1220
+
1221
+ EXAMPLES::
1222
+
1223
+ sage: C = Sets().example()
1224
+ sage: C._test_elements_eq_symmetric()
1225
+
1226
+ We test a non symmetric equality::
1227
+
1228
+ sage: P = Sets().example("wrapper")
1229
+ sage: P._test_elements_eq_symmetric() # needs sage.libs.pari
1230
+ sage: eq = P.element_class.__eq__
1231
+
1232
+ sage: def non_sym_eq(x, y):
1233
+ ....: if not y in P: return False
1234
+ ....: elif eq(x, P(47)) and eq(y, P(53)): return True
1235
+ ....: else: return eq(x, y)
1236
+ sage: P.element_class.__eq__ = non_sym_eq
1237
+ sage: P._test_elements_eq_symmetric() # needs sage.libs.pari
1238
+ Traceback (most recent call last):
1239
+ ...
1240
+ AssertionError: non symmetric equality: 47 == 53 but 53 != 47
1241
+
1242
+ We restore ``P.element_class`` in a proper state for further tests::
1243
+
1244
+ sage: P.element_class.__eq__ = eq
1245
+ """
1246
+ tester = self._tester(**options)
1247
+ S = list(tester.some_elements()) + [None, 0]
1248
+ from sage.misc.misc import some_tuples
1249
+ for x, y in some_tuples(S, 2, tester._max_runs):
1250
+ tester.assertEqual(x == y, y == x,
1251
+ LazyFormat("non symmetric equality: %s but %s") % (
1252
+ print_compare(x, y), print_compare(y, x)))
1253
+
1254
+ def _test_elements_eq_transitive(self, **options):
1255
+ """
1256
+ Run generic tests on the equality of elements.
1257
+
1258
+ Test that ``==`` is transitive.
1259
+
1260
+ See also: :class:`TestSuite`.
1261
+
1262
+ EXAMPLES::
1263
+
1264
+ sage: C = Sets().example()
1265
+ sage: C._test_elements_eq_transitive()
1266
+
1267
+ We test a non transitive equality::
1268
+
1269
+ sage: R = Zp(3) # needs sage.rings.padics
1270
+ sage: test = raw_getattr(Sets().ParentMethods, "_test_elements_eq_transitive")
1271
+ sage: test(R, elements=[R(3,2), R(3,1), R(0)]) # needs sage.rings.padics
1272
+ Traceback (most recent call last):
1273
+ ...
1274
+ AssertionError: non transitive equality:
1275
+ 3 + O(3^2) == O(3) and O(3) == 0 but 3 + O(3^2) != 0
1276
+ """
1277
+ tester = self._tester(**options)
1278
+ S = list(tester.some_elements())
1279
+ n = max(tester._max_runs, 8)
1280
+ if (len(S)+2)**3 <= n:
1281
+ S = list(S) + [None, 0]
1282
+ else:
1283
+ from random import sample
1284
+ from sage.rings.integer import Integer
1285
+ S = sample(S, Integer(n).nth_root(3,truncate_mode=1)[0] - 2) + [None, 0]
1286
+
1287
+ for x in S:
1288
+ for y in S:
1289
+ if not x == y:
1290
+ continue
1291
+ for z in S:
1292
+ if not y == z:
1293
+ continue
1294
+ tester.assertEqual(x, z,
1295
+ LazyFormat("non transitive equality:\n"
1296
+ "%s and %s but %s") % (
1297
+ print_compare(x, y),
1298
+ print_compare(y, z),
1299
+ print_compare(x, z)))
1300
+
1301
+ def _test_elements_neq(self, **options):
1302
+ """
1303
+ Run generic tests on the equality of elements.
1304
+
1305
+ Test that ``==`` and ``!=`` are consistent.
1306
+
1307
+ See also: :class:`TestSuite`.
1308
+
1309
+ EXAMPLES::
1310
+
1311
+ sage: C = Sets().example()
1312
+ sage: C._test_elements_neq()
1313
+
1314
+ We try a broken inequality::
1315
+
1316
+ sage: P = Sets().example("wrapper")
1317
+ sage: P._test_elements_neq() # needs sage.libs.pari
1318
+ sage: ne = P.element_class.__ne__
1319
+ sage: eq = P.element_class.__eq__
1320
+
1321
+ sage: P.element_class.__ne__ = lambda x, y: False
1322
+ sage: P._test_elements_neq() # needs sage.libs.pari
1323
+ Traceback (most recent call last):
1324
+ ...
1325
+ AssertionError: __eq__ and __ne__ inconsistency:
1326
+ 47 == 53 returns False but 47 != 53 returns False
1327
+
1328
+ sage: P.element_class.__ne__ = lambda x, y: not(x == y)
1329
+
1330
+ We restore ``P.element_class`` in a proper state for further tests::
1331
+
1332
+ sage: P.element_class.__ne__ = ne
1333
+ sage: P.element_class.__eq__ = eq
1334
+ """
1335
+ tester = self._tester(**options)
1336
+ S = list(tester.some_elements()) + [None, 0]
1337
+
1338
+ from sage.misc.misc import some_tuples
1339
+ for x,y in some_tuples(S, 2, tester._max_runs):
1340
+ tester.assertNotEqual(x == y, x != y,
1341
+ LazyFormat("__eq__ and __ne__ inconsistency:\n"
1342
+ " %s == %s returns %s but %s != %s returns %s") % (
1343
+ x, y, (x == y), x, y, (x != y)))
1344
+
1345
+ def some_elements(self):
1346
+ """
1347
+ Return a list (or iterable) of elements of ``self``.
1348
+
1349
+ This is typically used for running generic tests
1350
+ (see :class:`TestSuite`).
1351
+
1352
+ This default implementation calls :meth:`.an_element`.
1353
+
1354
+ EXAMPLES::
1355
+
1356
+ sage: S = Sets().example(); S
1357
+ Set of prime numbers (basic implementation)
1358
+ sage: S.an_element()
1359
+ 47
1360
+ sage: S.some_elements()
1361
+ [47]
1362
+ sage: S = Set([])
1363
+ sage: list(S.some_elements())
1364
+ []
1365
+
1366
+ This method should return an iterable, *not* an iterator.
1367
+ """
1368
+ try:
1369
+ return [self.an_element()]
1370
+ except EmptySetError:
1371
+ return []
1372
+
1373
+ def _test_some_elements(self, **options):
1374
+ """
1375
+ Run generic tests on the method :meth:`.some_elements`.
1376
+
1377
+ .. SEEALSO:: :class:`TestSuite`
1378
+
1379
+ EXAMPLES::
1380
+
1381
+ sage: C = Sets().example()
1382
+ sage: C._test_some_elements()
1383
+
1384
+ Let us now write a broken :meth:`.some_elements` method::
1385
+
1386
+ sage: from sage.categories.examples.sets_cat import *
1387
+ sage: class CCls(PrimeNumbers):
1388
+ ....: def some_elements(self):
1389
+ ....: return [self(17), 32]
1390
+ sage: CC = CCls()
1391
+ sage: CC._test_some_elements()
1392
+ Traceback (most recent call last):
1393
+ ...
1394
+ AssertionError: the object 32 in self.some_elements() is not in self
1395
+ """
1396
+ tester = self._tester(**options)
1397
+ elements = self.some_elements()
1398
+ # Todo: enable this once
1399
+ #tester.assertTrue(elements != iter(elements),
1400
+ # "self.some_elements() should return an iterable, not an iterator")
1401
+ for x in elements:
1402
+ tester.assertIn(x, self, LazyFormat(
1403
+ "the object %s in self.some_elements() is not in self") % (x,))
1404
+
1405
+ #Note: the four methods 'cardinality', 'is_finite_, 'is_empty' and
1406
+ # 'random_element' might or might not be implemented in the parent
1407
+ # objects. Most of the time a default implementation will be provided by
1408
+ # a subcategory of Sets. We do not declare them as optional abstract
1409
+ # methods to not pollute the namespace.
1410
+
1411
+ # def cardinality(self)
1412
+ # def is_finite(self)
1413
+ # def is_empty(self)
1414
+ # def random_element(self):
1415
+
1416
+ def _test_cardinality(self, **options):
1417
+ r"""
1418
+ Run generic test on the method :meth:`.cardinality`.
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: C = Sets().example()
1423
+ sage: C._test_cardinality()
1424
+
1425
+ Let us now write a broken :meth:`cardinality` method::
1426
+
1427
+ sage: from sage.categories.examples.sets_cat import *
1428
+ sage: class CCls(PrimeNumbers):
1429
+ ....: def cardinality(self):
1430
+ ....: return int(5)
1431
+ sage: CC = CCls()
1432
+ sage: CC._test_cardinality()
1433
+ Traceback (most recent call last):
1434
+ ...
1435
+ AssertionError: the output of the method cardinality must either
1436
+ be a Sage integer or infinity. Not <... 'int'>.
1437
+ """
1438
+ try:
1439
+ cardinality = self.cardinality()
1440
+ except (AttributeError,NotImplementedError):
1441
+ return
1442
+ from sage.structure.element import parent
1443
+ from sage.rings.infinity import Infinity
1444
+ from sage.rings.integer_ring import ZZ
1445
+ tester = self._tester(**options)
1446
+ tester.assertTrue(cardinality is Infinity or parent(cardinality) is ZZ,
1447
+ "the output of the method cardinality must either be a Sage integer or infinity. Not {}.".format(type(cardinality)))
1448
+
1449
+ # Functorial constructions
1450
+
1451
+ def construction(self):
1452
+ """
1453
+ Return a pair ``(functor, parent)`` such that
1454
+ ``functor(parent)`` returns ``self``. If ``self`` does
1455
+ not have a functorial construction, return ``None``.
1456
+
1457
+ EXAMPLES::
1458
+
1459
+ sage: QQ.construction()
1460
+ (FractionField, Integer Ring)
1461
+ sage: f, R = QQ['x'].construction()
1462
+ sage: f
1463
+ Poly[x]
1464
+ sage: R
1465
+ Rational Field
1466
+ sage: f(R)
1467
+ Univariate Polynomial Ring in x over Rational Field
1468
+ """
1469
+ return None
1470
+
1471
+ def _test_construction(self, **options):
1472
+ """
1473
+ Test that the construction returned by ``self`` really yields ``self``.
1474
+
1475
+ :meth:`construction` either returns None or a pair ``(F, O)``,
1476
+ and if it returns the latter, then it is supposed that ``F(O) == self``.
1477
+ The test verifies this assumption.
1478
+
1479
+ EXAMPLES:
1480
+
1481
+ We create a parent that returns a wrong construction (its construction
1482
+ returns the rational field rather than the parent itself)::
1483
+
1484
+ sage: class P(Parent):
1485
+ ....: Element = ElementWrapper
1486
+ ....: def __init__(self):
1487
+ ....: Parent.__init__(self, category=Sets())
1488
+ ....: def __eq__(self, P):
1489
+ ....: return type(self) == type(P)
1490
+ ....: def __hash__(self):
1491
+ ....: return hash(type(self))
1492
+ ....: def construction(self):
1493
+ ....: return sage.categories.pushout.FractionField(), ZZ
1494
+ ....:
1495
+ sage: import __main__
1496
+ sage: __main__.P = P # this is to enable pickling in doctests
1497
+ sage: p = P()
1498
+ sage: F,R = p.construction()
1499
+ sage: F(R)
1500
+ Rational Field
1501
+ sage: TestSuite(p).run()
1502
+ Failure in _test_construction:
1503
+ Traceback (most recent call last):
1504
+ ...
1505
+ AssertionError: the object's construction does not recreate this object
1506
+ ...
1507
+ The following tests failed: _test_construction
1508
+
1509
+ If the parent returns the empty construction, the test will not complain::
1510
+
1511
+ sage: ZZ.construction() is None
1512
+ True
1513
+ sage: TestSuite(ZZ).run() # indirect doctest
1514
+
1515
+ If the construction works as expected, the test will not complain
1516
+ either::
1517
+
1518
+ sage: F,R = QQ.construction()
1519
+ sage: F(R) == QQ
1520
+ True
1521
+ sage: TestSuite(QQ).run() # indirect doctest
1522
+ """
1523
+ tester = self._tester(**options)
1524
+ FO = self.construction()
1525
+ if FO is None:
1526
+ return
1527
+ tester.assertEqual(FO[0](FO[1]), self, "the object's construction does not recreate this object")
1528
+
1529
+ CartesianProduct = CartesianProduct
1530
+
1531
+ def cartesian_product(*parents, **kwargs):
1532
+ """
1533
+ Return the Cartesian product of the parents.
1534
+
1535
+ INPUT:
1536
+
1537
+ - ``parents`` -- list (or other iterable) of parents
1538
+
1539
+ - ``category`` -- (default: ``None``) the category the
1540
+ Cartesian product belongs to. If ``None`` is passed,
1541
+ then
1542
+ :meth:`~sage.categories.covariant_functorial_construction.CovariantFactorialConstruction.category_from_parents`
1543
+ is used to determine the category.
1544
+
1545
+ - ``extra_category`` -- (default: ``None``) a category
1546
+ that is added to the Cartesian product in addition
1547
+ to the categories obtained from the parents.
1548
+
1549
+ - other keyword arguments will passed on to the class used
1550
+ for this Cartesian product (see also
1551
+ :class:`~sage.sets.cartesian_product.CartesianProduct`).
1552
+
1553
+ OUTPUT: the Cartesian product
1554
+
1555
+ EXAMPLES::
1556
+
1557
+ sage: C = AlgebrasWithBasis(QQ)
1558
+ sage: A = C.example(); A.rename('A') # needs sage.combinat sage.modules
1559
+ sage: A.cartesian_product(A, A) # needs sage.combinat sage.modules
1560
+ A (+) A (+) A
1561
+ sage: ZZ.cartesian_product(GF(2), FiniteEnumeratedSet([1,2,3]))
1562
+ The Cartesian product of (Integer Ring,
1563
+ Finite Field of size 2, {1, 2, 3})
1564
+
1565
+ sage: C = ZZ.cartesian_product(A); C # needs sage.combinat sage.modules
1566
+ The Cartesian product of (Integer Ring, A)
1567
+
1568
+ TESTS::
1569
+
1570
+ sage: type(C) # needs sage.combinat sage.modules
1571
+ <class 'sage.sets.cartesian_product.CartesianProduct_with_category'>
1572
+ sage: C.category() # needs sage.combinat sage.modules
1573
+ Join of Category of rings and ...
1574
+ and Category of Cartesian products of commutative additive groups
1575
+
1576
+ ::
1577
+
1578
+ sage: cartesian_product([ZZ, ZZ], category=Sets()).category()
1579
+ Category of sets
1580
+ sage: cartesian_product([ZZ, ZZ]).category()
1581
+ Join of
1582
+ Category of Cartesian products of commutative rings and
1583
+ Category of Cartesian products of metric spaces and
1584
+ Category of Cartesian products of enumerated sets
1585
+ sage: cartesian_product([ZZ, ZZ], extra_category=Posets()).category()
1586
+ Join of
1587
+ Category of Cartesian products of commutative rings and
1588
+ Category of posets and
1589
+ Category of Cartesian products of metric spaces and
1590
+ Category of Cartesian products of enumerated sets
1591
+ """
1592
+ category = kwargs.pop('category', None)
1593
+ extra_category = kwargs.pop('extra_category', None)
1594
+
1595
+ category = category or cartesian_product.category_from_parents(parents)
1596
+ if extra_category:
1597
+ if isinstance(category, (list, tuple)):
1598
+ category = tuple(category) + (extra_category,)
1599
+ else:
1600
+ category = category & extra_category
1601
+ return parents[0].CartesianProduct(parents, category=category, **kwargs)
1602
+
1603
+ def algebra(self, base_ring, category=None, **kwds):
1604
+ """
1605
+ Return the algebra of ``self`` over ``base_ring``.
1606
+
1607
+ INPUT:
1608
+
1609
+ - ``self`` -- a parent `S`
1610
+ - ``base_ring`` -- a ring `K`
1611
+ - ``category`` -- a super category of the category
1612
+ of `S`, or ``None``
1613
+
1614
+ This returns the space of formal linear combinations of
1615
+ elements of `S` with coefficients in `K`, endowed with
1616
+ whatever structure can be induced from that of `S`.
1617
+ See the documentation of
1618
+ :mod:`sage.categories.algebra_functor` for details.
1619
+
1620
+ EXAMPLES:
1621
+
1622
+ If `S` is a :class:`group <Groups>`, the result is its
1623
+ group algebra `KS`::
1624
+
1625
+ sage: # needs sage.groups sage.modules
1626
+ sage: S = DihedralGroup(4); S
1627
+ Dihedral group of order 8 as a permutation group
1628
+ sage: A = S.algebra(QQ); A
1629
+ Algebra of Dihedral group of order 8 as a permutation group
1630
+ over Rational Field
1631
+ sage: A.category()
1632
+ Category of finite group algebras over Rational Field
1633
+ sage: a = A.an_element(); a
1634
+ () + (1,3) + 2*(1,3)(2,4) + 3*(1,4,3,2)
1635
+
1636
+ This space is endowed with an algebra structure, obtained
1637
+ by extending by bilinearity the multiplication of `G` to a
1638
+ multiplication on `RG`::
1639
+
1640
+ sage: a * a # needs sage.groups sage.modules
1641
+ 6*() + 4*(2,4) + 3*(1,2)(3,4) + 12*(1,2,3,4) + 2*(1,3)
1642
+ + 13*(1,3)(2,4) + 6*(1,4,3,2) + 3*(1,4)(2,3)
1643
+
1644
+ If `S` is a :class:`monoid <Monoids>`, the result is its
1645
+ monoid algebra `KS`::
1646
+
1647
+ sage: S = Monoids().example(); S
1648
+ An example of a monoid:
1649
+ the free monoid generated by ('a', 'b', 'c', 'd')
1650
+ sage: A = S.algebra(QQ); A # needs sage.modules
1651
+ Algebra of
1652
+ An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd')
1653
+ over Rational Field
1654
+ sage: A.category() # needs sage.modules
1655
+ Category of monoid algebras over Rational Field
1656
+
1657
+ Similarly, we can construct algebras for additive magmas,
1658
+ monoids, and groups.
1659
+
1660
+ One may specify for which category one takes the algebra;
1661
+ here we build the algebra of the additive group `GF_3`::
1662
+
1663
+ sage: # needs sage.modules
1664
+ sage: from sage.categories.additive_groups import AdditiveGroups
1665
+ sage: S = GF(7)
1666
+ sage: A = S.algebra(QQ, category=AdditiveGroups()); A
1667
+ Algebra of Finite Field of size 7 over Rational Field
1668
+ sage: A.category()
1669
+ Category of finite dimensional additive group algebras
1670
+ over Rational Field
1671
+ sage: a = A(S(1))
1672
+ sage: a
1673
+ 1
1674
+ sage: 1 + a * a * a
1675
+ 0 + 3
1676
+
1677
+ Note that the ``category`` keyword needs to be fed with
1678
+ the structure on `S` to be used, not the induced structure
1679
+ on the result.
1680
+ """
1681
+ if category is None:
1682
+ category = self.category()
1683
+ from sage.categories.semigroups import Semigroups
1684
+ from sage.categories.commutative_additive_semigroups import CommutativeAdditiveSemigroups
1685
+ if category.is_subcategory(Semigroups()) and category.is_subcategory(CommutativeAdditiveSemigroups()):
1686
+ raise TypeError(
1687
+ """ `S = {}` is both an additive and a multiplicative semigroup.
1688
+ Constructing its algebra is ambiguous.
1689
+ Please use, e.g., S.algebra(QQ, category=Semigroups())""".format(self))
1690
+ from sage.categories.groups import Groups
1691
+ from sage.categories.additive_groups import AdditiveGroups
1692
+ from sage.algebras.group_algebra import GroupAlgebra_class
1693
+ algebra_category = category.Algebras(base_ring)
1694
+ if (category.is_subcategory(Groups())
1695
+ or category.is_subcategory(AdditiveGroups())):
1696
+ # Somewhat dirty hack to wrap non-atomic objects
1697
+ from sage.categories.modules_with_basis import ModulesWithBasis
1698
+ if self not in ModulesWithBasis:
1699
+ if 'prefix' not in kwds:
1700
+ kwds['prefix'] = ''
1701
+ if 'bracket' not in kwds:
1702
+ kwds['bracket'] = False
1703
+ result = GroupAlgebra_class(base_ring, self,
1704
+ category=algebra_category, **kwds)
1705
+ result.__doc__ = Sets.ParentMethods.algebra.__doc__
1706
+ return result
1707
+
1708
+ def _sympy_(self):
1709
+ """
1710
+ Return an instance of a subclass of SymPy ``Set`` corresponding to ``self``.
1711
+
1712
+ The default implementation creates an instance of
1713
+ :class:`~sage.interfaces.sympy_wrapper`.
1714
+
1715
+ EXAMPLES::
1716
+
1717
+ sage: # needs sympy
1718
+ sage: F = FiniteEnumeratedSets().example(); F
1719
+ An example of a finite enumerated set: {1,2,3}
1720
+ sage: sF = F._sympy_(); sF
1721
+ SageSet(An example of a finite enumerated set: {1,2,3})
1722
+ sage: sF.is_finite_set
1723
+ True
1724
+ sage: bool(sF)
1725
+ True
1726
+ sage: len(sF)
1727
+ 3
1728
+ sage: list(sF)
1729
+ [1, 2, 3]
1730
+ sage: from sympy import FiniteSet
1731
+ sage: FiniteSet.fromiter(sF) # random - this output is sympy >= 1.9
1732
+ FiniteSet(1, 2, 3)
1733
+
1734
+ sage: RR._sympy_().is_finite_set # needs sympy
1735
+ False
1736
+
1737
+ sage: F = Family([1, 2])
1738
+ sage: F is Family([1, 2])
1739
+ False
1740
+ sage: sF = F._sympy_(); sF # needs sympy
1741
+ SageSet(Family (1, 2))
1742
+ sage: sF._sage_() is F # needs sympy
1743
+ True
1744
+ """
1745
+ from sage.interfaces.sympy_wrapper import SageSet
1746
+ from sage.interfaces.sympy import sympy_init
1747
+ sympy_init()
1748
+ return SageSet(self)
1749
+
1750
+ class ElementMethods:
1751
+ ## Should eventually contain the basic operations which are no math
1752
+ ## latex, hash, ...
1753
+ ##def equal(x, y):
1754
+ ##def =(x, y):
1755
+
1756
+ # Used by Element._test_category
1757
+ _dummy_attribute = None
1758
+
1759
+ def cartesian_product(*elements):
1760
+ """
1761
+ Return the Cartesian product of its arguments, as an element of
1762
+ the Cartesian product of the parents of those elements.
1763
+
1764
+ EXAMPLES::
1765
+
1766
+ sage: C = AlgebrasWithBasis(QQ)
1767
+ sage: A = C.example() # needs sage.combinat sage.modules
1768
+ sage: a, b, c = A.algebra_generators() # needs sage.combinat sage.modules
1769
+ sage: a.cartesian_product(b, c) # needs sage.combinat sage.modules
1770
+ B[(0, word: a)] + B[(1, word: b)] + B[(2, word: c)]
1771
+
1772
+ FIXME: is this a policy that we want to enforce on all parents?
1773
+ """
1774
+ from sage.structure.element import parent, Element
1775
+ assert all(isinstance(element, Element) for element in elements)
1776
+ parents = [parent(element) for element in elements]
1777
+ return cartesian_product(parents)._cartesian_product_of_elements(elements) # good name???
1778
+
1779
+ class MorphismMethods:
1780
+ @abstract_method(optional=True)
1781
+ def __invert__(self):
1782
+ r"""
1783
+ Return the inverse morphism, or raise an error.
1784
+
1785
+ The error may either state that the morphism is not
1786
+ invertible, or that Sage cannot invert it.
1787
+
1788
+ EXAMPLES::
1789
+
1790
+ sage: i = End(QQ).identity(); i
1791
+ Identity endomorphism of Rational Field
1792
+ sage: i.__invert__()
1793
+ Identity endomorphism of Rational Field
1794
+
1795
+ This method is meant to be used with the Python inversion
1796
+ operator `~`::
1797
+
1798
+ sage: ~i
1799
+ Identity endomorphism of Rational Field
1800
+
1801
+ We now try to inverse a couple of morphisms defined by a matrix::
1802
+
1803
+ sage: H = End(QQ^2) # needs sage.modules
1804
+ sage: phi = H(matrix([[1,1], [0,1]])); phi # needs sage.modules
1805
+ Vector space morphism represented by the matrix:
1806
+ [1 1]
1807
+ [0 1]
1808
+ Domain: Vector space of dimension 2 over Rational Field
1809
+ Codomain: Vector space of dimension 2 over Rational Field
1810
+ sage: ~phi # needs sage.modules
1811
+ Vector space morphism represented by the matrix:
1812
+ [ 1 -1]
1813
+ [ 0 1]
1814
+ Domain: Vector space of dimension 2 over Rational Field
1815
+ Codomain: Vector space of dimension 2 over Rational Field
1816
+
1817
+ sage: phi = H(matrix([[1,1], [1,1]])) # needs sage.modules
1818
+ sage: ~phi # needs sage.modules
1819
+ Traceback (most recent call last):
1820
+ ...
1821
+ ZeroDivisionError: matrix morphism not invertible
1822
+
1823
+ .. NOTE::
1824
+
1825
+ This is an optional method. A default implementation
1826
+ raising :exc:`NotImplementedError` could be provided instead.
1827
+ """
1828
+
1829
+ def is_injective(self):
1830
+ r"""
1831
+ Return whether this map is injective.
1832
+
1833
+ EXAMPLES::
1834
+
1835
+ sage: f = ZZ.hom(GF(3)); f
1836
+ Natural morphism:
1837
+ From: Integer Ring
1838
+ To: Finite Field of size 3
1839
+ sage: f.is_injective()
1840
+ False
1841
+ """
1842
+ if self.domain().cardinality() <= 1:
1843
+ return True
1844
+ if self.domain().cardinality() > self.codomain().cardinality():
1845
+ return False
1846
+ raise NotImplementedError
1847
+
1848
+ def image(self, domain_subset=None):
1849
+ r"""
1850
+ Return the image of the domain or of ``domain_subset``.
1851
+
1852
+ EXAMPLES::
1853
+
1854
+ sage: # needs sage.combinat
1855
+ sage: P = Partitions(6)
1856
+ sage: H = Hom(P, ZZ)
1857
+ sage: f = H(ZZ.sum)
1858
+ sage: X = f.image() # needs sage.libs.flint
1859
+ sage: list(X) # needs sage.libs.flint
1860
+ [6]
1861
+ """
1862
+ D = self.domain()
1863
+ if D is None:
1864
+ raise ValueError("this map became defunct by garbage collection")
1865
+ if domain_subset is None or domain_subset == D:
1866
+ try:
1867
+ if self.is_surjective():
1868
+ return D
1869
+ except NotImplementedError:
1870
+ pass
1871
+ domain_subset = D
1872
+ from sage.sets.set import Set_base
1873
+ from sage.sets.image_set import ImageSubobject, ImageSet
1874
+ if isinstance(domain_subset, Set_base):
1875
+ # Most of our parents are sets, but the mixin class Set_base
1876
+ # provides the full kit of operators. The image should get them too.
1877
+ cls = ImageSet
1878
+ else:
1879
+ cls = ImageSubobject
1880
+ return cls(self, domain_subset)
1881
+
1882
+ # Lazy imports to avoid circularity issues.
1883
+ Enumerated = LazyImport('sage.categories.enumerated_sets', 'EnumeratedSets', at_startup=True)
1884
+ Finite = LazyImport('sage.categories.finite_sets', 'FiniteSets', at_startup=True)
1885
+ Topological = LazyImport('sage.categories.topological_spaces',
1886
+ 'TopologicalSpaces', 'Topological', at_startup=True)
1887
+ Metric = LazyImport('sage.categories.metric_spaces', 'MetricSpaces',
1888
+ 'Metric', at_startup=True)
1889
+ from sage.categories.facade_sets import FacadeSets as Facade
1890
+
1891
+ class Infinite(CategoryWithAxiom):
1892
+
1893
+ class ParentMethods:
1894
+
1895
+ def is_finite(self):
1896
+ """
1897
+ Return whether this set is finite.
1898
+
1899
+ Since this set is infinite this always returns ``False``.
1900
+
1901
+ EXAMPLES::
1902
+
1903
+ sage: C = InfiniteEnumeratedSets().example()
1904
+ sage: C.is_finite()
1905
+ False
1906
+
1907
+ TESTS::
1908
+
1909
+ sage: C.is_finite.__func__ is sage.categories.sets_cat.Sets.Infinite.ParentMethods.is_finite
1910
+ True
1911
+ """
1912
+ return False
1913
+
1914
+ def is_empty(self):
1915
+ r"""
1916
+ Return whether this set is empty.
1917
+
1918
+ Since this set is infinite this always returns ``False``.
1919
+
1920
+ EXAMPLES::
1921
+
1922
+ sage: C = InfiniteEnumeratedSets().example()
1923
+ sage: C.is_empty()
1924
+ False
1925
+ """
1926
+ return False
1927
+
1928
+ def cardinality(self):
1929
+ """
1930
+ Count the elements of the enumerated set.
1931
+
1932
+ EXAMPLES::
1933
+
1934
+ sage: NN = InfiniteEnumeratedSets().example()
1935
+ sage: NN.cardinality()
1936
+ +Infinity
1937
+ """
1938
+ from sage.rings.infinity import infinity
1939
+ return infinity
1940
+
1941
+ class Subquotients(SubquotientsCategory):
1942
+ """
1943
+ A category for subquotients of sets.
1944
+
1945
+ .. SEEALSO:: :meth:`Sets().Subquotients`
1946
+
1947
+ EXAMPLES::
1948
+
1949
+ sage: Sets().Subquotients()
1950
+ Category of subquotients of sets
1951
+ sage: Sets().Subquotients().all_super_categories()
1952
+ [Category of subquotients of sets, Category of sets,
1953
+ Category of sets with partial maps,
1954
+ Category of objects]
1955
+ """
1956
+
1957
+ class ParentMethods:
1958
+
1959
+ def _repr_(self):
1960
+ """
1961
+ EXAMPLES::
1962
+
1963
+ sage: from sage.categories.examples.semigroups import IncompleteSubquotientSemigroup
1964
+ sage: S = IncompleteSubquotientSemigroup()
1965
+ sage: S._repr_()
1966
+ 'A subquotient of An example of a semigroup: the left zero semigroup'
1967
+ """
1968
+ return "A subquotient of %s" % (self.ambient())
1969
+
1970
+ @abstract_method
1971
+ def ambient(self):
1972
+ """
1973
+ Return the ambient space for ``self``.
1974
+
1975
+ EXAMPLES::
1976
+
1977
+ sage: Semigroups().Subquotients().example().ambient()
1978
+ An example of a semigroup: the left zero semigroup
1979
+
1980
+ .. SEEALSO::
1981
+
1982
+ :meth:`Sets.SubcategoryMethods.Subquotients` for the
1983
+ specifications and :meth:`.lift` and :meth:`.retract`.
1984
+ """
1985
+
1986
+ # Should lift and retract be declared as conversions to the coercion mechanism ?
1987
+ # Compatibility issue: in IntegerModRing, lift is a method returning the actual
1988
+ # lifting morphism::
1989
+ #
1990
+ # sage: F = IntegerModRing(3)
1991
+ # sage: F.lift()
1992
+ # Set-theoretic ring morphism:
1993
+ # From: Ring of integers modulo 3
1994
+ # To: Integer Ring
1995
+ # Defn: Choice of lifting map
1996
+ @abstract_method
1997
+ def lift(self, x):
1998
+ """
1999
+ Lift `x` to the ambient space for ``self``.
2000
+
2001
+ INPUT:
2002
+
2003
+ - ``x`` -- an element of ``self``
2004
+
2005
+ EXAMPLES::
2006
+
2007
+ sage: S = Semigroups().Subquotients().example()
2008
+ sage: s = S.an_element()
2009
+ sage: s, s.parent()
2010
+ (42, An example of a (sub)quotient semigroup:
2011
+ a quotient of the left zero semigroup)
2012
+ sage: S.lift(s), S.lift(s).parent()
2013
+ (42, An example of a semigroup: the left zero semigroup)
2014
+ sage: s.lift(), s.lift().parent()
2015
+ (42, An example of a semigroup: the left zero semigroup)
2016
+
2017
+ .. SEEALSO::
2018
+
2019
+ :class:`Sets.SubcategoryMethods.Subquotients` for
2020
+ the specifications, :meth:`.ambient`, :meth:`.retract`,
2021
+ and also :meth:`Sets.Subquotients.ElementMethods.lift`.
2022
+ """
2023
+
2024
+ @abstract_method
2025
+ def retract(self, x):
2026
+ """
2027
+ Retract ``x`` to ``self``.
2028
+
2029
+ INPUT:
2030
+
2031
+ - ``x`` -- an element of the ambient space for ``self``
2032
+
2033
+ .. SEEALSO::
2034
+
2035
+ :class:`Sets.SubcategoryMethods.Subquotients` for
2036
+ the specifications, :meth:`.ambient`, :meth:`.retract`,
2037
+ and also :meth:`Sets.Subquotients.ElementMethods.retract`.
2038
+
2039
+ EXAMPLES::
2040
+
2041
+ sage: S = Semigroups().Subquotients().example()
2042
+ sage: s = S.ambient().an_element()
2043
+ sage: s, s.parent()
2044
+ (42, An example of a semigroup: the left zero semigroup)
2045
+ sage: S.retract(s), S.retract(s).parent()
2046
+ (42, An example of a (sub)quotient semigroup:
2047
+ a quotient of the left zero semigroup)
2048
+ """
2049
+
2050
+ class ElementMethods:
2051
+
2052
+ def lift(self):
2053
+ """
2054
+ Lift ``self`` to the ambient space for its parent.
2055
+
2056
+ EXAMPLES::
2057
+
2058
+ sage: S = Semigroups().Subquotients().example()
2059
+ sage: s = S.an_element()
2060
+ sage: s, s.parent()
2061
+ (42, An example of a (sub)quotient semigroup:
2062
+ a quotient of the left zero semigroup)
2063
+ sage: S.lift(s), S.lift(s).parent()
2064
+ (42, An example of a semigroup: the left zero semigroup)
2065
+ sage: s.lift(), s.lift().parent()
2066
+ (42, An example of a semigroup: the left zero semigroup)
2067
+ """
2068
+ return self.parent().lift(self)
2069
+
2070
+ class Quotients(QuotientsCategory):
2071
+ """
2072
+ A category for quotients of sets.
2073
+
2074
+ .. SEEALSO:: :meth:`Sets().Quotients`
2075
+
2076
+ EXAMPLES::
2077
+
2078
+ sage: Sets().Quotients()
2079
+ Category of quotients of sets
2080
+ sage: Sets().Quotients().all_super_categories()
2081
+ [Category of quotients of sets,
2082
+ Category of subquotients of sets,
2083
+ Category of sets,
2084
+ Category of sets with partial maps,
2085
+ Category of objects]
2086
+ """
2087
+
2088
+ class ParentMethods:
2089
+
2090
+ def _repr_(self):
2091
+ """
2092
+ EXAMPLES::
2093
+
2094
+ sage: from sage.categories.examples.semigroups import IncompleteSubquotientSemigroup
2095
+ sage: S = IncompleteSubquotientSemigroup(category=Semigroups().Quotients())
2096
+ sage: S._repr_()
2097
+ 'A quotient of An example of a semigroup: the left zero semigroup'
2098
+ """
2099
+ return "A quotient of {}".format(self.ambient())
2100
+
2101
+ def _an_element_(self):
2102
+ """
2103
+ Return an element of ``self``, as per
2104
+ :meth:`Sets.ParentMethods.an_element`
2105
+
2106
+ EXAMPLES::
2107
+
2108
+ sage: S = FiniteEnumeratedSets().IsomorphicObjects().example()
2109
+ sage: S.an_element() # indirect doctest
2110
+ 1
2111
+ """
2112
+ return self.retract(self.ambient().an_element())
2113
+
2114
+ class Subobjects(SubobjectsCategory):
2115
+ """
2116
+ A category for subobjects of sets.
2117
+
2118
+ .. SEEALSO:: :meth:`Sets().Subobjects`
2119
+
2120
+ EXAMPLES::
2121
+
2122
+ sage: Sets().Subobjects()
2123
+ Category of subobjects of sets
2124
+ sage: Sets().Subobjects().all_super_categories()
2125
+ [Category of subobjects of sets,
2126
+ Category of subquotients of sets,
2127
+ Category of sets,
2128
+ Category of sets with partial maps,
2129
+ Category of objects]
2130
+ """
2131
+
2132
+ class ParentMethods:
2133
+
2134
+ def _repr_(self):
2135
+ """
2136
+ EXAMPLES::
2137
+
2138
+ sage: from sage.categories.examples.semigroups import IncompleteSubquotientSemigroup
2139
+ sage: S = IncompleteSubquotientSemigroup(category=Semigroups().Subobjects())
2140
+ sage: S._repr_()
2141
+ 'A subobject of An example of a semigroup: the left zero semigroup'
2142
+ """
2143
+ return "A subobject of {}".format(self.ambient())
2144
+
2145
+ class IsomorphicObjects(IsomorphicObjectsCategory):
2146
+ """
2147
+ A category for isomorphic objects of sets.
2148
+
2149
+ EXAMPLES::
2150
+
2151
+ sage: Sets().IsomorphicObjects()
2152
+ Category of isomorphic objects of sets
2153
+ sage: Sets().IsomorphicObjects().all_super_categories()
2154
+ [Category of isomorphic objects of sets,
2155
+ Category of subobjects of sets, Category of quotients of sets,
2156
+ Category of subquotients of sets,
2157
+ Category of sets,
2158
+ Category of sets with partial maps,
2159
+ Category of objects]
2160
+ """
2161
+
2162
+ class ParentMethods:
2163
+
2164
+ def _repr_(self):
2165
+ """
2166
+ EXAMPLES::
2167
+
2168
+ sage: S = FiniteEnumeratedSets().IsomorphicObjects().example()
2169
+ sage: S._repr_()
2170
+ 'The image by some isomorphism of An example of a finite enumerated set: {1,2,3}'
2171
+ """
2172
+ return "The image by some isomorphism of %s" % (self.ambient())
2173
+
2174
+ class CartesianProducts(CartesianProductsCategory):
2175
+ """
2176
+ EXAMPLES::
2177
+
2178
+ sage: C = Sets().CartesianProducts().example()
2179
+ sage: C
2180
+ The Cartesian product of (Set of prime numbers (basic implementation),
2181
+ An example of an infinite enumerated set: the nonnegative integers,
2182
+ An example of a finite enumerated set: {1,2,3})
2183
+ sage: C.category()
2184
+ Category of Cartesian products of sets
2185
+ sage: C.categories()
2186
+ [Category of Cartesian products of sets, Category of sets,
2187
+ Category of sets with partial maps,
2188
+ Category of objects]
2189
+ sage: TestSuite(C).run()
2190
+ """
2191
+
2192
+ def extra_super_categories(self):
2193
+ """
2194
+ A Cartesian product of sets is a set.
2195
+
2196
+ EXAMPLES::
2197
+
2198
+ sage: Sets().CartesianProducts().extra_super_categories()
2199
+ [Category of sets]
2200
+ sage: Sets().CartesianProducts().super_categories()
2201
+ [Category of sets]
2202
+ """
2203
+ return [Sets()]
2204
+
2205
+ def example(self):
2206
+ """
2207
+ EXAMPLES::
2208
+
2209
+ sage: Sets().CartesianProducts().example()
2210
+ The Cartesian product of (Set of prime numbers (basic implementation),
2211
+ An example of an infinite enumerated set: the nonnegative integers,
2212
+ An example of a finite enumerated set: {1,2,3})
2213
+ """
2214
+ from .finite_enumerated_sets import FiniteEnumeratedSets
2215
+ from .infinite_enumerated_sets import InfiniteEnumeratedSets
2216
+ from .cartesian_product import cartesian_product
2217
+ S1 = Sets().example()
2218
+ S2 = InfiniteEnumeratedSets().example()
2219
+ S3 = FiniteEnumeratedSets().example()
2220
+ return cartesian_product([S1, S2, S3])
2221
+
2222
+ class ParentMethods:
2223
+ def __iter__(self):
2224
+ r"""
2225
+ Return an iterator for the elements of this Cartesian product.
2226
+
2227
+ If all factors (except possibly the first factor) are known to be finite,
2228
+ it uses the lexicographic order.
2229
+
2230
+ Otherwise, the iterator enumerates the elements in increasing
2231
+ order of sum-of-ranks, refined by the reverse lexicographic order
2232
+ (see :func:`~sage.misc.mrange.cantor_product`).
2233
+
2234
+ EXAMPLES:
2235
+
2236
+ Sets are intrinsically unordered::
2237
+
2238
+ sage: for x,y in cartesian_product([Set([1,2]), Set(['a','b'])]): # random
2239
+ ....: print((x, y))
2240
+ (1, 'b')
2241
+ (1, 'a')
2242
+ (2, 'b')
2243
+ (2, 'a')
2244
+
2245
+ sage: A = FiniteEnumeratedSets()(["a", "b"])
2246
+ sage: B = FiniteEnumeratedSets().example(); B
2247
+ An example of a finite enumerated set: {1,2,3}
2248
+ sage: C = cartesian_product([A, B, A]); C
2249
+ The Cartesian product of ({'a', 'b'}, An example of a finite enumerated set: {1,2,3}, {'a', 'b'})
2250
+ sage: C in FiniteEnumeratedSets()
2251
+ True
2252
+ sage: list(C)
2253
+ [('a', 1, 'a'), ('a', 1, 'b'), ('a', 2, 'a'), ('a', 2, 'b'), ('a', 3, 'a'), ('a', 3, 'b'),
2254
+ ('b', 1, 'a'), ('b', 1, 'b'), ('b', 2, 'a'), ('b', 2, 'b'), ('b', 3, 'a'), ('b', 3, 'b')]
2255
+ sage: C.__iter__.__module__
2256
+ 'sage.categories.sets_cat'
2257
+
2258
+ sage: F22 = GF(2).cartesian_product(GF(2))
2259
+ sage: list(F22)
2260
+ [(0, 0), (0, 1), (1, 0), (1, 1)]
2261
+
2262
+ sage: # needs sage.combinat
2263
+ sage: C = cartesian_product([Permutations(10)]*4)
2264
+ sage: it = iter(C)
2265
+ sage: next(it)
2266
+ ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2267
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2268
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2269
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
2270
+ sage: next(it)
2271
+ ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2272
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2273
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
2274
+ [1, 2, 3, 4, 5, 6, 7, 8, 10, 9])
2275
+
2276
+ When all factors (except possibly the first factor) are known to be finite, it
2277
+ uses the lexicographic order::
2278
+
2279
+ sage: it = iter(cartesian_product([ZZ, GF(2)]))
2280
+ sage: [next(it) for _ in range(10)]
2281
+ [(0, 0), (0, 1),
2282
+ (1, 0), (1, 1),
2283
+ (-1, 0), (-1, 1),
2284
+ (2, 0), (2, 1),
2285
+ (-2, 0), (-2, 1)]
2286
+
2287
+ When other factors are infinite (or not known to be finite), it enumerates
2288
+ the elements in increasing order of sum-of-ranks::
2289
+
2290
+ sage: NN = NonNegativeIntegers()
2291
+ sage: it = iter(cartesian_product([NN, NN]))
2292
+ sage: [next(it) for _ in range(10)]
2293
+ [(0, 0),
2294
+ (1, 0), (0, 1),
2295
+ (2, 0), (1, 1), (0, 2),
2296
+ (3, 0), (2, 1), (1, 2), (0, 3)]
2297
+
2298
+ An example with the first factor finite, the second infinite::
2299
+
2300
+ sage: it = iter(cartesian_product([GF(2), ZZ]))
2301
+ sage: [next(it) for _ in range(11)]
2302
+ [(0, 0),
2303
+ (1, 0), (0, 1),
2304
+ (1, 1), (0, -1),
2305
+ (1, -1), (0, 2),
2306
+ (1, 2), (0, -2),
2307
+ (1, -2), (0, 3)]
2308
+
2309
+ .. NOTE::
2310
+
2311
+ Here it would be faster to use :func:`itertools.product` for sets
2312
+ of small size. But the latter expands all factor in memory!
2313
+ So we can not reasonably use it in general.
2314
+
2315
+ ALGORITHM:
2316
+
2317
+ The lexicographic enumeration follows Recipe 19.9 in the Python Cookbook
2318
+ by Alex Martelli and David Ascher.
2319
+ """
2320
+ factors = list(self.cartesian_factors())
2321
+ if any(f not in Sets().Finite() for f in factors[1:]):
2322
+ from sage.misc.mrange import cantor_product
2323
+ for t in cantor_product(*factors):
2324
+ yield self._cartesian_product_of_elements(t)
2325
+ return
2326
+
2327
+ # Lexicographic enumeration:
2328
+ # visualize an odometer, with "wheels" displaying "digits"...:
2329
+ wheels = [iter(f) for f in factors]
2330
+ try:
2331
+ digits = [next(it) for it in wheels]
2332
+ except StopIteration:
2333
+ return
2334
+ while True:
2335
+ yield self._cartesian_product_of_elements(digits)
2336
+ for i in range(len(digits)-1, -1, -1):
2337
+ try:
2338
+ digits[i] = next(wheels[i])
2339
+ break
2340
+ except StopIteration:
2341
+ wheels[i] = iter(factors[i])
2342
+ try:
2343
+ digits[i] = next(wheels[i])
2344
+ except StopIteration:
2345
+ return
2346
+ else:
2347
+ break
2348
+
2349
+ @cached_method
2350
+ def an_element(self):
2351
+ """
2352
+ EXAMPLES::
2353
+
2354
+ sage: C = Sets().CartesianProducts().example(); C
2355
+ The Cartesian product of (Set of prime numbers (basic implementation),
2356
+ An example of an infinite enumerated set: the nonnegative integers,
2357
+ An example of a finite enumerated set: {1,2,3})
2358
+ sage: C.an_element()
2359
+ (47, 42, 1)
2360
+ """
2361
+ return self._cartesian_product_of_elements(s.an_element() for s in self._sets)
2362
+
2363
+ def is_empty(self):
2364
+ r"""
2365
+ Return whether this set is empty.
2366
+
2367
+ EXAMPLES::
2368
+
2369
+
2370
+ sage: S1 = FiniteEnumeratedSet([1,2,3])
2371
+ sage: S2 = Set([])
2372
+ sage: cartesian_product([S1,ZZ]).is_empty()
2373
+ False
2374
+ sage: cartesian_product([S1,S2,S1]).is_empty()
2375
+ True
2376
+
2377
+ Even when some parent did not implement ``is_empty``,
2378
+ as long as one element is nonempty, the result can be determined::
2379
+
2380
+ sage: C = ConditionSet(QQ, lambda x: x > 0)
2381
+ sage: C.is_empty()
2382
+ Traceback (most recent call last):
2383
+ ...
2384
+ AttributeError...
2385
+ sage: cartesian_product([C,[]]).is_empty()
2386
+ True
2387
+ sage: cartesian_product([C,C]).is_empty()
2388
+ Traceback (most recent call last):
2389
+ ...
2390
+ NotImplementedError...
2391
+ """
2392
+ last_exception = None
2393
+ for c in self.cartesian_factors():
2394
+ try:
2395
+ if c.is_empty():
2396
+ return True
2397
+ except (AttributeError, NotImplementedError) as e:
2398
+ last_exception = e
2399
+ if last_exception is not None:
2400
+ raise NotImplementedError from last_exception
2401
+ return False
2402
+
2403
+ def is_finite(self):
2404
+ r"""
2405
+ Return whether this set is finite.
2406
+
2407
+ EXAMPLES::
2408
+
2409
+ sage: E = FiniteEnumeratedSet([1,2,3])
2410
+ sage: C = cartesian_product([E, SymmetricGroup(4)]) # needs sage.groups
2411
+ sage: C.is_finite() # needs sage.groups
2412
+ True
2413
+
2414
+ sage: cartesian_product([ZZ,ZZ]).is_finite()
2415
+ False
2416
+ sage: cartesian_product([ZZ, Set(), ZZ]).is_finite()
2417
+ True
2418
+
2419
+ TESTS:
2420
+
2421
+ This should still work even if some parent does not implement
2422
+ ``is_finite``::
2423
+
2424
+ sage: known_infinite_set = ZZ
2425
+ sage: unknown_infinite_set = Set([1]) + ConditionSet(QQ, lambda x: x > 0)
2426
+ sage: unknown_infinite_set.is_empty()
2427
+ False
2428
+ sage: unknown_infinite_set.is_finite()
2429
+ Traceback (most recent call last):
2430
+ ...
2431
+ AttributeError...
2432
+ sage: cartesian_product([unknown_infinite_set, known_infinite_set]).is_finite()
2433
+ False
2434
+ sage: unknown_empty_set = ConditionSet(QQ, lambda x: False)
2435
+ sage: cartesian_product([known_infinite_set, unknown_empty_set]).is_finite()
2436
+ Traceback (most recent call last):
2437
+ ...
2438
+ NotImplementedError...
2439
+ sage: cartesian_product([unknown_infinite_set, Set([])]).is_finite()
2440
+ True
2441
+ sage: cartesian_product([Set([1, 2, 3]), Set([4, 5])]).is_finite()
2442
+ True
2443
+ sage: cartesian_product([unknown_infinite_set, unknown_infinite_set]).is_finite()
2444
+ Traceback (most recent call last):
2445
+ ...
2446
+ NotImplementedError...
2447
+
2448
+ Coverage test when one factor has emptiness unknown but result is finite::
2449
+
2450
+ sage: s = ConditionSet(RR, lambda x: x^2 == 2, category=Sets().Finite())
2451
+ sage: s.is_finite()
2452
+ True
2453
+ sage: s.is_empty()
2454
+ Traceback (most recent call last):
2455
+ ...
2456
+ AttributeError...
2457
+ sage: cartesian_product([s, Set([1, 2, 3])]).is_finite()
2458
+ True
2459
+ """
2460
+ try:
2461
+ # Note: some parent might not implement "is_empty". So we
2462
+ # carefully isolate this test.
2463
+ if self.is_empty():
2464
+ return True
2465
+ except (AttributeError, NotImplementedError):
2466
+ # it is unknown whether some set may be empty
2467
+ if all(c.is_finite() for c in self.cartesian_factors()):
2468
+ return True
2469
+ raise NotImplementedError
2470
+
2471
+ # in this case, all sets are definitely nonempty
2472
+ last_exception = None
2473
+ for c in self.cartesian_factors():
2474
+ try:
2475
+ if not c.is_finite():
2476
+ return False
2477
+ except (AttributeError, NotImplementedError) as e:
2478
+ last_exception = e
2479
+ if last_exception is not None:
2480
+ raise NotImplementedError from last_exception
2481
+ return True
2482
+
2483
+ def cardinality(self):
2484
+ r"""
2485
+ Return the cardinality of ``self``.
2486
+
2487
+ EXAMPLES::
2488
+
2489
+ sage: E = FiniteEnumeratedSet([1,2,3])
2490
+ sage: C = cartesian_product([E, SymmetricGroup(4)]) # needs sage.groups
2491
+ sage: C.cardinality() # needs sage.groups
2492
+ 72
2493
+
2494
+ sage: E = FiniteEnumeratedSet([])
2495
+ sage: C = cartesian_product([E, ZZ, QQ])
2496
+ sage: C.cardinality()
2497
+ 0
2498
+
2499
+ sage: C = cartesian_product([ZZ, QQ])
2500
+ sage: C.cardinality()
2501
+ +Infinity
2502
+
2503
+ sage: cartesian_product([GF(5), Permutations(10)]).cardinality()
2504
+ 18144000
2505
+ sage: cartesian_product([GF(71)]*20).cardinality() == 71**20
2506
+ True
2507
+ """
2508
+ f = self.cartesian_factors()
2509
+
2510
+ try:
2511
+ # Note: some parent might not implement "is_empty". So we
2512
+ # carefully isolate this test.
2513
+ is_empty = any(c.is_empty() for c in f)
2514
+ except (AttributeError,NotImplementedError):
2515
+ pass
2516
+ else:
2517
+ if is_empty:
2518
+ from sage.rings.integer_ring import ZZ
2519
+ return ZZ.zero()
2520
+ elif any(c in Sets().Infinite() for c in f):
2521
+ from sage.rings.infinity import Infinity
2522
+ return Infinity
2523
+
2524
+ from sage.misc.misc_c import prod
2525
+ return prod(c.cardinality() for c in f)
2526
+
2527
+ def random_element(self, *args):
2528
+ r"""
2529
+ Return a random element of this Cartesian product.
2530
+
2531
+ The extra arguments are passed down to each of the
2532
+ factors of the Cartesian product.
2533
+
2534
+ EXAMPLES::
2535
+
2536
+ sage: C = cartesian_product([Permutations(10)]*5)
2537
+ sage: C.random_element() # random
2538
+ ([2, 9, 4, 7, 1, 8, 6, 10, 5, 3],
2539
+ [8, 6, 5, 7, 1, 4, 9, 3, 10, 2],
2540
+ [5, 10, 3, 8, 2, 9, 1, 4, 7, 6],
2541
+ [9, 6, 10, 3, 2, 1, 5, 8, 7, 4],
2542
+ [8, 5, 2, 9, 10, 3, 7, 1, 4, 6])
2543
+
2544
+ sage: C = cartesian_product([ZZ]*10)
2545
+ sage: c1 = C.random_element()
2546
+ sage: c1 # random
2547
+ (3, 1, 4, 1, 1, -3, 0, -4, -17, 2)
2548
+ sage: c2 = C.random_element(4,7)
2549
+ sage: c2 # random
2550
+ (6, 5, 6, 4, 5, 6, 6, 4, 5, 5)
2551
+ sage: all(4 <= i <= 7 for i in c2)
2552
+ True
2553
+ """
2554
+ return self._cartesian_product_of_elements(
2555
+ c.random_element(*args) for c in self.cartesian_factors())
2556
+
2557
+ @abstract_method
2558
+ def _sets_keys(self):
2559
+ """
2560
+ Return the indices of the Cartesian factors of ``self``.
2561
+
2562
+ EXAMPLES::
2563
+
2564
+ sage: cartesian_product([QQ, ZZ, ZZ])._sets_keys()
2565
+ {0, 1, 2}
2566
+ """
2567
+
2568
+ @abstract_method
2569
+ def cartesian_factors(self):
2570
+ """
2571
+ Return the Cartesian factors of ``self``.
2572
+
2573
+ EXAMPLES::
2574
+
2575
+ sage: cartesian_product([QQ, ZZ, ZZ]).cartesian_factors()
2576
+ (Rational Field, Integer Ring, Integer Ring)
2577
+ """
2578
+
2579
+ @abstract_method
2580
+ def cartesian_projection(self, i):
2581
+ """
2582
+ Return the natural projection onto the `i`-th
2583
+ Cartesian factor of ``self``.
2584
+
2585
+ INPUT:
2586
+
2587
+ - ``i`` -- the index of a Cartesian factor of ``self``
2588
+
2589
+ EXAMPLES::
2590
+
2591
+ sage: C = Sets().CartesianProducts().example(); C
2592
+ The Cartesian product of (Set of prime numbers (basic implementation),
2593
+ An example of an infinite enumerated set: the nonnegative integers,
2594
+ An example of a finite enumerated set: {1,2,3})
2595
+ sage: x = C.an_element(); x
2596
+ (47, 42, 1)
2597
+ sage: pi = C.cartesian_projection(1)
2598
+ sage: pi(x)
2599
+ 42
2600
+ """
2601
+
2602
+ def construction(self):
2603
+ """
2604
+ The construction functor and the list of Cartesian factors.
2605
+
2606
+ EXAMPLES::
2607
+
2608
+ sage: C = cartesian_product([QQ, ZZ, ZZ])
2609
+ sage: C.construction()
2610
+ (The cartesian_product functorial construction,
2611
+ (Rational Field, Integer Ring, Integer Ring))
2612
+ """
2613
+ return cartesian_product, self.cartesian_factors()
2614
+
2615
+ @abstract_method
2616
+ def _cartesian_product_of_elements(self, elements):
2617
+ """
2618
+ Return the Cartesian product of the given ``elements``.
2619
+
2620
+ This method should accept any iterable.
2621
+
2622
+ INPUT:
2623
+
2624
+ - ``elements`` -- an iterable (e.g. a tuple or a list) of
2625
+ elements of each Cartesian factor of ``self``
2626
+
2627
+ EXAMPLES::
2628
+
2629
+ sage: S1 = Sets().example()
2630
+ sage: S2 = InfiniteEnumeratedSets().example()
2631
+ sage: X = [S2, S1, S2]
2632
+ sage: C = cartesian_product(X)
2633
+ sage: C._cartesian_product_of_elements([S.an_element() for S in X])
2634
+ (42, 47, 42)
2635
+ sage: C._cartesian_product_of_elements(S.an_element() for S in X)
2636
+ (42, 47, 42)
2637
+ """
2638
+
2639
+ def _sympy_(self):
2640
+ """
2641
+ Return a SymPy ``ProductSet`` corresponding to ``self``.
2642
+
2643
+ EXAMPLES::
2644
+
2645
+ sage: ZZ3 = cartesian_product([ZZ, ZZ, ZZ])
2646
+ sage: sZZ3 = ZZ3._sympy_(); sZZ3 # needs sympy
2647
+ ProductSet(Integers, Integers, Integers)
2648
+ sage: (1, 2, 3) in sZZ3 # needs sympy
2649
+ True
2650
+ """
2651
+ from sympy import ProductSet
2652
+ from sage.interfaces.sympy import sympy_init
2653
+ sympy_init()
2654
+ return ProductSet(*self.cartesian_factors())
2655
+
2656
+ class ElementMethods:
2657
+
2658
+ def cartesian_projection(self, i):
2659
+ """
2660
+ Return the projection of ``self`` onto the `i`-th
2661
+ factor of the Cartesian product.
2662
+
2663
+ INPUT:
2664
+
2665
+ - ``i`` -- the index of a factor of the Cartesian product
2666
+
2667
+ EXAMPLES::
2668
+
2669
+ sage: # needs sage.modules
2670
+ sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F')
2671
+ sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G')
2672
+ sage: S = cartesian_product([F, G])
2673
+ sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5))
2674
+ ....: + 3 * S.monomial((1,6)))
2675
+ sage: x.cartesian_projection(0)
2676
+ B[4] + 2*B[5]
2677
+ sage: x.cartesian_projection(1)
2678
+ 3*B[6]
2679
+ """
2680
+ return self.parent().cartesian_projection(i)(self)
2681
+
2682
+ def cartesian_factors(self):
2683
+ """
2684
+ Return the Cartesian factors of ``self``.
2685
+
2686
+ EXAMPLES::
2687
+
2688
+ sage: # needs sage.modules
2689
+ sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename('F')
2690
+ sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename('G')
2691
+ sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename('H')
2692
+ sage: S = cartesian_product([F, G, H])
2693
+ sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5))
2694
+ ....: + 3 * S.monomial((1,6)) + 4 * S.monomial((2,4))
2695
+ ....: + 5 * S.monomial((2,7)))
2696
+ sage: x.cartesian_factors()
2697
+ (B[4] + 2*B[5], 3*B[6], 4*B[4] + 5*B[7])
2698
+ sage: [s.parent() for s in x.cartesian_factors()]
2699
+ [F, G, H]
2700
+ sage: S.zero().cartesian_factors()
2701
+ (0, 0, 0)
2702
+ sage: [s.parent() for s in S.zero().cartesian_factors()]
2703
+ [F, G, H]
2704
+ """
2705
+ # TODO: optimize
2706
+ return tuple(self.cartesian_projection(i)
2707
+ for i in self.parent()._sets_keys())
2708
+ #return Family(self._sets.keys(), self.projection)
2709
+
2710
+ class Algebras(AlgebrasCategory):
2711
+
2712
+ def extra_super_categories(self):
2713
+ """
2714
+ EXAMPLES::
2715
+
2716
+ sage: Sets().Algebras(ZZ).super_categories()
2717
+ [Category of modules with basis over Integer Ring]
2718
+
2719
+ sage: Sets().Algebras(QQ).extra_super_categories()
2720
+ [Category of vector spaces with basis over Rational Field]
2721
+
2722
+ sage: Sets().example().algebra(ZZ).categories() # needs sage.modules
2723
+ [Category of set algebras over Integer Ring,
2724
+ Category of modules with basis over Integer Ring,
2725
+ ...
2726
+ Category of objects]
2727
+ """
2728
+ from sage.categories.modules_with_basis import ModulesWithBasis
2729
+ return [ModulesWithBasis(self.base_ring())]
2730
+
2731
+ class ParentMethods:
2732
+ def construction(self):
2733
+ r"""
2734
+ Return the functorial construction of ``self``.
2735
+
2736
+ EXAMPLES::
2737
+
2738
+ sage: A = GroupAlgebra(KleinFourGroup(), QQ) # needs sage.groups sage.modules
2739
+ sage: F, arg = A.construction(); F, arg # needs sage.groups sage.modules
2740
+ (GroupAlgebraFunctor, Rational Field)
2741
+ sage: F(arg) is A # needs sage.groups sage.modules
2742
+ True
2743
+
2744
+ This also works for structures such as monoid algebras (see
2745
+ :issue:`27937`)::
2746
+
2747
+ sage: A = FreeAbelianMonoid('x,y').algebra(QQ) # needs sage.combinat sage.modules
2748
+ sage: F, arg = A.construction(); F, arg # needs sage.combinat sage.modules
2749
+ (The algebra functorial construction,
2750
+ Free abelian monoid on 2 generators (x, y))
2751
+ sage: F(arg) is A # needs sage.combinat sage.modules
2752
+ True
2753
+ """
2754
+ from sage.categories.algebra_functor import (
2755
+ GroupAlgebraFunctor, AlgebraFunctor)
2756
+ try:
2757
+ group = self.group()
2758
+ except AttributeError:
2759
+ return (AlgebraFunctor(self.base_ring()),
2760
+ self.basis().keys())
2761
+ return GroupAlgebraFunctor(group), self.base_ring()
2762
+
2763
+ def _repr_(self):
2764
+ r"""
2765
+ Return the string representation of ``self``.
2766
+
2767
+ EXAMPLES::
2768
+
2769
+ sage: # needs sage.groups sage.modules
2770
+ sage: A = Groups().example().algebra(QQ); A
2771
+ Algebra of General Linear Group of degree 4 over Rational Field
2772
+ over Rational Field
2773
+ sage: A._name = "foo"
2774
+ sage: A
2775
+ foo over Rational Field
2776
+ sage: A = KleinFourGroup().algebra(ZZ)
2777
+ sage: A
2778
+ Algebra of The Klein 4 group of order 4, as a permutation group
2779
+ over Integer Ring
2780
+ """
2781
+ if hasattr(self, "_name"):
2782
+ return self._name + " over {}".format(self.base_ring())
2783
+ else:
2784
+ return 'Algebra of {} over {}'.format(self.basis().keys(),
2785
+ self.base_ring())
2786
+
2787
+ class WithRealizations(WithRealizationsCategory):
2788
+
2789
+ def extra_super_categories(self):
2790
+ """
2791
+ A set with multiple realizations is a facade parent.
2792
+
2793
+ EXAMPLES::
2794
+
2795
+ sage: Sets().WithRealizations().extra_super_categories()
2796
+ [Category of facade sets]
2797
+ sage: Sets().WithRealizations().super_categories()
2798
+ [Category of facade sets]
2799
+ """
2800
+ return [Sets().Facade()]
2801
+
2802
+ def example(self, base_ring=None, set=None):
2803
+ r"""
2804
+ Return an example of set with multiple realizations, as
2805
+ per :meth:`Category.example`.
2806
+
2807
+ EXAMPLES::
2808
+
2809
+ sage: Sets().WithRealizations().example() # needs sage.modules
2810
+ The subset algebra of {1, 2, 3} over Rational Field
2811
+
2812
+ sage: Sets().WithRealizations().example(ZZ, Set([1,2])) # needs sage.modules
2813
+ The subset algebra of {1, 2} over Integer Ring
2814
+ """
2815
+ from sage.rings.rational_field import QQ
2816
+ from sage.sets.set import Set
2817
+ if base_ring is None:
2818
+ base_ring = QQ
2819
+ if set is None:
2820
+ set = Set([1,2,3])
2821
+ from sage.categories.examples.with_realizations import SubsetAlgebra
2822
+ return SubsetAlgebra(base_ring, set)
2823
+
2824
+ class ParentMethods:
2825
+
2826
+ def _test_with_realizations(self, **options):
2827
+ r"""
2828
+ Test that this parent with realizations is
2829
+ properly implemented.
2830
+
2831
+ INPUT:
2832
+
2833
+ - ``options`` -- any keyword arguments accepted
2834
+ by :meth:`_tester`
2835
+
2836
+ EXAMPLES::
2837
+
2838
+ sage: A = Sets().WithRealizations().example() # needs sage.modules
2839
+ sage: A._test_with_realizations() # needs sage.modules
2840
+
2841
+ See the documentation for :class:`TestSuite`
2842
+ for more information.
2843
+ """
2844
+ tester = self._tester(**options)
2845
+ for R in self.realizations():
2846
+ tester.assertIn(R, self.Realizations())
2847
+ # Could check that there are coerce maps between any two realizations
2848
+
2849
+ @lazy_attribute
2850
+ def _realizations(self):
2851
+ """
2852
+ This lazily initializes the attribute
2853
+ ``_realizations`` the first time it is needed.
2854
+
2855
+ TESTS::
2856
+
2857
+ sage: class MyParent(Parent):
2858
+ ....: pass
2859
+ sage: P = MyParent(category = Sets().WithRealizations())
2860
+ sage: P._realizations
2861
+ []
2862
+ """
2863
+ return []
2864
+
2865
+ def _register_realization(self, realization):
2866
+ """
2867
+ EXAMPLES::
2868
+
2869
+ sage: # needs sage.combinat sage.modules
2870
+ sage: A = Sets().WithRealizations().example(QQ['x']); A
2871
+ The subset algebra of {1, 2, 3}
2872
+ over Univariate Polynomial Ring in x over Rational Field
2873
+ sage: class ANewRealizationOfA(CombinatorialFreeModule):
2874
+ ....: pass
2875
+ sage: category = A.Realizations() & Algebras(QQ['x']).WithBasis()
2876
+ sage: R = ANewRealizationOfA(A.base_ring(), A.F().basis().keys(),
2877
+ ....: category=category)
2878
+ sage: R in A.realizations() # indirect doctest
2879
+ True
2880
+
2881
+ Note: the test above uses ``QQ[x]`` to not interfere
2882
+ with other tests.
2883
+ """
2884
+ assert realization.realization_of() is self
2885
+ self._realizations.append(realization)
2886
+
2887
+ def inject_shorthands(self, shorthands=None, verbose=True):
2888
+ """
2889
+ Import standard shorthands into the global namespace.
2890
+
2891
+ INPUT:
2892
+
2893
+ - ``shorthands`` -- list (or iterable) of strings
2894
+ (default: ``self._shorthands``)
2895
+ or ``'all'`` (for ``self._shorthands_all``)
2896
+ - ``verbose`` -- boolean (default: ``True``);
2897
+ whether to print the defined shorthands
2898
+
2899
+ EXAMPLES:
2900
+
2901
+ When computing with a set with multiple realizations,
2902
+ like :class:`SymmetricFunctions` or
2903
+ :class:`~sage.categories.examples.with_realizations.SubsetAlgebra`,
2904
+ it is convenient to define shorthands for the various
2905
+ realizations, but cumbersome to do it by hand::
2906
+
2907
+ sage: S = SymmetricFunctions(ZZ); S # needs sage.combinat sage.modules
2908
+ Symmetric Functions over Integer Ring
2909
+ sage: s = S.s(); s # needs sage.combinat sage.modules
2910
+ Symmetric Functions over Integer Ring in the Schur basis
2911
+ sage: e = S.e(); e # needs sage.combinat sage.modules
2912
+ Symmetric Functions over Integer Ring in the elementary basis
2913
+
2914
+ This method automates the process::
2915
+
2916
+ sage: # needs sage.combinat sage.modules
2917
+ sage: S.inject_shorthands()
2918
+ Defining e as shorthand for
2919
+ Symmetric Functions over Integer Ring in the elementary basis
2920
+ Defining f as shorthand for
2921
+ Symmetric Functions over Integer Ring in the forgotten basis
2922
+ Defining h as shorthand for
2923
+ Symmetric Functions over Integer Ring in the homogeneous basis
2924
+ Defining m as shorthand for
2925
+ Symmetric Functions over Integer Ring in the monomial basis
2926
+ Defining p as shorthand for
2927
+ Symmetric Functions over Integer Ring in the powersum basis
2928
+ Defining s as shorthand for
2929
+ Symmetric Functions over Integer Ring in the Schur basis
2930
+ sage: s[1] + e[2] * p[1,1] + 2*h[3] + m[2,1]
2931
+ s[1] - 2*s[1, 1, 1] + s[1, 1, 1, 1] + s[2, 1]
2932
+ + 2*s[2, 1, 1] + s[2, 2] + 2*s[3] + s[3, 1]
2933
+ sage: e
2934
+ Symmetric Functions over Integer Ring in the elementary basis
2935
+ sage: p
2936
+ Symmetric Functions over Integer Ring in the powersum basis
2937
+ sage: s
2938
+ Symmetric Functions over Integer Ring in the Schur basis
2939
+
2940
+ Sometimes, like for symmetric functions, one can
2941
+ request for all shorthands to be defined, including
2942
+ less common ones::
2943
+
2944
+ sage: S.inject_shorthands("all") # needs lrcalc_python sage.combinat sage.modules
2945
+ Defining e as shorthand for
2946
+ Symmetric Functions over Integer Ring in the elementary basis
2947
+ Defining f as shorthand for
2948
+ Symmetric Functions over Integer Ring in the forgotten basis
2949
+ Defining h as shorthand for
2950
+ Symmetric Functions over Integer Ring in the homogeneous basis
2951
+ Defining ht as shorthand for
2952
+ Symmetric Functions over Integer Ring in the
2953
+ induced trivial symmetric group character basis
2954
+ Defining m as shorthand for
2955
+ Symmetric Functions over Integer Ring in the monomial basis
2956
+ Defining o as shorthand for
2957
+ Symmetric Functions over Integer Ring in the orthogonal basis
2958
+ Defining p as shorthand for
2959
+ Symmetric Functions over Integer Ring in the powersum basis
2960
+ Defining s as shorthand for
2961
+ Symmetric Functions over Integer Ring in the Schur basis
2962
+ Defining sp as shorthand for
2963
+ Symmetric Functions over Integer Ring in the symplectic basis
2964
+ Defining st as shorthand for
2965
+ Symmetric Functions over Integer Ring in the
2966
+ irreducible symmetric group character basis
2967
+ Defining w as shorthand for
2968
+ Symmetric Functions over Integer Ring in the Witt basis
2969
+
2970
+ The messages can be silenced by setting ``verbose=False``::
2971
+
2972
+ sage: # needs sage.combinat sage.modules
2973
+ sage: Q = QuasiSymmetricFunctions(ZZ)
2974
+ sage: Q.inject_shorthands(verbose=False)
2975
+ sage: F[1,2,1] + 5*M[1,3] + F[2]^2
2976
+ 5*F[1, 1, 1, 1] - 5*F[1, 1, 2] - 3*F[1, 2, 1] + 6*F[1, 3] +
2977
+ 2*F[2, 2] + F[3, 1] + F[4]
2978
+ sage: F
2979
+ Quasisymmetric functions over the Integer Ring in the
2980
+ Fundamental basis
2981
+ sage: M
2982
+ Quasisymmetric functions over the Integer Ring in the
2983
+ Monomial basis
2984
+
2985
+ One can also just import a subset of the shorthands::
2986
+
2987
+ sage: # needs sage.combinat sage.modules
2988
+ sage: SQ = SymmetricFunctions(QQ)
2989
+ sage: SQ.inject_shorthands(['p', 's'], verbose=False)
2990
+ sage: p
2991
+ Symmetric Functions over Rational Field in the powersum basis
2992
+ sage: s
2993
+ Symmetric Functions over Rational Field in the Schur basis
2994
+
2995
+ Note that ``e`` is left unchanged::
2996
+
2997
+ sage: e # needs sage.combinat sage.modules
2998
+ Symmetric Functions over Integer Ring in the elementary basis
2999
+
3000
+ TESTS::
3001
+
3002
+ sage: e == S.e(), h == S.h(), m == S.m(), p == SQ.p(), s == SQ.s() # needs sage.combinat sage.modules
3003
+ (True, True, True, True, True)
3004
+ """
3005
+ from sage.misc.misc import inject_variable
3006
+ if shorthands == 'all':
3007
+ shorthands = getattr(self, '_shorthands_all', None)
3008
+ if shorthands is None:
3009
+ shorthands = getattr(self, '_shorthands', None)
3010
+ if shorthands is None:
3011
+ raise NotImplementedError("no shorthands defined for {}".format(self))
3012
+ for shorthand in shorthands:
3013
+ realization = getattr(self, shorthand)()
3014
+ if verbose:
3015
+ print('Defining {} as shorthand for {}'.format(shorthand, realization))
3016
+ inject_variable(shorthand, realization, warn=False)
3017
+
3018
+ @abstract_method(optional=True)
3019
+ def a_realization(self):
3020
+ """
3021
+ Return a realization of ``self``.
3022
+
3023
+ EXAMPLES::
3024
+
3025
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3026
+ The subset algebra of {1, 2, 3} over Rational Field
3027
+ sage: A.a_realization() # needs sage.modules
3028
+ The subset algebra of {1, 2, 3} over Rational Field
3029
+ in the Fundamental basis
3030
+ """
3031
+
3032
+ def realizations(self):
3033
+ """
3034
+ Return all the realizations of ``self`` that ``self``
3035
+ is aware of.
3036
+
3037
+ EXAMPLES::
3038
+
3039
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3040
+ The subset algebra of {1, 2, 3} over Rational Field
3041
+ sage: A.realizations() # needs sage.modules
3042
+ [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis,
3043
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis,
3044
+ The subset algebra of {1, 2, 3} over Rational Field in the Out basis]
3045
+
3046
+ .. NOTE::
3047
+
3048
+ Constructing a parent ``P`` in the category
3049
+ ``A.Realizations()`` automatically adds ``P`` to
3050
+ this list by calling ``A._register_realization(A)``
3051
+ """
3052
+ return self._realizations
3053
+
3054
+ def facade_for(self):
3055
+ """
3056
+ Return the parents ``self`` is a facade for, that is
3057
+ the realizations of ``self``
3058
+
3059
+ EXAMPLES::
3060
+
3061
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3062
+ The subset algebra of {1, 2, 3} over Rational Field
3063
+ sage: A.facade_for() # needs sage.modules
3064
+ [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis,
3065
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis,
3066
+ The subset algebra of {1, 2, 3} over Rational Field in the Out basis]
3067
+
3068
+ sage: # needs sage.combinat sage.modules
3069
+ sage: A = Sets().WithRealizations().example(); A
3070
+ The subset algebra of {1, 2, 3} over Rational Field
3071
+ sage: f = A.F().an_element(); f
3072
+ F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}]
3073
+ sage: i = A.In().an_element(); i
3074
+ In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}]
3075
+ sage: o = A.Out().an_element(); o
3076
+ Out[{}] + 2*Out[{1}] + 3*Out[{2}] + Out[{1, 2}]
3077
+ sage: f in A, i in A, o in A
3078
+ (True, True, True)
3079
+ """
3080
+ return self.realizations()
3081
+
3082
+ # Do we really want this feature?
3083
+ class Realizations(Category_realization_of_parent):
3084
+
3085
+ def super_categories(self):
3086
+ """
3087
+ EXAMPLES::
3088
+
3089
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3090
+ The subset algebra of {1, 2, 3} over Rational Field
3091
+ sage: A.Realizations().super_categories() # needs sage.modules
3092
+ [Category of realizations of sets]
3093
+ """
3094
+ return [Sets().Realizations()]
3095
+
3096
+ def _an_element_(self):
3097
+ """
3098
+ Return an element of some realization of ``self``.
3099
+
3100
+ EXAMPLES::
3101
+
3102
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3103
+ The subset algebra of {1, 2, 3} over Rational Field
3104
+ sage: A.an_element() # indirect doctest # needs sage.modules
3105
+ F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}]
3106
+
3107
+ TESTS:
3108
+
3109
+ Check that we are consistent no matter which basis is
3110
+ created first::
3111
+
3112
+ sage: M = posets.BooleanLattice(4).moebius_algebra(QQ) # needs sage.graphs sage.modules
3113
+ sage: I = M.I() # needs sage.graphs sage.modules
3114
+ sage: M._an_element_() # needs sage.graphs sage.modules
3115
+ 2*E[0] + 2*E[1] + 3*E[2]
3116
+ """
3117
+ return self.a_realization().an_element()
3118
+
3119
+ # TODO: maybe this could be taken care of by Sets.Facade()?
3120
+ def __contains__(self, x):
3121
+ r"""
3122
+ Test whether ``x`` is in ``self``, that is if it is an
3123
+ element of some realization of ``self``.
3124
+
3125
+ EXAMPLES::
3126
+
3127
+ sage: # needs sage.combinat sage.modules
3128
+ sage: A = Sets().WithRealizations().example(); A
3129
+ The subset algebra of {1, 2, 3} over Rational Field
3130
+ sage: A.an_element() in A
3131
+ True
3132
+ sage: A.In().an_element() in A
3133
+ True
3134
+ sage: A.F().an_element() in A
3135
+ True
3136
+ sage: A.Out().an_element() in A
3137
+ True
3138
+ sage: 1 in A
3139
+ True
3140
+ sage: QQ['x'].an_element() in A
3141
+ False
3142
+ """
3143
+ return any(x in realization for realization in self.realizations())
3144
+
3145
+ class Realizations(RealizationsCategory):
3146
+
3147
+ class ParentMethods:
3148
+
3149
+ def __init_extra__(self):
3150
+ """
3151
+ Register ``self`` as a realization of ``self.realization_of``.
3152
+
3153
+ TESTS::
3154
+
3155
+ sage: A = Sets().WithRealizations().example() # needs sage.modules
3156
+ sage: A.realizations() # indirect doctest # needs sage.modules
3157
+ [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis,
3158
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis,
3159
+ The subset algebra of {1, 2, 3} over Rational Field in the Out basis]
3160
+ """
3161
+ self.realization_of()._register_realization(self)
3162
+
3163
+ @cached_method
3164
+ def realization_of(self):
3165
+ """
3166
+ Return the parent this is a realization of.
3167
+
3168
+ EXAMPLES::
3169
+
3170
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3171
+ The subset algebra of {1, 2, 3} over Rational Field
3172
+ sage: In = A.In(); In # needs sage.modules
3173
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis
3174
+ sage: In.realization_of() # needs sage.modules
3175
+ The subset algebra of {1, 2, 3} over Rational Field
3176
+ """
3177
+ for category in self.categories():
3178
+ if isinstance(category, Category_realization_of_parent):
3179
+ return category.base()
3180
+
3181
+ def _realization_name(self):
3182
+ """
3183
+ Return the name of this realization.
3184
+
3185
+ In this default implementation, this is guessed from
3186
+ the name of its class.
3187
+
3188
+ EXAMPLES::
3189
+
3190
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3191
+ The subset algebra of {1, 2, 3} over Rational Field
3192
+ sage: In = A.In(); In # needs sage.modules
3193
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis
3194
+ sage: In._realization_name() # needs sage.modules
3195
+ 'In'
3196
+ """
3197
+ # The __base__ gets rid of the with_category
3198
+ # The split adds support for nested classes
3199
+ return self.__class__.__base__.__name__.split('.')[-1]
3200
+
3201
+ def _repr_(self):
3202
+ """
3203
+ EXAMPLES::
3204
+
3205
+ sage: A = Sets().WithRealizations().example(); A # needs sage.modules
3206
+ The subset algebra of {1, 2, 3} over Rational Field
3207
+ sage: In = A.In(); In # needs sage.modules
3208
+ The subset algebra of {1, 2, 3} over Rational Field in the In basis
3209
+
3210
+ In the example above, :meth:`repr` was overridden by
3211
+ the category ``A.Realizations()``. We now add a new
3212
+ (fake) realization which is not in
3213
+ ``A.Realizations()`` to actually exercise this
3214
+ method::
3215
+
3216
+ sage: from sage.categories.realizations import Realizations
3217
+ sage: class Blah(Parent):
3218
+ ....: pass
3219
+ sage: C = Sets.WithRealizations.ParentMethods.Realizations(A) # needs sage.modules
3220
+ sage: P = Blah(category=C) # needs sage.modules
3221
+ sage: P # indirect doctest # needs sage.modules
3222
+ The subset algebra of {1, 2, 3} over Rational Field in the realization Blah
3223
+ """
3224
+ return "{} in the realization {}".format(self.realization_of(), self._realization_name())
3225
+
3226
+
3227
+ # Moved from sage.categories.cartesian_product to avoid circular import errors
3228
+ cartesian_product = CartesianProductFunctor()