passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.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 (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
sage/sets/family.pyx ADDED
@@ -0,0 +1,1556 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Families
4
+
5
+ A Family is an associative container which models a family
6
+ `(f_i)_{i \in I}`. Then, ``f[i]`` returns the element of the family indexed by
7
+ ``i``. Whenever available, set and combinatorial class operations (counting,
8
+ iteration, listing) on the family are induced from those of the index
9
+ set. Families should be created through the :func:`Family` function.
10
+
11
+ AUTHORS:
12
+
13
+ - Nicolas Thiery (2008-02): initial release
14
+
15
+ - Florent Hivert (2008-04): various fixes, cleanups and improvements.
16
+
17
+ TESTS:
18
+
19
+ Check :issue:`12482` (shall be run in a fresh session)::
20
+
21
+ sage: P = Partitions(3)
22
+ sage: Family(P, lambda x: x).category()
23
+ Category of finite enumerated sets
24
+ """
25
+
26
+ # *****************************************************************************
27
+ # Copyright (C) 2008-2017 Nicolas Thiery <nthiery at users.sf.net>
28
+ # 2008-2009 Mike Hansen <mhansen@gmail.com>
29
+ # 2008-2010 Florent Hivert <Florent.Hivert@univ-rouen.fr>
30
+ # 2013-2021 Travis Scrimshaw
31
+ # 2014 Nathann Cohen
32
+ # 2017 Erik M. Bray
33
+ # 2018 Frédéric Chapoton
34
+ # 2019 Markus Wageringel
35
+ # 2022-2023 Matthias Koeppe
36
+ #
37
+ # This program is free software: you can redistribute it and/or modify
38
+ # it under the terms of the GNU General Public License as published by
39
+ # the Free Software Foundation, either version 2 of the License, or
40
+ # (at your option) any later version.
41
+ # https://www.gnu.org/licenses/
42
+ # ****************************************************************************
43
+ import types
44
+ from copy import copy
45
+ from pprint import pformat, saferepr
46
+ from collections.abc import Iterable
47
+
48
+ from sage.categories.enumerated_sets import EnumeratedSets
49
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
50
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
51
+ from sage.misc.cachefunc import cached_method
52
+ from sage.misc.call import AttrCallObject
53
+ from sage.rings.infinity import Infinity
54
+ from sage.rings.integer import Integer
55
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
56
+ from sage.sets.non_negative_integers import NonNegativeIntegers
57
+
58
+
59
+ def Family(indices, function=None, hidden_keys=[], hidden_function=None, lazy=False, name=None):
60
+ r"""
61
+ A Family is an associative container which models a family
62
+ `(f_i)_{i \in I}`. Then, ``f[i]`` returns the element of the family
63
+ indexed by `i`. Whenever available, set and combinatorial class
64
+ operations (counting, iteration, listing) on the family are induced
65
+ from those of the index set.
66
+
67
+ There are several available implementations (classes) for different
68
+ usages; Family serves as a factory, and will create instances of
69
+ the appropriate classes depending on its arguments.
70
+
71
+ INPUT:
72
+
73
+ - ``indices`` -- the indices for the family
74
+ - ``function`` -- (optional) the function `f` applied to all visible
75
+ indices; the default is the identity function
76
+ - ``hidden_keys`` -- (optional) a list of hidden indices that can be
77
+ accessed through ``my_family[i]``
78
+ - ``hidden_function`` -- (optional) a function for the hidden indices
79
+ - ``lazy`` -- boolean (default: ``False``); whether the family is lazily
80
+ created or not; if the indices are infinite, then this is automatically
81
+ made ``True``
82
+ - ``name`` -- (optional) the name of the function; only used when the
83
+ family is lazily created via a function
84
+
85
+ EXAMPLES:
86
+
87
+ In its simplest form, a list `l = [l_0, l_1, \ldots, l_{\ell}]` or a
88
+ tuple by itself is considered as the family `(l_i)_{i \in I}` where
89
+ `I` is the set `\{0, \ldots, \ell\}` where `\ell` is ``len(l) - 1``.
90
+ So ``Family(l)`` returns the corresponding family::
91
+
92
+ sage: f = Family([1,2,3])
93
+ sage: f
94
+ Family (1, 2, 3)
95
+ sage: f = Family((1,2,3))
96
+ sage: f
97
+ Family (1, 2, 3)
98
+
99
+ Instead of a list you can as well pass any iterable object::
100
+
101
+ sage: f = Family(2*i+1 for i in [1,2,3])
102
+ sage: f
103
+ Family (3, 5, 7)
104
+
105
+ A family can also be constructed from a dictionary ``t``. The resulting
106
+ family is very close to ``t``, except that the elements of the family
107
+ are the values of ``t``. Here, we define the family
108
+ `(f_i)_{i \in \{3,4,7\}}` with `f_3 = a`, `f_4 = b`, and `f_7 = d`::
109
+
110
+ sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
111
+ sage: f
112
+ Finite family {3: 'a', 4: 'b', 7: 'd'}
113
+ sage: f[7]
114
+ 'd'
115
+ sage: len(f)
116
+ 3
117
+ sage: list(f)
118
+ ['a', 'b', 'd']
119
+ sage: [ x for x in f ]
120
+ ['a', 'b', 'd']
121
+ sage: f.keys()
122
+ [3, 4, 7]
123
+ sage: 'b' in f
124
+ True
125
+ sage: 'e' in f
126
+ False
127
+
128
+ A family can also be constructed by its index set `I` and
129
+ a function `f`, as in `(f(i))_{i \in I}`::
130
+
131
+ sage: f = Family([3,4,7], lambda i: 2*i)
132
+ sage: f
133
+ Finite family {3: 6, 4: 8, 7: 14}
134
+ sage: f.keys()
135
+ [3, 4, 7]
136
+ sage: f[7]
137
+ 14
138
+ sage: list(f)
139
+ [6, 8, 14]
140
+ sage: [x for x in f]
141
+ [6, 8, 14]
142
+ sage: len(f)
143
+ 3
144
+
145
+ By default, all images are computed right away, and stored in an internal
146
+ dictionary::
147
+
148
+ sage: f = Family((3,4,7), lambda i: 2*i)
149
+ sage: f
150
+ Finite family {3: 6, 4: 8, 7: 14}
151
+
152
+ Note that this requires all the elements of the list to be
153
+ hashable. One can ask instead for the images `f(i)` to be computed
154
+ lazily, when needed::
155
+
156
+ sage: f = Family([3,4,7], lambda i: 2*i, lazy=True)
157
+ sage: f
158
+ Lazy family (<lambda>(i))_{i in [3, 4, 7]}
159
+ sage: f[7]
160
+ 14
161
+ sage: list(f)
162
+ [6, 8, 14]
163
+ sage: [x for x in f]
164
+ [6, 8, 14]
165
+
166
+ This allows in particular for modeling infinite families::
167
+
168
+ sage: f = Family(ZZ, lambda i: 2*i, lazy=True)
169
+ sage: f
170
+ Lazy family (<lambda>(i))_{i in Integer Ring}
171
+ sage: f.keys()
172
+ Integer Ring
173
+ sage: f[1]
174
+ 2
175
+ sage: f[-5]
176
+ -10
177
+ sage: i = iter(f)
178
+ sage: next(i), next(i), next(i), next(i), next(i)
179
+ (0, 2, -2, 4, -4)
180
+
181
+ Note that the ``lazy`` keyword parameter is only needed to force
182
+ laziness. Usually it is automatically set to a correct default value (ie:
183
+ ``False`` for finite data structures and ``True`` for enumerated sets::
184
+
185
+ sage: f == Family(ZZ, lambda i: 2*i)
186
+ True
187
+
188
+ Beware that for those kind of families len(f) is not supposed to
189
+ work. As a replacement, use the .cardinality() method::
190
+
191
+ sage: f = Family(Permutations(3), attrcall("to_lehmer_code"))
192
+ sage: list(f)
193
+ [[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [2, 0, 0], [2, 1, 0]]
194
+ sage: f.cardinality()
195
+ 6
196
+
197
+ Caveat: Only certain families with lazy behavior can be pickled. In
198
+ particular, only functions that work with Sage's pickle_function
199
+ and unpickle_function (in sage.misc.fpickle) will correctly
200
+ unpickle. The following two work::
201
+
202
+ sage: f = Family(Permutations(3), lambda p: p.to_lehmer_code()); f
203
+ Lazy family (<lambda>(i))_{i in Standard permutations of 3}
204
+ sage: f == loads(dumps(f))
205
+ True
206
+
207
+ sage: f = Family(Permutations(3), attrcall("to_lehmer_code")); f
208
+ Lazy family (i.to_lehmer_code())_{i in Standard permutations of 3}
209
+ sage: f == loads(dumps(f))
210
+ True
211
+
212
+ But this one does not::
213
+
214
+ sage: def plus_n(n): return lambda x: x+n
215
+ sage: f = Family([1,2,3], plus_n(3), lazy=True); f
216
+ Lazy family (<lambda>(i))_{i in [1, 2, 3]}
217
+ sage: f == loads(dumps(f))
218
+ Traceback (most recent call last):
219
+ ...
220
+ ValueError: Cannot pickle code objects from closures
221
+
222
+ Finally, it can occasionally be useful to add some hidden elements
223
+ in a family, which are accessible as ``f[i]``, but do not appear in the
224
+ keys or the container operations::
225
+
226
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
227
+ sage: f
228
+ Finite family {3: 6, 4: 8, 7: 14}
229
+ sage: f.keys()
230
+ [3, 4, 7]
231
+ sage: f.hidden_keys()
232
+ [2]
233
+ sage: f[7]
234
+ 14
235
+ sage: f[2]
236
+ 4
237
+ sage: list(f)
238
+ [6, 8, 14]
239
+ sage: [x for x in f]
240
+ [6, 8, 14]
241
+ sage: len(f)
242
+ 3
243
+
244
+ The following example illustrates when the function is actually
245
+ called::
246
+
247
+ sage: def compute_value(i):
248
+ ....: print('computing 2*'+str(i))
249
+ ....: return 2*i
250
+ sage: f = Family([3,4,7], compute_value, hidden_keys=[2])
251
+ computing 2*3
252
+ computing 2*4
253
+ computing 2*7
254
+ sage: f
255
+ Finite family {3: 6, 4: 8, 7: 14}
256
+ sage: f.keys()
257
+ [3, 4, 7]
258
+ sage: f.hidden_keys()
259
+ [2]
260
+ sage: f[7]
261
+ 14
262
+ sage: f[2]
263
+ computing 2*2
264
+ 4
265
+ sage: f[2]
266
+ 4
267
+ sage: list(f)
268
+ [6, 8, 14]
269
+ sage: [x for x in f]
270
+ [6, 8, 14]
271
+ sage: len(f)
272
+ 3
273
+
274
+ Here is a close variant where the function for the hidden keys is
275
+ different from that for the other keys::
276
+
277
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2], hidden_function = lambda i: 3*i)
278
+ sage: f
279
+ Finite family {3: 6, 4: 8, 7: 14}
280
+ sage: f.keys()
281
+ [3, 4, 7]
282
+ sage: f.hidden_keys()
283
+ [2]
284
+ sage: f[7]
285
+ 14
286
+ sage: f[2]
287
+ 6
288
+ sage: list(f)
289
+ [6, 8, 14]
290
+ sage: [x for x in f]
291
+ [6, 8, 14]
292
+ sage: len(f)
293
+ 3
294
+
295
+ Family accept finite and infinite EnumeratedSets as input::
296
+
297
+ sage: f = Family(FiniteEnumeratedSet([1,2,3]))
298
+ sage: f
299
+ Family (1, 2, 3)
300
+ sage: f = Family(NonNegativeIntegers())
301
+ sage: f
302
+ Family (Non negative integers)
303
+
304
+ ::
305
+
306
+ sage: f = Family(FiniteEnumeratedSet([3,4,7]), lambda i: 2*i)
307
+ sage: f
308
+ Finite family {3: 6, 4: 8, 7: 14}
309
+ sage: f.keys()
310
+ {3, 4, 7}
311
+ sage: f[7]
312
+ 14
313
+ sage: list(f)
314
+ [6, 8, 14]
315
+ sage: [x for x in f]
316
+ [6, 8, 14]
317
+ sage: len(f)
318
+ 3
319
+
320
+ TESTS::
321
+
322
+ sage: f = Family({1:'a', 2:'b', 3:'c'})
323
+ sage: f
324
+ Finite family {1: 'a', 2: 'b', 3: 'c'}
325
+ sage: f[2]
326
+ 'b'
327
+ sage: loads(dumps(f)) == f
328
+ True
329
+
330
+ ::
331
+
332
+ sage: f = Family({1:'a', 2:'b', 3:'c'}, lazy=True)
333
+ Traceback (most recent call last):
334
+ ...
335
+ ValueError: lazy keyword only makes sense together with function keyword
336
+
337
+ ::
338
+
339
+ sage: f = Family(list(range(1,27)), lambda i: chr(i+96))
340
+ sage: f
341
+ Finite family {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g',
342
+ 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o',
343
+ 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w',
344
+ 24: 'x', 25: 'y', 26: 'z'}
345
+ sage: f[2]
346
+ 'b'
347
+
348
+ The factory ``Family`` is supposed to be idempotent. We test this feature here::
349
+
350
+ sage: from sage.sets.family import FiniteFamily, LazyFamily, TrivialFamily
351
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
352
+ sage: g = Family(f)
353
+ sage: f == g
354
+ True
355
+
356
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
357
+ sage: g = Family(f)
358
+ sage: f == g
359
+ True
360
+
361
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
362
+ sage: g = Family(f)
363
+ sage: f == g
364
+ True
365
+
366
+ sage: f = TrivialFamily([3,4,7])
367
+ sage: g = Family(f)
368
+ sage: f == g
369
+ True
370
+
371
+ A family should keep the order of the keys::
372
+
373
+ sage: f = Family(["c", "a", "b"], lambda i: 2*i)
374
+ sage: list(f)
375
+ ['cc', 'aa', 'bb']
376
+
377
+ Even with hidden keys (see :issue:`22955`)::
378
+
379
+ sage: f = Family(["c", "a", "b"], lambda i: 2*i,
380
+ ....: hidden_keys=[5], hidden_function=lambda i: i%2)
381
+ sage: list(f)
382
+ ['cc', 'aa', 'bb']
383
+
384
+ Only the hidden function is applied to the hidden keys::
385
+
386
+ sage: f[5]
387
+ 1
388
+ """
389
+ assert isinstance(hidden_keys, list)
390
+ assert isinstance(lazy, bool)
391
+
392
+ if not hidden_keys:
393
+ if hidden_function is not None:
394
+ raise ValueError("hidden_function keyword only makes sense "
395
+ "together with hidden_keys keyword !")
396
+ if function is None:
397
+ if lazy:
398
+ raise ValueError("lazy keyword only makes sense together with function keyword")
399
+ if isinstance(indices, dict):
400
+ return FiniteFamily(indices)
401
+ if isinstance(indices, (list, tuple)):
402
+ return TrivialFamily(indices)
403
+ if isinstance(indices, (FiniteFamily, LazyFamily, TrivialFamily)):
404
+ return indices
405
+ if indices in EnumeratedSets():
406
+ return EnumeratedFamily(indices)
407
+ if isinstance(indices, Iterable):
408
+ return TrivialFamily(indices)
409
+
410
+ raise NotImplementedError
411
+ if (isinstance(indices, (list, tuple, FiniteEnumeratedSet))
412
+ and not lazy):
413
+ return FiniteFamily({i: function(i) for i in indices},
414
+ keys=indices)
415
+
416
+ return LazyFamily(indices, function, name)
417
+ if lazy:
418
+ raise ValueError("lazy keyword is incompatible with hidden keys")
419
+ if hidden_function is None:
420
+ hidden_function = function
421
+ return FiniteFamilyWithHiddenKeys({i: function(i) for i in indices},
422
+ hidden_keys, hidden_function,
423
+ keys=indices)
424
+
425
+
426
+ cdef class AbstractFamily(Parent):
427
+ """
428
+ The abstract class for family.
429
+
430
+ Any family belongs to a class which inherits from :class:`AbstractFamily`.
431
+ """
432
+ def hidden_keys(self):
433
+ """
434
+ Return the hidden keys of the family, if any.
435
+
436
+ EXAMPLES::
437
+
438
+ sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
439
+ sage: f.hidden_keys()
440
+ []
441
+ """
442
+ return []
443
+
444
+ def keys(self):
445
+ """
446
+ Return the keys of the family.
447
+
448
+ EXAMPLES::
449
+
450
+ sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
451
+ sage: sorted(f.keys())
452
+ [3, 4, 7]
453
+ """
454
+ raise NotImplementedError
455
+
456
+ def values(self):
457
+ """
458
+ Return the elements (values) of this family.
459
+
460
+ EXAMPLES::
461
+
462
+ sage: f = Family(["c", "a", "b"], lambda x: x + x)
463
+ sage: sorted(f.values())
464
+ ['aa', 'bb', 'cc']
465
+ """
466
+ raise NotImplementedError
467
+
468
+ def items(self):
469
+ """
470
+ Return an iterator for key-value pairs.
471
+
472
+ A key can only appear once, but if the function is not injective, values may
473
+ appear multiple times.
474
+
475
+ EXAMPLES::
476
+
477
+ sage: f = Family([-2, -1, 0, 1, 2], abs)
478
+ sage: list(f.items())
479
+ [(-2, 2), (-1, 1), (0, 0), (1, 1), (2, 2)]
480
+ """
481
+ return zip(self.keys(), self.values())
482
+
483
+ def zip(self, f, other, name=None):
484
+ r"""
485
+ Given two families with same index set `I` (and same hidden
486
+ keys if relevant), returns the family
487
+ `( f(self[i], other[i]) )_{i \in I}`
488
+
489
+ .. TODO:: generalize to any number of families and merge with map?
490
+
491
+ EXAMPLES::
492
+
493
+ sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
494
+ sage: g = Family({3: '1', 4: '2', 7: '3'})
495
+ sage: h = f.zip(lambda x,y: x+y, g)
496
+ sage: list(h)
497
+ ['a1', 'b2', 'd3']
498
+ """
499
+ assert self.keys() == other.keys()
500
+ assert self.hidden_keys() == other.hidden_keys()
501
+ return Family(self.keys(), lambda i: f(self[i], other[i]),
502
+ hidden_keys=self.hidden_keys(), name=name)
503
+
504
+ def map(self, f, name=None):
505
+ r"""
506
+ Return the family `( f(\mathtt{self}[i]) )_{i \in I}`, where
507
+ `I` is the index set of ``self``.
508
+
509
+ EXAMPLES::
510
+
511
+ sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
512
+ sage: g = f.map(lambda x: x+'1')
513
+ sage: list(g)
514
+ ['a1', 'b1', 'd1']
515
+ """
516
+ return Family(self.keys(), lambda i: f(self[i]), hidden_keys=self.hidden_keys(), name=name)
517
+
518
+ # temporary; tested by TestSuite.
519
+ _an_element_ = EnumeratedSets.ParentMethods._an_element_
520
+
521
+ @cached_method
522
+ def inverse_family(self):
523
+ """
524
+ Return the inverse family, with keys and values exchanged. This
525
+ presumes that there are no duplicate values in ``self``.
526
+
527
+ This default implementation is not lazy and therefore will
528
+ only work with not too big finite families. It is also cached
529
+ for the same reason::
530
+
531
+ sage: Family({3: 'a', 4: 'b', 7: 'd'}).inverse_family()
532
+ Finite family {'a': 3, 'b': 4, 'd': 7}
533
+
534
+ sage: Family((3,4,7)).inverse_family()
535
+ Finite family {3: 0, 4: 1, 7: 2}
536
+ """
537
+ return Family({self[k]: k for k in self.keys()})
538
+
539
+
540
+ cdef class FiniteFamily(AbstractFamily):
541
+ r"""
542
+ A :class:`FiniteFamily` is an associative container which models a finite
543
+ family `(f_i)_{i \in I}`. Its elements `f_i` are therefore its
544
+ values. Instances should be created via the :func:`Family` factory. See its
545
+ documentation for examples and tests.
546
+
547
+ EXAMPLES:
548
+
549
+ We define the family `(f_i)_{i \in \{3,4,7\}}` with `f_3=a`,
550
+ `f_4=b`, and `f_7=d`::
551
+
552
+ sage: from sage.sets.family import FiniteFamily
553
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
554
+
555
+ Individual elements are accessible as in a usual dictionary::
556
+
557
+ sage: f[7]
558
+ 'd'
559
+
560
+ And the other usual dictionary operations are also available::
561
+
562
+ sage: len(f)
563
+ 3
564
+ sage: f.keys()
565
+ [3, 4, 7]
566
+
567
+ However f behaves as a container for the `f_i`'s::
568
+
569
+ sage: list(f)
570
+ ['a', 'b', 'd']
571
+ sage: [ x for x in f ]
572
+ ['a', 'b', 'd']
573
+
574
+ The order of the elements can be specified using the ``keys`` optional argument::
575
+
576
+ sage: f = FiniteFamily({"a": "aa", "b": "bb", "c" : "cc" }, keys = ["c", "a", "b"])
577
+ sage: list(f)
578
+ ['cc', 'aa', 'bb']
579
+ """
580
+
581
+ def __init__(self, dictionary, keys=None):
582
+ """
583
+ TESTS::
584
+
585
+ sage: from sage.sets.family import FiniteFamily
586
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
587
+ sage: TestSuite(f).run()
588
+
589
+ Check for bug :issue:`5538`::
590
+
591
+ sage: d = {1:"a", 3:"b", 4:"c"}
592
+ sage: f = Family(d)
593
+ sage: d[2] = 'DD'
594
+ sage: f
595
+ Finite family {1: 'a', 3: 'b', 4: 'c'}
596
+ """
597
+ # TODO: use keys to specify the order of the elements
598
+ Parent.__init__(self, category=FiniteEnumeratedSets())
599
+ self._dictionary = dict(dictionary)
600
+ self._keys = keys
601
+
602
+ @cached_method
603
+ def __hash__(self):
604
+ """
605
+ Return a hash value for ``self``.
606
+
607
+ EXAMPLES::
608
+
609
+ sage: f = Family(["c", "a", "b"], lambda x: x+x)
610
+ sage: hash(f) == hash(f)
611
+ True
612
+ sage: f2 = Family(["a", "c", "b"], lambda x: x+x)
613
+ sage: hash(f) == hash(f2)
614
+ True
615
+ sage: g = Family(["b", "c", "a"], lambda x: x+x+x)
616
+ sage: hash(f) == hash(g)
617
+ False
618
+
619
+ ::
620
+
621
+ sage: f = Family({1:[1,2]})
622
+ sage: hash(f) == hash(f)
623
+ True
624
+ """
625
+ try:
626
+ return hash(frozenset(self._dictionary.items()))
627
+ except (TypeError, ValueError):
628
+ return hash(frozenset(self.keys() +
629
+ [repr(v) for v in self.values()]))
630
+
631
+ def __bool__(self):
632
+ r"""
633
+ Return if ``self`` is empty or not.
634
+
635
+ EXAMPLES::
636
+
637
+ sage: from sage.sets.family import TrivialFamily
638
+ sage: f = Family(["c", "a", "b"], lambda x: x+x)
639
+ sage: bool(f)
640
+ True
641
+ sage: g = Family({})
642
+ sage: bool(g)
643
+ False
644
+ sage: h = Family([], lambda x: x+x)
645
+ sage: bool(h)
646
+ False
647
+ """
648
+ return bool(self._dictionary)
649
+
650
+ def keys(self):
651
+ """
652
+ Return the index set of this family.
653
+
654
+ EXAMPLES::
655
+
656
+ sage: f = Family(["c", "a", "b"], lambda x: x+x)
657
+ sage: f.keys()
658
+ ['c', 'a', 'b']
659
+ """
660
+ return (self._keys if self._keys is not None
661
+ else list(self._dictionary))
662
+
663
+ def values(self):
664
+ """
665
+ Return the elements of this family.
666
+
667
+ EXAMPLES::
668
+
669
+ sage: f = Family(["c", "a", "b"], lambda x: x+x)
670
+ sage: f.values()
671
+ ['cc', 'aa', 'bb']
672
+ """
673
+ if self._keys is not None:
674
+ return [self._dictionary[key] for key in self._keys]
675
+ else:
676
+ return list(self._dictionary.values())
677
+
678
+ def has_key(self, k) -> bool:
679
+ """
680
+ Return whether ``k`` is a key of ``self``.
681
+
682
+ EXAMPLES::
683
+
684
+ sage: Family({"a":1, "b":2, "c":3}).has_key("a")
685
+ True
686
+ sage: Family({"a":1, "b":2, "c":3}).has_key("d")
687
+ False
688
+ """
689
+ return k in self._dictionary
690
+
691
+ def __eq__(self, other) -> bool:
692
+ """
693
+ EXAMPLES::
694
+
695
+ sage: f = Family({1:'a', 2:'b', 3:'c'})
696
+ sage: g = Family({1:'a', 2:'b', 3:'c'})
697
+ sage: f == g
698
+ True
699
+
700
+ TESTS::
701
+
702
+ sage: from sage.sets.family import FiniteFamily
703
+
704
+ sage: f1 = FiniteFamily({1:'a', 2:'b', 3:'c'}, keys = [1,2,3])
705
+ sage: g1 = FiniteFamily({1:'a', 2:'b', 3:'c'}, keys = [1,2,3])
706
+ sage: h1 = FiniteFamily({1:'a', 2:'b', 3:'c'}, keys = [2,1,3])
707
+
708
+ sage: f1 == g1
709
+ True
710
+ sage: f1 == h1
711
+ False
712
+ sage: f1 == f
713
+ False
714
+ """
715
+ return (isinstance(other, self.__class__) and
716
+ self._keys == (<FiniteFamily> other)._keys and
717
+ self._dictionary == (<FiniteFamily> other)._dictionary)
718
+
719
+ def _repr_(self):
720
+ """
721
+ EXAMPLES::
722
+
723
+ sage: from sage.sets.family import FiniteFamily
724
+ sage: FiniteFamily({3: 'a'}) # indirect doctest
725
+ Finite family {3: 'a'}
726
+
727
+ sage: FiniteFamily({3: 'a', 4: 'b'}) # indirect doctest
728
+ Finite family {3: 'a', 4: 'b'}
729
+
730
+ sage: FiniteFamily({3: 'a', 4: 'b'}, keys=[4,3]) # indirect doctest
731
+ Finite family {4: 'b', 3: 'a'}
732
+ """
733
+ if self._keys is None:
734
+ d = ' '.join(pformat(self._dictionary)[1:-1].splitlines())
735
+ else:
736
+ d = ', '.join('{}: {}'.format(saferepr(key),
737
+ saferepr(self._dictionary[key]))
738
+ for key in self._keys)
739
+ return 'Finite family {{{}}}'.format(d)
740
+
741
+ def __contains__(self, x):
742
+ """
743
+ EXAMPLES::
744
+
745
+ sage: from sage.sets.family import FiniteFamily
746
+ sage: f = FiniteFamily({3: 'a'})
747
+ sage: 'a' in f
748
+ True
749
+ sage: 'b' in f
750
+ False
751
+ """
752
+ return x in self.values()
753
+
754
+ def __len__(self):
755
+ """
756
+ Return the number of elements in ``self``.
757
+
758
+ EXAMPLES::
759
+
760
+ sage: from sage.sets.family import FiniteFamily
761
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
762
+ sage: len(f)
763
+ 3
764
+ """
765
+ return len(self._dictionary)
766
+
767
+ def cardinality(self):
768
+ """
769
+ Return the number of elements in ``self``.
770
+
771
+ EXAMPLES::
772
+
773
+ sage: from sage.sets.family import FiniteFamily
774
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
775
+ sage: f.cardinality()
776
+ 3
777
+ """
778
+ return Integer(len(self._dictionary))
779
+
780
+ def __iter__(self):
781
+ """
782
+ EXAMPLES::
783
+
784
+ sage: from sage.sets.family import FiniteFamily
785
+ sage: f = FiniteFamily({3: 'a'})
786
+ sage: i = iter(f)
787
+ sage: next(i)
788
+ 'a'
789
+ """
790
+ return iter(self.values())
791
+
792
+ def __getitem__(self, i):
793
+ """
794
+ Note that we can't just do self.__getitem__ =
795
+ dictionary.__getitem__ in the __init__ method since Python
796
+ queries the object's type/class for the special methods rather than
797
+ querying the object itself.
798
+
799
+ EXAMPLES::
800
+
801
+ sage: from sage.sets.family import FiniteFamily
802
+ sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
803
+ sage: f[3]
804
+ 'a'
805
+ """
806
+ return self._dictionary[i]
807
+
808
+ # For the pickle and copy modules
809
+ def __getstate__(self):
810
+ """
811
+ TESTS::
812
+
813
+ sage: from sage.sets.family import FiniteFamily
814
+ sage: f = FiniteFamily({3: 'a'})
815
+ sage: f.__getstate__()
816
+ {'dictionary': {3: 'a'}, 'keys': None}
817
+ """
818
+ return {'dictionary': self._dictionary, 'keys': self._keys}
819
+
820
+ def __setstate__(self, state):
821
+ """
822
+ TESTS::
823
+
824
+ sage: from sage.sets.family import FiniteFamily
825
+ sage: f = FiniteFamily({3: 'a'})
826
+ sage: f.__setstate__({'dictionary': {4:'b'}})
827
+ sage: f
828
+ Finite family {4: 'b'}
829
+ """
830
+ self.__init__(state['dictionary'], keys=state.get("keys"))
831
+
832
+
833
+ class FiniteFamilyWithHiddenKeys(FiniteFamily):
834
+ r"""
835
+ A close variant of :class:`FiniteFamily` where the family contains some
836
+ hidden keys whose corresponding values are computed lazily (and
837
+ remembered). Instances should be created via the :func:`Family` factory.
838
+ See its documentation for examples and tests.
839
+
840
+ Caveat: Only instances of this class whose functions are compatible
841
+ with :mod:`sage.misc.fpickle` can be pickled.
842
+ """
843
+ def __init__(self, dictionary, hidden_keys, hidden_function, keys=None):
844
+ """
845
+ EXAMPLES::
846
+
847
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
848
+ sage: TestSuite(f).run()
849
+ """
850
+ FiniteFamily.__init__(self, dictionary, keys=keys)
851
+ self._hidden_keys = hidden_keys
852
+ self.hidden_function = hidden_function
853
+ self.hidden_dictionary = {}
854
+
855
+ # would be better to define as usual method
856
+ # any better to unset the def of __getitem__ by FiniteFamily?
857
+ # self.__getitem__ = lambda i: dictionary[i] if dictionary.has_key(i) else hidden_dictionary[i]
858
+
859
+ def __getitem__(self, i):
860
+ """
861
+ EXAMPLES::
862
+
863
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
864
+ sage: f[3]
865
+ 6
866
+ sage: f[2]
867
+ 4
868
+ sage: f[5]
869
+ Traceback (most recent call last):
870
+ ...
871
+ KeyError
872
+ """
873
+ try:
874
+ return FiniteFamily.__getitem__(self, i)
875
+ except KeyError:
876
+ try:
877
+ return self.hidden_dictionary[i]
878
+ except KeyError:
879
+ if i not in self._hidden_keys:
880
+ raise KeyError
881
+ v = self.hidden_function(i)
882
+ self.hidden_dictionary[i] = v
883
+ return v
884
+
885
+ def hidden_keys(self):
886
+ """
887
+ Return ``self``'s hidden keys.
888
+
889
+ EXAMPLES::
890
+
891
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
892
+ sage: f.hidden_keys()
893
+ [2]
894
+ """
895
+ return self._hidden_keys
896
+
897
+ def __getstate__(self):
898
+ """
899
+ TESTS::
900
+
901
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
902
+ sage: d = f.__getstate__()
903
+ sage: d['hidden_keys']
904
+ [2]
905
+ """
906
+ from sage.misc.fpickle import pickle_function
907
+ f = pickle_function(self.hidden_function)
908
+ state = super().__getstate__()
909
+ state.update({'hidden_keys': self._hidden_keys,
910
+ 'hidden_dictionary': self.hidden_dictionary,
911
+ 'hidden_function': f})
912
+ return state
913
+
914
+ def __setstate__(self, d):
915
+ """
916
+ TESTS::
917
+
918
+ sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
919
+ sage: d = f.__getstate__()
920
+ sage: f = Family([4,5,6], lambda i: 2*i, hidden_keys=[2])
921
+ sage: f.__setstate__(d)
922
+ sage: f.keys()
923
+ [3, 4, 7]
924
+ sage: f[3]
925
+ 6
926
+ """
927
+ hidden_function = d['hidden_function']
928
+ if isinstance(hidden_function, (str, bytes)):
929
+ # Let's assume that hidden_function is an unpickled function.
930
+ from sage.misc.fpickle import unpickle_function
931
+ hidden_function = unpickle_function(hidden_function)
932
+ self.__init__(d['dictionary'], d['hidden_keys'], hidden_function)
933
+ self.hidden_dictionary = d['hidden_dictionary']
934
+ # Old pickles from before Issue #22955 may not have a 'keys'
935
+ if 'keys' in d:
936
+ self._keys = d['keys']
937
+ else:
938
+ self._keys = None
939
+
940
+
941
+ class LazyFamily(AbstractFamily):
942
+ r"""
943
+ A LazyFamily(I, f) is an associative container which models the
944
+ (possibly infinite) family `(f(i))_{i \in I}`.
945
+
946
+ Instances should be created via the :func:`Family` factory. See its
947
+ documentation for examples and tests.
948
+ """
949
+ def __init__(self, set, function, name=None):
950
+ """
951
+ TESTS::
952
+
953
+ sage: from sage.sets.family import LazyFamily
954
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i); f
955
+ Lazy family (<lambda>(i))_{i in [3, 4, 7]}
956
+ sage: TestSuite(f).run()
957
+
958
+ Check for :issue:`5538`::
959
+
960
+ sage: l = [3,4,7]
961
+ sage: f = LazyFamily(l, lambda i: 2*i)
962
+ sage: l[1] = 18
963
+ sage: f
964
+ Lazy family (<lambda>(i))_{i in [3, 4, 7]}
965
+ """
966
+ if set in FiniteEnumeratedSets():
967
+ category = FiniteEnumeratedSets()
968
+ elif set in InfiniteEnumeratedSets():
969
+ category = InfiniteEnumeratedSets()
970
+ elif isinstance(set, (list, tuple, range)):
971
+ category = FiniteEnumeratedSets()
972
+ else: # some sets such as QQ implements is_finite() but is not in InfiniteEnumeratedSets()
973
+ try:
974
+ if set.is_finite():
975
+ category = FiniteEnumeratedSets()
976
+ else:
977
+ category = InfiniteEnumeratedSets()
978
+ except (AttributeError, NotImplementedError):
979
+ category = EnumeratedSets()
980
+
981
+ Parent.__init__(self, category=category)
982
+
983
+ self.set = copy(set)
984
+ self.function = function
985
+ self.function_name = name
986
+
987
+ def __bool__(self):
988
+ r"""
989
+ Return if ``self`` is empty or not.
990
+
991
+ EXAMPLES::
992
+
993
+ sage: from sage.sets.family import LazyFamily
994
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
995
+ sage: bool(f)
996
+ True
997
+ sage: g = LazyFamily([], lambda i: 2*i)
998
+ sage: bool(g)
999
+ False
1000
+ sage: h = Family(ZZ, lambda x: x+x)
1001
+ sage: bool(h)
1002
+ True
1003
+ """
1004
+ return bool(self.set)
1005
+
1006
+ @cached_method
1007
+ def __hash__(self):
1008
+ """
1009
+ Return a hash value for ``self``.
1010
+
1011
+ EXAMPLES::
1012
+
1013
+ sage: from sage.sets.family import LazyFamily
1014
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1015
+ sage: hash(f) == hash(f)
1016
+ True
1017
+ sage: g = LazyFamily(ZZ, lambda i: 2*i)
1018
+ sage: hash(g) == hash(g)
1019
+ True
1020
+ sage: h = LazyFamily(ZZ, lambda i: 2*i, name='foo')
1021
+ sage: hash(h) == hash(h)
1022
+ True
1023
+
1024
+ ::
1025
+
1026
+ sage: class X():
1027
+ ....: def __call__(self, x):
1028
+ ....: return x
1029
+ ....: __hash__ = None
1030
+ sage: f = Family([1,2,3], X())
1031
+ sage: hash(f) == hash(f)
1032
+ True
1033
+ """
1034
+ try:
1035
+ return hash(self.keys()) + hash(self.function)
1036
+ except (TypeError, ValueError):
1037
+ return super().__hash__()
1038
+
1039
+ def __eq__(self, other):
1040
+ """
1041
+ WARNING: Since there is no way to compare function, we only compare
1042
+ their name.
1043
+
1044
+ TESTS::
1045
+
1046
+ sage: from sage.sets.family import LazyFamily
1047
+ sage: fun = lambda i: 2*i
1048
+ sage: f = LazyFamily([3,4,7], fun)
1049
+ sage: g = LazyFamily([3,4,7], fun)
1050
+ sage: f == g
1051
+ True
1052
+ """
1053
+ if not isinstance(other, self.__class__):
1054
+ return False
1055
+ if not self.set == other.set:
1056
+ return False
1057
+ return repr(self) == repr(other)
1058
+
1059
+ def _repr_(self):
1060
+ """
1061
+ EXAMPLES::
1062
+
1063
+ sage: from sage.sets.family import LazyFamily
1064
+ sage: def fun(i): 2*i
1065
+ sage: f = LazyFamily([3,4,7], fun); f
1066
+ Lazy family (fun(i))_{i in [3, 4, 7]}
1067
+
1068
+ sage: f = Family(Permutations(3), attrcall("to_lehmer_code"), lazy=True); f
1069
+ Lazy family (i.to_lehmer_code())_{i in Standard permutations of 3}
1070
+
1071
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i); f
1072
+ Lazy family (<lambda>(i))_{i in [3, 4, 7]}
1073
+
1074
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i, name='foo'); f
1075
+ Lazy family (foo(i))_{i in [3, 4, 7]}
1076
+
1077
+ TESTS:
1078
+
1079
+ Check that using a class as the function is correctly handled::
1080
+
1081
+ sage: Family(NonNegativeIntegers(), PerfectMatchings) # needs sage.combinat
1082
+ Lazy family (<class 'sage.combinat.perfect_matching.PerfectMatchings'>(i))_{i in Non negative integers}
1083
+ """
1084
+ if self.function_name is not None:
1085
+ name = self.function_name + "(i)"
1086
+ elif isinstance(self.function, types.LambdaType):
1087
+ name = self.function.__name__
1088
+ name = name + "(i)"
1089
+ else:
1090
+ name = repr(self.function)
1091
+ if isinstance(self.function, AttrCallObject):
1092
+ name = "i" + name[1:]
1093
+ else:
1094
+ name = name + "(i)"
1095
+ return "Lazy family ({})_{{i in {}}}".format(name, self.set)
1096
+
1097
+ def keys(self):
1098
+ """
1099
+ Return ``self``'s keys.
1100
+
1101
+ EXAMPLES::
1102
+
1103
+ sage: from sage.sets.family import LazyFamily
1104
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1105
+ sage: f.keys()
1106
+ [3, 4, 7]
1107
+ """
1108
+ return self.set
1109
+
1110
+ def cardinality(self):
1111
+ """
1112
+ Return the number of elements in ``self``.
1113
+
1114
+ EXAMPLES::
1115
+
1116
+ sage: from sage.sets.family import LazyFamily
1117
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1118
+ sage: f.cardinality()
1119
+ 3
1120
+ sage: l = LazyFamily(NonNegativeIntegers(), lambda i: 2*i)
1121
+ sage: l.cardinality()
1122
+ +Infinity
1123
+
1124
+ TESTS:
1125
+
1126
+ Check that :issue:`15195` is fixed::
1127
+
1128
+ sage: C = cartesian_product([PositiveIntegers(), [1,2,3]])
1129
+ sage: C.cardinality()
1130
+ +Infinity
1131
+ sage: F = Family(C, lambda x: x)
1132
+ sage: F.cardinality()
1133
+ +Infinity
1134
+ """
1135
+ try:
1136
+ return Integer(len(self.set))
1137
+ except (AttributeError, NotImplementedError, TypeError):
1138
+ return self.set.cardinality()
1139
+
1140
+ def __iter__(self):
1141
+ """
1142
+ EXAMPLES::
1143
+
1144
+ sage: from sage.sets.family import LazyFamily
1145
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1146
+ sage: [i for i in f]
1147
+ [6, 8, 14]
1148
+ """
1149
+ for i in self.set:
1150
+ yield self[i]
1151
+
1152
+ def __contains__(self, x):
1153
+ """
1154
+ EXAMPLES::
1155
+
1156
+ sage: from sage.sets.family import LazyFamily
1157
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1158
+ sage: 3 in f, 14 in f
1159
+ (False, True)
1160
+
1161
+ By default this expands the lazy family, which is only done for
1162
+ families known to be finite::
1163
+
1164
+ sage: 5 in LazyFamily(NonNegativeIntegers(), lambda i: 2*i)
1165
+ Traceback (most recent call last):
1166
+ ...
1167
+ ValueError: family must be finite to check containment
1168
+ """
1169
+ if self not in FiniteEnumeratedSets():
1170
+ raise ValueError('family must be finite to check containment')
1171
+ return x in iter(self)
1172
+
1173
+ def __getitem__(self, i):
1174
+ """
1175
+ EXAMPLES::
1176
+
1177
+ sage: from sage.sets.family import LazyFamily
1178
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1179
+ sage: f[3]
1180
+ 6
1181
+
1182
+ TESTS::
1183
+
1184
+ sage: f[5]
1185
+ 10
1186
+ """
1187
+ return self.function(i)
1188
+
1189
+ def __getstate__(self):
1190
+ """
1191
+ EXAMPLES::
1192
+
1193
+ sage: from sage.sets.family import LazyFamily
1194
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1195
+ sage: d = f.__getstate__()
1196
+ sage: d['set']
1197
+ [3, 4, 7]
1198
+
1199
+ sage: f = LazyFamily(Permutations(3), lambda p: p.to_lehmer_code())
1200
+ sage: f == loads(dumps(f))
1201
+ True
1202
+
1203
+ sage: f = LazyFamily(Permutations(3), attrcall("to_lehmer_code"))
1204
+ sage: f == loads(dumps(f))
1205
+ True
1206
+ """
1207
+ f = self.function
1208
+ # This should be done once for all by registering
1209
+ # sage.misc.fpickle.pickle_function to copyreg
1210
+ if isinstance(f, types.FunctionType):
1211
+ from sage.misc.fpickle import pickle_function
1212
+ f = pickle_function(f)
1213
+
1214
+ return {'set': self.set,
1215
+ 'function': f}
1216
+
1217
+ def __setstate__(self, d):
1218
+ """
1219
+ EXAMPLES::
1220
+
1221
+ sage: from sage.sets.family import LazyFamily
1222
+ sage: f = LazyFamily([3,4,7], lambda i: 2*i)
1223
+ sage: d = f.__getstate__()
1224
+ sage: f = LazyFamily([4,5,6], lambda i: 2*i)
1225
+ sage: f.__setstate__(d)
1226
+ sage: f.keys()
1227
+ [3, 4, 7]
1228
+ sage: f[3]
1229
+ 6
1230
+ """
1231
+ function = d['function']
1232
+ if isinstance(function, bytes):
1233
+ # Let's assume that function is an unpickled function.
1234
+ from sage.misc.fpickle import unpickle_function
1235
+ function = unpickle_function(function)
1236
+
1237
+ self.__init__(d['set'], function)
1238
+
1239
+
1240
+ class TrivialFamily(AbstractFamily):
1241
+ r"""
1242
+ :class:`TrivialFamily` turns a list/tuple `c` into a family indexed by the
1243
+ set `\{0, \dots, |c|-1\}`.
1244
+
1245
+ Instances should be created via the :func:`Family` factory. See its
1246
+ documentation for examples and tests.
1247
+ """
1248
+ def __init__(self, enumeration):
1249
+ """
1250
+ EXAMPLES::
1251
+
1252
+ sage: from sage.sets.family import TrivialFamily
1253
+ sage: f = TrivialFamily((3,4,7)); f
1254
+ Family (3, 4, 7)
1255
+ sage: f = TrivialFamily([3,4,7]); f
1256
+ Family (3, 4, 7)
1257
+ sage: TestSuite(f).run()
1258
+ """
1259
+ Parent.__init__(self, category=FiniteEnumeratedSets())
1260
+ self._enumeration = tuple(enumeration)
1261
+
1262
+ def __bool__(self):
1263
+ r"""
1264
+ Return if ``self`` is empty or not.
1265
+
1266
+ EXAMPLES::
1267
+
1268
+ sage: from sage.sets.family import TrivialFamily
1269
+ sage: f = TrivialFamily((3,4,7))
1270
+ sage: bool(f)
1271
+ True
1272
+ sage: g = Family([])
1273
+ sage: bool(g)
1274
+ False
1275
+ """
1276
+ return bool(self._enumeration)
1277
+
1278
+ def __eq__(self, other):
1279
+ """
1280
+ TESTS::
1281
+
1282
+ sage: f = Family((3,4,7))
1283
+ sage: g = Family([3,4,7])
1284
+ sage: f == g
1285
+ True
1286
+ """
1287
+ return (isinstance(other, self.__class__) and
1288
+ self._enumeration == other._enumeration)
1289
+
1290
+ def __hash__(self):
1291
+ """
1292
+ Return a hash value for ``self``.
1293
+
1294
+ EXAMPLES::
1295
+
1296
+ sage: from sage.sets.family import TrivialFamily
1297
+ sage: f = TrivialFamily((3,4,7))
1298
+ sage: hash(f) == hash(f)
1299
+ True
1300
+ """
1301
+ return hash(self._enumeration)
1302
+
1303
+ def _repr_(self):
1304
+ """
1305
+ EXAMPLES::
1306
+
1307
+ sage: from sage.sets.family import TrivialFamily
1308
+ sage: f = TrivialFamily([3,4,7]); f # indirect doctest
1309
+ Family (3, 4, 7)
1310
+ """
1311
+ return "Family %s" % ((self._enumeration),)
1312
+
1313
+ def keys(self):
1314
+ """
1315
+ Return ``self``'s keys.
1316
+
1317
+ EXAMPLES::
1318
+
1319
+ sage: from sage.sets.family import TrivialFamily
1320
+ sage: f = TrivialFamily([3,4,7])
1321
+ sage: f.keys()
1322
+ [0, 1, 2]
1323
+ """
1324
+ return list(range(len(self._enumeration)))
1325
+
1326
+ def cardinality(self):
1327
+ """
1328
+ Return the number of elements in ``self``.
1329
+
1330
+ EXAMPLES::
1331
+
1332
+ sage: from sage.sets.family import TrivialFamily
1333
+ sage: f = TrivialFamily([3,4,7])
1334
+ sage: f.cardinality()
1335
+ 3
1336
+ """
1337
+ return Integer(len(self._enumeration))
1338
+
1339
+ def __iter__(self):
1340
+ """
1341
+ EXAMPLES::
1342
+
1343
+ sage: from sage.sets.family import TrivialFamily
1344
+ sage: f = TrivialFamily([3,4,7])
1345
+ sage: [i for i in f]
1346
+ [3, 4, 7]
1347
+ """
1348
+ return iter(self._enumeration)
1349
+
1350
+ def __contains__(self, x):
1351
+ """
1352
+ EXAMPLES::
1353
+
1354
+ sage: from sage.sets.family import TrivialFamily
1355
+ sage: f = TrivialFamily([3,4,7])
1356
+ sage: 3 in f
1357
+ True
1358
+ sage: 5 in f
1359
+ False
1360
+ """
1361
+ return x in self._enumeration
1362
+
1363
+ def __getitem__(self, i):
1364
+ """
1365
+ EXAMPLES::
1366
+
1367
+ sage: from sage.sets.family import TrivialFamily
1368
+ sage: f = TrivialFamily([3,4,7])
1369
+ sage: f[1]
1370
+ 4
1371
+ """
1372
+ return self._enumeration[i]
1373
+
1374
+ def __getstate__(self):
1375
+ """
1376
+ TESTS::
1377
+
1378
+ sage: from sage.sets.family import TrivialFamily
1379
+ sage: f = TrivialFamily([3,4,7])
1380
+ sage: f.__getstate__()
1381
+ {'_enumeration': (3, 4, 7)}
1382
+ """
1383
+ return {'_enumeration': self._enumeration}
1384
+
1385
+ def __setstate__(self, state):
1386
+ """
1387
+ TESTS::
1388
+
1389
+ sage: from sage.sets.family import TrivialFamily
1390
+ sage: f = TrivialFamily([3,4,7])
1391
+ sage: f.__setstate__({'_enumeration': (2, 4, 8)})
1392
+ sage: f
1393
+ Family (2, 4, 8)
1394
+ """
1395
+ self.__init__(state['_enumeration'])
1396
+
1397
+ def map(self, f, name=None):
1398
+ r"""
1399
+ Return the family `( f(\mathtt{self}[i]) )_{i \in I}`,
1400
+ where `I` is the index set of ``self``.
1401
+
1402
+ The result is again a :class:`TrivialFamily`.
1403
+
1404
+ EXAMPLES::
1405
+
1406
+ sage: from sage.sets.family import TrivialFamily
1407
+ sage: f = TrivialFamily(['a', 'b', 'd'])
1408
+ sage: g = f.map(lambda x: x + '1'); g
1409
+ Family ('a1', 'b1', 'd1')
1410
+ """
1411
+ # tuple([... for ...]) is faster than tuple(... for ...)
1412
+ return Family(tuple([f(x) for x in self._enumeration]), name=name)
1413
+
1414
+
1415
+ class EnumeratedFamily(LazyFamily):
1416
+ r"""
1417
+ :class:`EnumeratedFamily` turns an enumerated set ``c`` into a family
1418
+ indexed by the set `\{0,\dots, |c|-1\}` (or ``NN`` if `|c|` is
1419
+ countably infinite).
1420
+
1421
+ Instances should be created via the :func:`Family` factory. See its
1422
+ documentation for examples and tests.
1423
+ """
1424
+ def __init__(self, enumset):
1425
+ """
1426
+ EXAMPLES::
1427
+
1428
+ sage: from sage.sets.family import EnumeratedFamily
1429
+ sage: f = EnumeratedFamily(Permutations(3))
1430
+ sage: TestSuite(f).run()
1431
+
1432
+ sage: f = Family(NonNegativeIntegers())
1433
+ sage: TestSuite(f).run()
1434
+
1435
+ TESTS:
1436
+
1437
+ Check that category and keys are set correctly (:issue:`28274`)::
1438
+
1439
+ sage: from sage.sets.family import EnumeratedFamily
1440
+ sage: f = EnumeratedFamily(Permutations(4))
1441
+ sage: f.category()
1442
+ Category of finite enumerated sets
1443
+ sage: list(f.keys()) == list(range(f.cardinality()))
1444
+ True
1445
+ sage: Family(Permutations()).keys()
1446
+ Non negative integers
1447
+ sage: type(Family(NN))
1448
+ <class 'sage.sets.family.EnumeratedFamily_with_category'>
1449
+ """
1450
+ if enumset.cardinality() == Infinity:
1451
+ baseset = NonNegativeIntegers()
1452
+ else:
1453
+ baseset = range(enumset.cardinality())
1454
+ LazyFamily.__init__(self, baseset, enumset.unrank)
1455
+ self.enumset = enumset
1456
+
1457
+ def __eq__(self, other):
1458
+ """
1459
+ EXAMPLES::
1460
+
1461
+ sage: f = Family(Permutations(3))
1462
+ sage: g = Family(Permutations(3))
1463
+ sage: f == g
1464
+ True
1465
+ """
1466
+ return (isinstance(other, self.__class__) and
1467
+ self.enumset == other.enumset)
1468
+
1469
+ def __repr__(self):
1470
+ """
1471
+ EXAMPLES::
1472
+
1473
+ sage: f = Family(Permutations(3)); f # indirect doctest
1474
+ Family (Standard permutations of 3)
1475
+
1476
+ sage: f = Family(NonNegativeIntegers()); f
1477
+ Family (Non negative integers)
1478
+ """
1479
+ # return "Family ((%s)[i])_(i=1...%s)"%(self.enumset, self.enumset.cardinality())
1480
+ if isinstance(self.enumset, FiniteEnumeratedSet):
1481
+ return "Family %s" % (self.enumset._elements,)
1482
+ return "Family (%s)" % (self.enumset)
1483
+
1484
+ def __contains__(self, x):
1485
+ """
1486
+ EXAMPLES::
1487
+
1488
+ sage: f = Family(Permutations(3))
1489
+ sage: [2,1,3] in f
1490
+ True
1491
+ """
1492
+ return x in self.enumset
1493
+
1494
+ def cardinality(self):
1495
+ """
1496
+ Return the number of elements in ``self``.
1497
+
1498
+ EXAMPLES::
1499
+
1500
+ sage: from sage.sets.family import EnumeratedFamily
1501
+ sage: f = EnumeratedFamily(Permutations(3))
1502
+ sage: f.cardinality()
1503
+ 6
1504
+
1505
+ sage: f = Family(NonNegativeIntegers())
1506
+ sage: f.cardinality()
1507
+ +Infinity
1508
+ """
1509
+ return self.enumset.cardinality()
1510
+
1511
+ def __iter__(self):
1512
+ """
1513
+ EXAMPLES::
1514
+
1515
+ sage: from sage.sets.family import EnumeratedFamily
1516
+ sage: f = EnumeratedFamily(Permutations(3))
1517
+ sage: [i for i in f]
1518
+ [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
1519
+ """
1520
+ yield from self.enumset
1521
+
1522
+ def __getitem__(self, i):
1523
+ """
1524
+ EXAMPLES::
1525
+
1526
+ sage: from sage.sets.family import EnumeratedFamily
1527
+ sage: f = EnumeratedFamily(Permutations(3))
1528
+ sage: f[1]
1529
+ [1, 3, 2]
1530
+ """
1531
+ return self.enumset.unrank(i)
1532
+
1533
+ def __getstate__(self):
1534
+ """
1535
+ EXAMPLES::
1536
+
1537
+ sage: from sage.sets.family import EnumeratedFamily
1538
+ sage: f = EnumeratedFamily(Permutations(3))
1539
+ sage: f.__getstate__()
1540
+ {'enumset': Standard permutations of 3}
1541
+ sage: loads(dumps(f)) == f
1542
+ True
1543
+ """
1544
+ return {'enumset': self.enumset}
1545
+
1546
+ def __setstate__(self, state):
1547
+ """
1548
+ EXAMPLES::
1549
+
1550
+ sage: from sage.sets.family import EnumeratedFamily
1551
+ sage: f = EnumeratedFamily(Permutations(0))
1552
+ sage: f.__setstate__({'enumset': Permutations(3)})
1553
+ sage: f
1554
+ Family (Standard permutations of 3)
1555
+ """
1556
+ self.__init__(state['enumset'])