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
@@ -0,0 +1,1994 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ # sage.doctest: needs sage.combinat sage.graphs
3
+ r"""
4
+ Finite posets
5
+
6
+ Here is some terminology used in this file:
7
+
8
+ - An *order filter* (or *upper set*) of a poset `P` is a subset `S` of `P`
9
+ such that if `x \leq y` and `x\in S` then `y\in S`.
10
+
11
+ - An *order ideal* (or *lower set*) of a poset `P` is a subset `S` of `P`
12
+ such that if `x \leq y` and `y\in S` then `x\in S`.
13
+ """
14
+ # ****************************************************************************
15
+ # Copyright (C) 2011 Nicolas M. Thiery <nthiery at users.sf.net>
16
+ #
17
+ # Distributed under the terms of the GNU General Public License (GPL)
18
+ # https://www.gnu.org/licenses/
19
+ # *****************************************************************************
20
+
21
+ from sage.misc.abstract_method import abstract_method
22
+ from sage.categories.category_with_axiom import CategoryWithAxiom
23
+
24
+
25
+ class FinitePosets(CategoryWithAxiom):
26
+ r"""
27
+ The category of finite posets i.e. finite sets with a partial
28
+ order structure.
29
+
30
+ EXAMPLES::
31
+
32
+ sage: FinitePosets()
33
+ Category of finite posets
34
+ sage: FinitePosets().super_categories()
35
+ [Category of posets, Category of finite sets]
36
+ sage: FinitePosets().example()
37
+ NotImplemented
38
+
39
+ .. SEEALSO:: :class:`~sage.categories.posets.Posets`, :func:`Poset`
40
+
41
+ TESTS::
42
+
43
+ sage: C = FinitePosets()
44
+ sage: C is Posets().Finite()
45
+ True
46
+ sage: TestSuite(C).run()
47
+ """
48
+
49
+ class ParentMethods:
50
+
51
+ ##########################################################################
52
+ # Properties of this poset
53
+
54
+ def is_lattice(self):
55
+ r"""
56
+ Return whether the poset is a lattice.
57
+
58
+ A poset is a lattice if all pairs of elements have
59
+ both a least upper bound ("join") and a greatest lower bound
60
+ ("meet") in the poset.
61
+
62
+ EXAMPLES::
63
+
64
+ sage: P = Poset([[1, 3, 2], [4], [4, 5, 6], [6], [7], [7], [7], []])
65
+ sage: P.is_lattice() # needs sage.modules
66
+ True
67
+
68
+ sage: P = Poset([[1, 2], [3], [3], []])
69
+ sage: P.is_lattice() # needs sage.modules
70
+ True
71
+
72
+ sage: P = Poset({0: [2, 3], 1: [2, 3]})
73
+ sage: P.is_lattice()
74
+ False
75
+
76
+ sage: P = Poset({1: [2, 3, 4], 2: [5, 6], 3: [5, 7], 4: [6, 7], 5: [8, 9],
77
+ ....: 6: [8, 10], 7: [9, 10], 8: [11], 9: [11], 10: [11]})
78
+ sage: P.is_lattice() # needs sage.modules
79
+ False
80
+
81
+ TESTS::
82
+
83
+ sage: P = Poset()
84
+ sage: P.is_lattice()
85
+ True
86
+
87
+ .. SEEALSO::
88
+
89
+ - Weaker properties: :meth:`~sage.combinat.posets.posets.FinitePoset.is_join_semilattice`,
90
+ :meth:`~sage.combinat.posets.posets.FinitePoset.is_meet_semilattice`
91
+ """
92
+ return (self.cardinality() == 0 or
93
+ (self.has_bottom() and self.is_join_semilattice()))
94
+
95
+ def is_self_dual(self):
96
+ r"""
97
+ Return whether the poset is *self-dual*.
98
+
99
+ A poset is self-dual if it is isomorphic to its dual poset.
100
+
101
+ EXAMPLES::
102
+
103
+ sage: P = Poset({1: [3, 4], 2: [3, 4]})
104
+ sage: P.is_self_dual()
105
+ True
106
+
107
+ sage: P = Poset({1: [2, 3]})
108
+ sage: P.is_self_dual()
109
+ False
110
+
111
+ TESTS::
112
+
113
+ sage: P = Poset()
114
+ sage: P.is_self_dual()
115
+ True
116
+
117
+ .. SEEALSO::
118
+
119
+ - Stronger properties: :meth:`~sage.combinat.posets.lattices.FiniteLatticePoset.is_orthocomplemented` (for lattices)
120
+ - Other: :meth:`~sage.combinat.posets.posets.FinitePoset.dual`
121
+ """
122
+ # Two quick checks before full isomorphic test.
123
+ if sorted(self._hasse_diagram.in_degree()) != sorted(self._hasse_diagram.out_degree()):
124
+ return False
125
+ levels_orig = [len(x) for x in self._hasse_diagram.level_sets()]
126
+ dual_poset_hasse = self._hasse_diagram.reverse()
127
+ levels_dual = [len(x) for x in dual_poset_hasse.level_sets()]
128
+ if levels_orig != levels_dual:
129
+ return False
130
+ return self._hasse_diagram.is_isomorphic(dual_poset_hasse)
131
+
132
+ ##########################################################################
133
+ # Properties of morphisms
134
+
135
+ def is_poset_isomorphism(self, f, codomain):
136
+ r"""
137
+ Return whether `f` is an isomorphism of posets from
138
+ ``self`` to ``codomain``.
139
+
140
+ INPUT:
141
+
142
+ - ``f`` -- a function from ``self`` to ``codomain``
143
+ - ``codomain`` -- a poset
144
+
145
+ EXAMPLES:
146
+
147
+ We build the poset `D` of divisors of 30, and check that
148
+ it is isomorphic to the boolean lattice `B` of the subsets
149
+ of `\{2,3,5\}` ordered by inclusion, via the reverse
150
+ function `f: B \to D, b \mapsto \prod_{x\in b} x`::
151
+
152
+ sage: D = Poset((divisors(30), attrcall("divides")))
153
+ sage: B = Poset(([frozenset(s) for s in Subsets([2,3,5])],
154
+ ....: attrcall("issubset")))
155
+ sage: def f(b): return D(prod(b))
156
+ sage: B.is_poset_isomorphism(f, D)
157
+ True
158
+
159
+ On the other hand, `f` is not an isomorphism to the chain
160
+ of divisors of 30, ordered by usual comparison::
161
+
162
+ sage: P = Poset((divisors(30), operator.le))
163
+ sage: def f(b): return P(prod(b))
164
+ sage: B.is_poset_isomorphism(f, P)
165
+ False
166
+
167
+ A non surjective case::
168
+
169
+ sage: B = Poset(([frozenset(s) for s in Subsets([2,3])],
170
+ ....: attrcall("issubset")))
171
+ sage: def f(b): return D(prod(b))
172
+ sage: B.is_poset_isomorphism(f, D)
173
+ False
174
+
175
+ A non injective case::
176
+
177
+ sage: B = Poset(([frozenset(s) for s in Subsets([2,3,5,6])],
178
+ ....: attrcall("issubset")))
179
+ sage: def f(b): return D(gcd(prod(b), 30))
180
+ sage: B.is_poset_isomorphism(f, D)
181
+ False
182
+
183
+ .. NOTE:: since ``D`` and ``B`` are not facade posets, ``f`` is
184
+ responsible for the conversions between integers and subsets to
185
+ elements of ``D`` and ``B`` and back.
186
+
187
+ .. SEEALSO:: :meth:`FiniteLatticePosets.ParentMethods.is_lattice_morphism`
188
+ """
189
+ image = {f(x) for x in self}
190
+ if len(image) != self.cardinality():
191
+ # Not injective
192
+ return False
193
+ if len(image) != codomain.cardinality():
194
+ # Not surjective
195
+ return False
196
+ for x in self:
197
+ if {f(y) for y in self.upper_covers(x)} != set(codomain.upper_covers(f(x))):
198
+ return False
199
+ return True
200
+
201
+ def is_poset_morphism(self, f, codomain):
202
+ r"""
203
+ Return whether `f` is a morphism of posets from ``self``
204
+ to ``codomain``, that is
205
+
206
+ .. MATH::
207
+
208
+ x\leq y \Longrightarrow f(x) \leq f(y)
209
+
210
+ for all `x` and `y` in ``self``.
211
+
212
+ INPUT:
213
+
214
+ - ``f`` -- a function from ``self`` to ``codomain``
215
+ - ``codomain`` -- a poset
216
+
217
+ EXAMPLES:
218
+
219
+ We build the boolean lattice of the subsets of
220
+ `\{2,3,5,6\}` and the lattice of divisors of `30`, and
221
+ check that the map `b \mapsto \gcd(\prod_{x\in b} x, 30)`
222
+ is a morphism of posets::
223
+
224
+ sage: D = Poset((divisors(30), attrcall("divides")))
225
+ sage: B = Poset(([frozenset(s) for s in Subsets([2,3,5,6])],
226
+ ....: attrcall("issubset")))
227
+ sage: def f(b): return D(gcd(prod(b), 30))
228
+ sage: B.is_poset_morphism(f, D)
229
+ True
230
+
231
+ .. NOTE:: since ``D`` and ``B`` are not facade posets, ``f`` is responsible
232
+ for the conversions between integers and subsets to elements of
233
+ ``D`` and ``B`` and back.
234
+
235
+ `f` is also a morphism of posets to the chain of divisors
236
+ of 30, ordered by usual comparison::
237
+
238
+ sage: P = Poset((divisors(30), operator.le))
239
+ sage: def f(b): return P(gcd(prod(b), 30))
240
+ sage: B.is_poset_morphism(f, P)
241
+ True
242
+
243
+ FIXME: should this be ``is_order_preserving_morphism``?
244
+
245
+ .. SEEALSO:: :meth:`is_poset_isomorphism`
246
+
247
+ TESTS:
248
+
249
+ Base cases::
250
+
251
+ sage: P = posets.ChainPoset(2)
252
+ sage: Q = posets.AntichainPoset(2)
253
+ sage: f = lambda x: 1-x
254
+ sage: P.is_poset_morphism(f, P)
255
+ False
256
+ sage: P.is_poset_morphism(f, Q)
257
+ False
258
+ sage: Q.is_poset_morphism(f, Q)
259
+ True
260
+ sage: Q.is_poset_morphism(f, P)
261
+ True
262
+
263
+ sage: P = Poset(); P
264
+ Finite poset containing 0 elements
265
+ sage: P.is_poset_morphism(f, P)
266
+ True
267
+ """
268
+ for x in self:
269
+ for y in self.upper_covers(x):
270
+ if not codomain.is_lequal(f(x),f(y)):
271
+ return False
272
+ return True
273
+
274
+ ##########################################################################
275
+ # About order ideals, order filters and the like
276
+
277
+ def order_ideal_generators(self, ideal, direction='down'):
278
+ r"""
279
+ Return the antichain of (minimal) generators of the order
280
+ ideal (resp. order filter) ``ideal``.
281
+
282
+ INPUT:
283
+
284
+ - ``ideal`` -- an order ideal `I` (resp. order filter)
285
+ of ``self``, as a list (or iterable); this should be
286
+ an order ideal if ``direction`` is set to ``'down'``,
287
+ and an order filter if ``direction`` is set to
288
+ ``'up'``
289
+ - ``direction`` -- ``'up'`` or ``'down'`` (default:
290
+ ``'down'``)
291
+
292
+ The antichain of (minimal) generators of an order ideal
293
+ `I` in a poset `P` is the set of all minimal elements of
294
+ `P`. In the case of an order filter, the definition is
295
+ similar, but with "maximal" used instead of "minimal".
296
+
297
+ EXAMPLES:
298
+
299
+ We build the boolean lattice of all subsets of `\{1,2,3\}`
300
+ ordered by inclusion, and compute an order ideal there::
301
+
302
+ sage: P = Poset((Subsets([1,2,3]), attrcall("issubset")))
303
+ sage: I = P.order_ideal([Set([1,2]), Set([2,3]), Set([1])])
304
+ sage: sorted(sorted(p) for p in I)
305
+ [[], [1], [1, 2], [2], [2, 3], [3]]
306
+
307
+ Then, we retrieve the generators of this ideal::
308
+
309
+ sage: gen = P.order_ideal_generators(I)
310
+ sage: sorted(sorted(p) for p in gen)
311
+ [[1, 2], [2, 3]]
312
+
313
+ If ``direction`` is ``'up'``, then this instead computes
314
+ the minimal generators for an order filter::
315
+
316
+ sage: I = P.order_filter([Set([1,2]), Set([2,3]), Set([1])])
317
+ sage: sorted(sorted(p) for p in I)
318
+ [[1], [1, 2], [1, 2, 3], [1, 3], [2, 3]]
319
+ sage: gen = P.order_ideal_generators(I, direction='up')
320
+ sage: sorted(sorted(p) for p in gen)
321
+ [[1], [2, 3]]
322
+
323
+ Complexity: `O(n+m)` where `n` is the cardinality of `I`,
324
+ and `m` the number of upper covers of elements of `I`.
325
+ """
326
+ if direction == 'down':
327
+ covers = self.upper_covers
328
+ else:
329
+ covers = self.lower_covers
330
+ ideal_as_set = set(ideal)
331
+ from sage.sets.set import Set
332
+ return Set(x for x in ideal if all(y not in ideal_as_set
333
+ for y in covers(x)))
334
+
335
+ def order_filter_generators(self, filter):
336
+ r"""
337
+ Generators for an order filter.
338
+
339
+ INPUT:
340
+
341
+ - ``filter`` -- an order filter of ``self``, as a list (or iterable)
342
+
343
+ EXAMPLES::
344
+
345
+ sage: P = Poset((Subsets([1,2,3]), attrcall("issubset")))
346
+ sage: I = P.order_filter([Set([1,2]), Set([2,3]), Set([1])])
347
+ sage: sorted(sorted(p) for p in I)
348
+ [[1], [1, 2], [1, 2, 3], [1, 3], [2, 3]]
349
+ sage: gen = P.order_filter_generators(I)
350
+ sage: sorted(sorted(p) for p in gen)
351
+ [[1], [2, 3]]
352
+
353
+ .. SEEALSO:: :meth:`order_ideal_generators`
354
+ """
355
+ return self.order_ideal_generators(filter, direction='up')
356
+
357
+ def order_ideal_complement_generators(self, antichain, direction='up'):
358
+ r"""
359
+ Return the Panyushev complement of the antichain
360
+ ``antichain``.
361
+
362
+ Given an antichain `A` of a poset `P`, the Panyushev
363
+ complement of `A` is defined to be the antichain consisting
364
+ of the minimal elements of the order filter `B`, where `B`
365
+ is the (set-theoretic) complement of the order ideal of
366
+ `P` generated by `A`.
367
+
368
+ Setting the optional keyword variable ``direction`` to
369
+ ``'down'`` leads to the inverse Panyushev complement being
370
+ computed instead of the Panyushev complement. The inverse
371
+ Panyushev complement of an antichain `A` is the antichain
372
+ whose Panyushev complement is `A`. It can be found as the
373
+ antichain consisting of the maximal elements of the order
374
+ ideal `C`, where `C` is the (set-theoretic) complement of
375
+ the order filter of `P` generated by `A`.
376
+
377
+ :meth:`panyushev_complement` is an alias for this method.
378
+
379
+ Panyushev complementation is related (actually, isomorphic)
380
+ to rowmotion (:meth:`rowmotion`).
381
+
382
+ INPUT:
383
+
384
+ - ``antichain`` -- an antichain of ``self``, as a list (or
385
+ iterable), or, more generally, generators of an order ideal
386
+ (resp. order filter)
387
+ - ``direction`` -- ``'up'`` or ``'down'`` (default: ``'up'``)
388
+
389
+ OUTPUT:
390
+
391
+ - the generating antichain of the complement order filter
392
+ (resp. order ideal) of the order ideal (resp. order filter)
393
+ generated by the antichain ``antichain``
394
+
395
+ EXAMPLES::
396
+
397
+ sage: P = Poset( ( [1,2,3], [ [1,3], [2,3] ] ) )
398
+ sage: P.order_ideal_complement_generators([1])
399
+ {2}
400
+ sage: P.order_ideal_complement_generators([3])
401
+ set()
402
+ sage: P.order_ideal_complement_generators([1,2])
403
+ {3}
404
+ sage: P.order_ideal_complement_generators([1,2,3])
405
+ set()
406
+
407
+ sage: P.order_ideal_complement_generators([1], direction='down')
408
+ {2}
409
+ sage: P.order_ideal_complement_generators([3], direction='down')
410
+ {1, 2}
411
+ sage: P.order_ideal_complement_generators([1,2], direction='down')
412
+ set()
413
+ sage: P.order_ideal_complement_generators([1,2,3], direction='down')
414
+ set()
415
+
416
+ .. WARNING::
417
+
418
+ This is a brute force implementation, building the
419
+ order ideal generated by the antichain, and searching
420
+ for order filter generators of its complement
421
+ """
422
+ if direction == 'up':
423
+ I = self.order_ideal(antichain)
424
+ else:
425
+ I = self.order_filter(antichain)
426
+ I_comp = set(self).difference(I)
427
+ return set(self.order_ideal_generators(I_comp, direction=direction))
428
+
429
+ panyushev_complement = order_ideal_complement_generators
430
+
431
+ def rowmotion(self, order_ideal):
432
+ r"""
433
+ The image of the order ideal ``order_ideal`` under rowmotion
434
+ in ``self``.
435
+
436
+ Rowmotion on a finite poset `P` is an automorphism of the set
437
+ `J(P)` of all order ideals of `P`. One way to define it is as
438
+ follows: Given an order ideal `I \in J(P)`, we let `F` be the
439
+ set-theoretic complement of `I` in `P`. Furthermore we let
440
+ `A` be the antichain consisting of all minimal elements of
441
+ `F`. Then, the rowmotion of `I` is defined to be the order
442
+ ideal of `P` generated by the antichain `A` (that is, the
443
+ order ideal consisting of each element of `P` which has some
444
+ element of `A` above it).
445
+
446
+ Rowmotion is related (actually, isomorphic) to Panyushev
447
+ complementation (:meth:`panyushev_complement`).
448
+
449
+ INPUT:
450
+
451
+ - ``order_ideal`` -- an order ideal of ``self``, as a set
452
+
453
+ OUTPUT: the image of ``order_ideal`` under rowmotion, as a set again
454
+
455
+ EXAMPLES::
456
+
457
+ sage: P = Poset( {1: [2, 3], 2: [], 3: [], 4: [8],
458
+ ....: 5: [], 6: [5], 7: [1, 4], 8: []} )
459
+ sage: I = Set({2, 6, 1, 7})
460
+ sage: P.rowmotion(I)
461
+ {1, 3, 4, 5, 6, 7}
462
+
463
+ sage: P = Poset( {} )
464
+ sage: I = Set({})
465
+ sage: P.rowmotion(I)
466
+ {}
467
+ """
468
+ result = order_ideal
469
+ for i in reversed(self.linear_extension()):
470
+ result = self.order_ideal_toggle(result, i)
471
+ return result
472
+
473
+ def birational_free_labelling(self, linear_extension=None,
474
+ prefix='x', base_field=None,
475
+ reduced=False, addvars=None,
476
+ labels=None,
477
+ min_label=None,
478
+ max_label=None):
479
+ r"""
480
+ Return the birational free labelling of ``self``.
481
+
482
+ Let us hold back defining this, and introduce birational
483
+ toggles and birational rowmotion first. These notions have
484
+ been introduced in [EP2013]_ as generalizations of the notions
485
+ of toggles (:meth:`~sage.categories.posets.Posets.ParentMethods.order_ideal_toggle`)
486
+ and :meth:`rowmotion <rowmotion>` on order ideals of a finite poset. They
487
+ have been studied further in [GR2013]_.
488
+
489
+ Let `\mathbf{K}` be a field, and `P` be a finite poset. Let
490
+ `\widehat{P}` denote the poset obtained from `P` by adding a
491
+ new element `1` which is greater than all existing elements
492
+ of `P`, and a new element `0` which is smaller than all
493
+ existing elements of `P` and `1`. Now, a `\mathbf{K}`-*labelling
494
+ of* `P` will mean any function from `\widehat{P}` to `\mathbf{K}`.
495
+ The image of an element `v` of `\widehat{P}` under this labelling
496
+ will be called the *label* of this labelling at `v`. The set
497
+ of all `\mathbf{K}`-labellings of `P` is clearly
498
+ `\mathbf{K}^{\widehat{P}}`.
499
+
500
+ For any `v \in P`, we now define a rational map
501
+ `T_v : \mathbf{K}^{\widehat{P}} \dashrightarrow
502
+ \mathbf{K}^{\widehat{P}}` as follows: For every `f \in
503
+ \mathbf{K}^{\widehat{P}}`, the image `T_v f` should send every
504
+ element `u \in \widehat{P}` distinct from `v` to `f(u)` (so the
505
+ labels at all `u \neq v` don't change), while `v` is sent to
506
+
507
+ .. MATH::
508
+
509
+ \frac{1}{f(v)} \cdot
510
+ \frac{\sum_{u \lessdot v} f(u)}
511
+ {\sum_{u \gtrdot v} \frac{1}{f(u)}}
512
+
513
+ (both sums are over all `u \in \widehat{P}` satisfying the
514
+ respectively given conditions). Here, `\lessdot` and `\gtrdot`
515
+ mean (respectively) "covered by" and "covers", interpreted with
516
+ respect to the poset `\widehat{P}`. This rational map `T_v`
517
+ is an involution and is called the *(birational)* `v`-*toggle*; see
518
+ :meth:`birational_toggle` for its implementation.
519
+
520
+ Now, *birational rowmotion* is defined as the composition
521
+ `T_{v_1} \circ T_{v_2} \circ \cdots \circ T_{v_n}`, where
522
+ `(v_1, v_2, \ldots, v_n)` is a linear extension of `P`
523
+ (written as a linear ordering of the elements of `P`). This
524
+ is a rational map
525
+ `\mathbf{K}^{\widehat{P}} \dashrightarrow \mathbf{K}^{\widehat{P}}`
526
+ which does not depend on the choice of the linear extension;
527
+ it is denoted by `R`. See :meth:`birational_rowmotion` for
528
+ its implementation.
529
+
530
+ The definitions of birational toggles and birational
531
+ rowmotion extend to the case of `\mathbf{K}` being any semifield
532
+ rather than necessarily a field (although it becomes less
533
+ clear what constitutes a rational map in this generality).
534
+ The most useful case is that of the :class:`tropical semiring
535
+ <sage.rings.semirings.tropical_semiring.TropicalSemiring>`,
536
+ in which case birational rowmotion relates to classical
537
+ constructions such as promotion of rectangular semistandard
538
+ Young tableaux (page 5 of [EP2013b]_ and future work, via the
539
+ related notion of birational *promotion*) and rowmotion on
540
+ order ideals of the poset ([EP2013]_).
541
+
542
+ The *birational free labelling* is a special labelling
543
+ defined for every finite poset `P` and every linear extension
544
+ `(v_1, v_2, \ldots, v_n)` of `P`. It is given by sending
545
+ every element `v_i` in `P` to `x_i`, sending the element `0`
546
+ of `\widehat{P}` to `a`, and sending the element `1` of
547
+ `\widehat{P}` to `b`, where the ground field `\mathbf{K}` is the
548
+ field of rational functions in `n+2` indeterminates
549
+ `a, x_1, x_2, \ldots, x_n, b` over `\mathbb Q`.
550
+
551
+ In Sage, a labelling `f` of a poset `P` is encoded as a
552
+ `4`-tuple `(\mathbf{K}, d, u, v)`, where `\mathbf{K}` is the
553
+ ground field of the labelling (i. e., its target), `d` is the
554
+ dictionary containing the values of `f` at the elements of
555
+ `P` (the keys being the respective elements of `P`), `u`
556
+ is the label of `f` at `0`, and `v` is the label of `f` at
557
+ `1`.
558
+
559
+ .. WARNING::
560
+
561
+ The dictionary `d` is labelled by the elements of `P`.
562
+ If `P` is a poset with ``facade`` option set to
563
+ ``False``, these might not be what they seem to be!
564
+ (For instance, if
565
+ ``P == Poset({1: [2, 3]}, facade=False)``, then the
566
+ value of `d` at `1` has to be accessed by ``d[P(1)]``, not
567
+ by ``d[1]``.)
568
+
569
+ .. WARNING::
570
+
571
+ Dictionaries are mutable. They do compare correctly,
572
+ but are not hashable and need to be cloned to avoid
573
+ spooky action at a distance. Be careful!
574
+
575
+ INPUT:
576
+
577
+ - ``linear_extension`` -- (default: the default linear
578
+ extension of ``self``) a linear extension of ``self``
579
+ (as a linear extension or as a list), or more generally
580
+ a list of all elements of all elements of ``self`` each
581
+ occurring exactly once
582
+
583
+ - ``prefix`` -- (default: ``'x'``) the prefix to name
584
+ the indeterminates corresponding to the elements of
585
+ ``self`` in the labelling (so, setting it to
586
+ ``'frog'`` will result in these indeterminates being
587
+ called ``frog1, frog2, ..., frogn`` rather than
588
+ ``x1, x2, ..., xn``).
589
+
590
+ - ``base_field`` -- (default: ``QQ``) the base field to
591
+ be used instead of `\QQ` to define the rational
592
+ function field over; this is not going to be the base
593
+ field of the labelling, because the latter will have
594
+ indeterminates adjoined!
595
+
596
+ - ``reduced`` -- boolean (default: ``False``); if set to
597
+ ``True``, the result will be the *reduced* birational
598
+ free labelling, which differs from the regular one by
599
+ having `0` and `1` both sent to `1` instead of `a` and
600
+ `b` (the indeterminates `a` and `b` then also won't
601
+ appear in the ground field)
602
+
603
+ - ``addvars`` -- (default: ``''``) a string containing
604
+ names of extra variables to be adjoined to the ground
605
+ field (these don't have an effect on the labels)
606
+
607
+ - ``labels`` -- (default: ``'x'``) either a function
608
+ that takes an element of the poset and returns a name
609
+ for the indeterminate corresponding to that element,
610
+ or a string containing a comma-separated list of
611
+ indeterminates that will be assigned to elements in
612
+ the order of ``linear_extension``. If the
613
+ list contains more indeterminates than needed, the
614
+ excess will be ignored. If it contains too few, then
615
+ the needed indeterminates will be constructed from
616
+ ``prefix``.
617
+
618
+ - ``min_label`` -- (default: ``'a'``) a string to be
619
+ used as the label for the element `0` of `\widehat{P}`
620
+
621
+ - ``max_label`` -- (default: ``'b'``) a string to be
622
+ used as the label for the element `1` of `\widehat{P}`
623
+
624
+ OUTPUT:
625
+
626
+ The birational free labelling of the poset ``self`` and the
627
+ linear extension ``linear_extension``. Or, if ``reduced``
628
+ is set to ``True``, the reduced birational free labelling.
629
+
630
+ EXAMPLES:
631
+
632
+ We construct the birational free labelling on a simple
633
+ poset::
634
+
635
+ sage: P = Poset({1: [2, 3]})
636
+ sage: l = P.birational_free_labelling(); l
637
+ (Fraction Field of Multivariate Polynomial Ring
638
+ in a, x1, x2, x3, b over Rational Field,
639
+ {...},
640
+ a,
641
+ b)
642
+ sage: sorted(l[1].items())
643
+ [(1, x1), (2, x2), (3, x3)]
644
+
645
+ sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2]); l
646
+ (Fraction Field of Multivariate Polynomial Ring
647
+ in a, x1, x2, x3, b over Rational Field,
648
+ {...},
649
+ a,
650
+ b)
651
+ sage: sorted(l[1].items())
652
+ [(1, x1), (2, x3), (3, x2)]
653
+
654
+ sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2],
655
+ ....: reduced=True, addvars="spam, eggs"); l
656
+ (Fraction Field of Multivariate Polynomial Ring
657
+ in x1, x2, x3, spam, eggs over Rational Field,
658
+ {...},
659
+ 1,
660
+ 1)
661
+ sage: sorted(l[1].items())
662
+ [(1, x1), (2, x3), (3, x2)]
663
+
664
+ sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2],
665
+ ....: prefix='wut', reduced=True,
666
+ ....: addvars="spam, eggs"); l
667
+ (Fraction Field of Multivariate Polynomial Ring
668
+ in wut1, wut2, wut3, spam, eggs over Rational Field,
669
+ {...},
670
+ 1,
671
+ 1)
672
+ sage: sorted(l[1].items())
673
+ [(1, wut1), (2, wut3), (3, wut2)]
674
+
675
+ sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2],
676
+ ....: reduced=False, addvars="spam, eggs"); l
677
+ (Fraction Field of Multivariate Polynomial Ring
678
+ in a, x1, x2, x3, b, spam, eggs over Rational Field,
679
+ {...},
680
+ a,
681
+ b)
682
+ sage: sorted(l[1].items())
683
+ [(1, x1), (2, x3), (3, x2)]
684
+ sage: l[1][2]
685
+ x3
686
+
687
+ Illustrating labelling with a function::
688
+
689
+ sage: P = posets.ChainPoset(2).product(posets.ChainPoset(2)) # needs sage.modules
690
+ sage: def x_label(e):
691
+ ....: return 'x_' + str(e[0]) + str(e[1])
692
+ sage: l = P.birational_free_labelling(labels=x_label)
693
+ sage: sorted(l[1].items())
694
+ [((0, 0), x_00), ((0, 1), x_01), ((1, 0), x_10), ((1, 1), x_11)]
695
+ sage: l[2]
696
+ a
697
+
698
+ The same, but with ``min_label`` and ``max_label`` provided::
699
+
700
+ sage: P = posets.ChainPoset(2).product(posets.ChainPoset(2)) # needs sage.modules
701
+ sage: l = P.birational_free_labelling(labels=x_label,
702
+ ....: min_label='lambda', max_label='mu')
703
+ sage: sorted(l[1].items())
704
+ [((0, 0), x_00), ((0, 1), x_01), ((1, 0), x_10), ((1, 1), x_11)]
705
+ sage: l[2]
706
+ lambda
707
+ sage: l[3]
708
+ mu
709
+
710
+ Illustrating labelling with a comma separated list of labels::
711
+
712
+ sage: l = P.birational_free_labelling(labels='w,x,y,z')
713
+ sage: sorted(l[1].items())
714
+ [((0, 0), w), ((0, 1), x), ((1, 0), y), ((1, 1), z)]
715
+ sage: l = P.birational_free_labelling(labels='w,x,y,z,m')
716
+ sage: sorted(l[1].items())
717
+ [((0, 0), w), ((0, 1), x), ((1, 0), y), ((1, 1), z)]
718
+ sage: l = P.birational_free_labelling(labels='w')
719
+ sage: sorted(l[1].items())
720
+ [((0, 0), w), ((0, 1), x1), ((1, 0), x2), ((1, 1), x3)]
721
+
722
+ Illustrating the warning about facade::
723
+
724
+ sage: P = Poset({1: [2, 3]}, facade=False)
725
+ sage: l = P.birational_free_labelling(linear_extension=[1, 3, 2],
726
+ ....: reduced=False,
727
+ ....: addvars="spam, eggs"); l
728
+ (Fraction Field of Multivariate Polynomial Ring
729
+ in a, x1, x2, x3, b, spam, eggs over Rational Field,
730
+ {...},
731
+ a,
732
+ b)
733
+ sage: l[1][2]
734
+ Traceback (most recent call last):
735
+ ...
736
+ KeyError: 2
737
+ sage: l[1][P(2)]
738
+ x3
739
+
740
+ Another poset::
741
+
742
+ sage: # needs sage.modules
743
+ sage: P = posets.SSTPoset([2,1])
744
+ sage: lext = sorted(P)
745
+ sage: l = P.birational_free_labelling(linear_extension=lext,
746
+ ....: addvars='ohai'); l
747
+ (Fraction Field of Multivariate Polynomial Ring
748
+ in a, x1, x2, x3, x4, x5, x6, x7, x8, b, ohai over Rational Field,
749
+ {...},
750
+ a,
751
+ b)
752
+ sage: sorted(l[1].items())
753
+ [([[1, 1], [2]], x1), ([[1, 1], [3]], x2),
754
+ ([[1, 2], [2]], x3), ([[1, 2], [3]], x4),
755
+ ([[1, 3], [2]], x5), ([[1, 3], [3]], x6),
756
+ ([[2, 2], [3]], x7), ([[2, 3], [3]], x8)]
757
+
758
+ See :meth:`birational_rowmotion`, :meth:`birational_toggle` and
759
+ :meth:`birational_toggles` for more substantial examples of what
760
+ one can do with the birational free labelling.
761
+
762
+ TESTS:
763
+
764
+ The ``linear_extension`` keyword does not have to be given an
765
+ actual linear extension::
766
+
767
+ sage: # needs sage.modules
768
+ sage: P = posets.ChainPoset(2).product(posets.ChainPoset(3)); P
769
+ Finite lattice containing 6 elements
770
+ sage: lex = [(1,0),(0,0),(1,1),(0,1),(1,2),(0,2)]
771
+ sage: l = P.birational_free_labelling(linear_extension=lex,
772
+ ....: prefix='u', reduced=True)
773
+ sage: l
774
+ (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field,
775
+ {...},
776
+ 1,
777
+ 1)
778
+ sage: sorted(l[1].items())
779
+ [((0, 0), u2),
780
+ ((0, 1), u4),
781
+ ((0, 2), u6),
782
+ ((1, 0), u1),
783
+ ((1, 1), u3),
784
+ ((1, 2), u5)]
785
+
786
+ For comparison, the standard linear extension::
787
+
788
+ sage: # needs sage.modules
789
+ sage: l = P.birational_free_labelling(prefix='u', reduced=True); l
790
+ (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field,
791
+ {...},
792
+ 1,
793
+ 1)
794
+ sage: sorted(l[1].items())
795
+ [((0, 0), u1),
796
+ ((0, 1), u2),
797
+ ((0, 2), u3),
798
+ ((1, 0), u4),
799
+ ((1, 1), u5),
800
+ ((1, 2), u6)]
801
+
802
+ If you want your linear extension to be tested for being a
803
+ linear extension, just call the ``linear_extension`` method
804
+ on the poset::
805
+
806
+ sage: # needs sage.modules
807
+ sage: lex = [(0,0),(0,1),(1,0),(1,1),(0,2),(1,2)]
808
+ sage: l = P.birational_free_labelling(linear_extension=P.linear_extension(lex),
809
+ ....: prefix='u', reduced=True)
810
+ sage: l
811
+ (Fraction Field of Multivariate Polynomial Ring in u1, u2, u3, u4, u5, u6 over Rational Field,
812
+ {...},
813
+ 1,
814
+ 1)
815
+ sage: sorted(l[1].items())
816
+ [((0, 0), u1),
817
+ ((0, 1), u2),
818
+ ((0, 2), u5),
819
+ ((1, 0), u3),
820
+ ((1, 1), u4),
821
+ ((1, 2), u6)]
822
+
823
+ Nonstandard base field::
824
+
825
+ sage: P = Poset({1: [3], 2: [3,4]})
826
+ sage: lex = [1, 2, 4, 3]
827
+ sage: l = P.birational_free_labelling(linear_extension=lex,
828
+ ....: prefix='aaa',
829
+ ....: base_field=Zmod(13))
830
+ sage: l
831
+ (Fraction Field of Multivariate Polynomial Ring in a, aaa1, aaa2, aaa3, aaa4, b over Ring of integers modulo 13,
832
+ {...},
833
+ a,
834
+ b)
835
+ sage: l[1][4]
836
+ aaa3
837
+
838
+ The empty poset::
839
+
840
+ sage: P = Poset({})
841
+ sage: P.birational_free_labelling(reduced=False, addvars="spam, eggs")
842
+ (Fraction Field of Multivariate Polynomial Ring in a, b, spam, eggs over Rational Field,
843
+ {},
844
+ a,
845
+ b)
846
+ sage: P.birational_free_labelling(reduced=True, addvars="spam, eggs")
847
+ (Fraction Field of Multivariate Polynomial Ring in spam, eggs over Rational Field,
848
+ {},
849
+ 1,
850
+ 1)
851
+ sage: P.birational_free_labelling(reduced=True)
852
+ (Multivariate Polynomial Ring in no variables over Rational Field,
853
+ {},
854
+ 1,
855
+ 1)
856
+ sage: P.birational_free_labelling(prefix='zzz')
857
+ (Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field,
858
+ {},
859
+ a,
860
+ b)
861
+ sage: P.birational_free_labelling(labels='x,y,z', min_label='spam', max_label='eggs')
862
+ (Fraction Field of Multivariate Polynomial Ring in spam, eggs over Rational Field,
863
+ {},
864
+ spam,
865
+ eggs)
866
+ """
867
+ if base_field is None:
868
+ from sage.rings.rational_field import QQ
869
+ base_field = QQ
870
+ if linear_extension is None:
871
+ linear_extension = self.linear_extension()
872
+ n = self.cardinality()
873
+ label_list = []
874
+ if labels:
875
+ if callable(labels):
876
+ label_list = [labels(e) for e in linear_extension]
877
+ else:
878
+ label_list = labels.split(',')
879
+ if len(label_list) > n:
880
+ label_list = label_list[:n]
881
+ elif len(label_list) < n:
882
+ label_list += [prefix + str(i) for i in range(1, n + 1 - len(label_list))]
883
+ else:
884
+ label_list = [prefix + str(i) for i in range(1, n + 1)]
885
+ if not reduced:
886
+ if min_label is None:
887
+ min_label = 'a'
888
+ if max_label is None:
889
+ max_label = 'b'
890
+ label_list = [min_label] + label_list + [max_label]
891
+ if addvars:
892
+ label_list += addvars.split(',')
893
+ varstring = ','.join(label_list)
894
+ varnum = len(label_list)
895
+
896
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
897
+ PR = PolynomialRing(base_field, varstring, varnum)
898
+ # Now, ``PR`` is the polynomial ring in `n + 2` indeterminates
899
+ # (or more, if ``addvars`` was set; or less, if ``reduced`` is
900
+ # ``True``) over ``base_field``.
901
+ # The first `n + 2` of these indeterminates are named
902
+ # ``a, x1, x2, ..., xn, b`` (if ``reduced`` is ``False``).
903
+ # These will label the vertices of `\widehat{P}`.
904
+ if reduced:
905
+ xs = tuple(PR.gens()[: n])
906
+ else:
907
+ xs = tuple(PR.gens()[1 : n + 1])
908
+ # So ``xs`` is the list ``[x1, x2, ..., xn]``.
909
+ if not reduced:
910
+ a = PR.gens()[0]
911
+ b = PR.gens()[n + 1]
912
+ else:
913
+ a = PR.one()
914
+ b = PR.one()
915
+ # So ``a`` and ``b`` are the labels at `0` and `1`.
916
+ FF = PR.fraction_field()
917
+ # ``FF`` is the field of rational functions.
918
+ dct = {self(p): xs[i] for (i, p) in enumerate(linear_extension)}
919
+ return (FF, dct, a, b)
920
+
921
+ def birational_toggle(self, v, labelling):
922
+ r"""
923
+ Return the result of applying the birational `v`-toggle `T_v`
924
+ to the `\mathbf{K}`-labelling ``labelling`` of the poset ``self``.
925
+
926
+ See the documentation of :meth:`birational_free_labelling`
927
+ for a definition of this toggle and of `\mathbf{K}`-labellings as
928
+ well as an explanation of how `\mathbf{K}`-labellings are to be
929
+ encoded to be understood by Sage. This implementation allows
930
+ `\mathbf{K}` to be a semifield, not just a field. The birational
931
+ `v`-toggle is only a rational map, so an exception (most
932
+ likely, :exc:`ZeroDivisionError`) will be thrown if the
933
+ denominator is zero.
934
+
935
+ INPUT:
936
+
937
+ - ``v`` -- an element of ``self`` (must have ``self`` as
938
+ parent if ``self`` is a ``facade=False`` poset)
939
+
940
+ - ``labelling`` -- a `\mathbf{K}`-labelling of ``self`` in the
941
+ sense as defined in the documentation of
942
+ :meth:`birational_free_labelling`
943
+
944
+ OUTPUT:
945
+
946
+ The `\mathbf{K}`-labelling `T_v f` of ``self``, where `f` is
947
+ ``labelling``.
948
+
949
+ EXAMPLES:
950
+
951
+ Let us start with the birational free labelling of the
952
+ "V"-poset (the three-element poset with Hasse diagram looking
953
+ like a "V")::
954
+
955
+ sage: V = Poset({1: [2, 3]})
956
+ sage: s = V.birational_free_labelling(); s
957
+ (Fraction Field of Multivariate Polynomial Ring
958
+ in a, x1, x2, x3, b over Rational Field,
959
+ {...},
960
+ a,
961
+ b)
962
+ sage: sorted(s[1].items())
963
+ [(1, x1), (2, x2), (3, x3)]
964
+
965
+ The image of `s` under the `1`-toggle `T_1` is::
966
+
967
+ sage: s1 = V.birational_toggle(1, s); s1
968
+ (Fraction Field of Multivariate Polynomial Ring
969
+ in a, x1, x2, x3, b over Rational Field,
970
+ {...},
971
+ a,
972
+ b)
973
+ sage: sorted(s1[1].items())
974
+ [(1, a*x2*x3/(x1*x2 + x1*x3)), (2, x2), (3, x3)]
975
+
976
+ Now let us apply the `2`-toggle `T_2` (to the old ``s``)::
977
+
978
+ sage: s2 = V.birational_toggle(2, s); s2
979
+ (Fraction Field of Multivariate Polynomial Ring
980
+ in a, x1, x2, x3, b over Rational Field,
981
+ {...},
982
+ a,
983
+ b)
984
+ sage: sorted(s2[1].items())
985
+ [(1, x1), (2, x1*b/x2), (3, x3)]
986
+
987
+ On the other hand, we can also apply `T_2` to the image of `s`
988
+ under `T_1`::
989
+
990
+ sage: s12 = V.birational_toggle(2, s1); s12
991
+ (Fraction Field of Multivariate Polynomial Ring
992
+ in a, x1, x2, x3, b over Rational Field,
993
+ {...},
994
+ a,
995
+ b)
996
+ sage: sorted(s12[1].items())
997
+ [(1, a*x2*x3/(x1*x2 + x1*x3)), (2, a*x3*b/(x1*x2 + x1*x3)), (3, x3)]
998
+
999
+ Each toggle is an involution::
1000
+
1001
+ sage: all( V.birational_toggle(i, V.birational_toggle(i, s)) == s
1002
+ ....: for i in V )
1003
+ True
1004
+
1005
+ We can also start with a less generic labelling::
1006
+
1007
+ sage: t = (QQ, {1: 3, 2: 6, 3: 7}, 2, 10)
1008
+ sage: t1 = V.birational_toggle(1, t); t1
1009
+ (Rational Field, {...}, 2, 10)
1010
+ sage: sorted(t1[1].items())
1011
+ [(1, 28/13), (2, 6), (3, 7)]
1012
+ sage: t13 = V.birational_toggle(3, t1); t13
1013
+ (Rational Field, {...}, 2, 10)
1014
+ sage: sorted(t13[1].items())
1015
+ [(1, 28/13), (2, 6), (3, 40/13)]
1016
+
1017
+ However, labellings have to be sufficiently generic, lest
1018
+ denominators vanish::
1019
+
1020
+ sage: t = (QQ, {1: 3, 2: 5, 3: -5}, 1, 15)
1021
+ sage: t1 = V.birational_toggle(1, t)
1022
+ Traceback (most recent call last):
1023
+ ...
1024
+ ZeroDivisionError: rational division by zero
1025
+
1026
+ We don't get into zero-division issues in the tropical
1027
+ semiring (unless the zero of the tropical semiring appears
1028
+ in the labelling)::
1029
+
1030
+ sage: TT = TropicalSemiring(QQ)
1031
+ sage: t = (TT, {1: TT(2), 2: TT(4), 3: TT(1)}, TT(6), TT(0))
1032
+ sage: t1 = V.birational_toggle(1, t); t1
1033
+ (Tropical semiring over Rational Field, {...}, 6, 0)
1034
+ sage: sorted(t1[1].items())
1035
+ [(1, 8), (2, 4), (3, 1)]
1036
+ sage: t12 = V.birational_toggle(2, t1); t12
1037
+ (Tropical semiring over Rational Field, {...}, 6, 0)
1038
+ sage: sorted(t12[1].items())
1039
+ [(1, 8), (2, 4), (3, 1)]
1040
+ sage: t123 = V.birational_toggle(3, t12); t123
1041
+ (Tropical semiring over Rational Field, {...}, 6, 0)
1042
+ sage: sorted(t123[1].items())
1043
+ [(1, 8), (2, 4), (3, 7)]
1044
+
1045
+ We turn to more interesting posets. Here is the `6`-element
1046
+ poset arising from the weak order on `S_3`::
1047
+
1048
+ sage: P = posets.SymmetricGroupWeakOrderPoset(3)
1049
+ sage: sorted(list(P))
1050
+ ['123', '132', '213', '231', '312', '321']
1051
+ sage: t = (TT, {'123': TT(4), '132': TT(2), '213': TT(3),
1052
+ ....: '231': TT(1), '321': TT(1), '312': TT(2)}, TT(7), TT(1))
1053
+ sage: t1 = P.birational_toggle('123', t); t1
1054
+ (Tropical semiring over Rational Field, {...}, 7, 1)
1055
+ sage: sorted(t1[1].items())
1056
+ [('123', 6), ('132', 2), ('213', 3), ('231', 1), ('312', 2), ('321', 1)]
1057
+ sage: t13 = P.birational_toggle('213', t1); t13
1058
+ (Tropical semiring over Rational Field, {...}, 7, 1)
1059
+ sage: sorted(t13[1].items())
1060
+ [('123', 6), ('132', 2), ('213', 4), ('231', 1), ('312', 2), ('321', 1)]
1061
+
1062
+ Let us verify on this example some basic properties of
1063
+ toggles. First of all, again let us check that `T_v` is an
1064
+ involution for every `v`::
1065
+
1066
+ sage: all( P.birational_toggle(v, P.birational_toggle(v, t)) == t
1067
+ ....: for v in P )
1068
+ True
1069
+
1070
+ Furthermore, two toggles `T_v` and `T_w` commute unless
1071
+ one of `v` or `w` covers the other::
1072
+
1073
+ sage: all( P.covers(v, w) or P.covers(w, v)
1074
+ ....: or P.birational_toggle(v, P.birational_toggle(w, t))
1075
+ ....: == P.birational_toggle(w, P.birational_toggle(v, t))
1076
+ ....: for v in P for w in P )
1077
+ True
1078
+
1079
+ TESTS:
1080
+
1081
+ Setting ``facade`` to ``False`` does not break
1082
+ ``birational_toggle``::
1083
+
1084
+ sage: P = Poset({'x': ['y', 'w'], 'y': ['z'], 'w': ['z']}, facade=False)
1085
+ sage: lex = ['x', 'y', 'w', 'z']
1086
+ sage: t = P.birational_free_labelling(linear_extension=lex)
1087
+ sage: all( P.birational_toggle(v, P.birational_toggle(v, t)) == t
1088
+ ....: for v in P )
1089
+ True
1090
+ sage: t4 = P.birational_toggle(P('z'), t); t4
1091
+ (Fraction Field of Multivariate Polynomial Ring
1092
+ in a, x1, x2, x3, x4, b over Rational Field,
1093
+ {...},
1094
+ a,
1095
+ b)
1096
+ sage: t4[1][P('x')]
1097
+ x1
1098
+ sage: t4[1][P('y')]
1099
+ x2
1100
+ sage: t4[1][P('w')]
1101
+ x3
1102
+ sage: t4[1][P('z')]
1103
+ (x2*b + x3*b)/x4
1104
+
1105
+ The one-element poset::
1106
+
1107
+ sage: P = Poset({8: []})
1108
+ sage: t = P.birational_free_labelling()
1109
+ sage: t8 = P.birational_toggle(8, t); t8
1110
+ (Fraction Field of Multivariate Polynomial Ring in a, x1, b over Rational Field,
1111
+ {...},
1112
+ a,
1113
+ b)
1114
+ sage: t8[1][8]
1115
+ a*b/x1
1116
+ """
1117
+ FF = labelling[0] # base field
1118
+ a = labelling[2] # label at `0 \in \widehat{P}`
1119
+ b = labelling[3]
1120
+ newdict = labelling[1].copy()
1121
+ # Construct the harmonic sum ``x`` of the labels at the
1122
+ # elements covering ``v``:
1123
+ uppers = self.upper_covers(v)
1124
+ if len(uppers) == 0:
1125
+ x = FF.one() / b
1126
+ else:
1127
+ x = FF.sum(FF.one() / newdict[j] for j in uppers)
1128
+ # ``FF.sum``, not ``sum``, see trac #15591.
1129
+ x = FF.one() / x
1130
+ # Construct the sum ``y`` of the labels at the elements
1131
+ # covered by ``v``:
1132
+ lowers = self.lower_covers(v)
1133
+ if len(lowers) == 0:
1134
+ y = a
1135
+ else:
1136
+ y = FF.sum(newdict[j] for j in lowers)
1137
+ # Now, transform the label at v:
1138
+ newdict[v] = x * y / newdict[v]
1139
+ return (FF, newdict, a, b)
1140
+
1141
+ def birational_toggles(self, vs, labelling):
1142
+ r"""
1143
+ Return the result of applying a sequence of birational
1144
+ toggles (specified by ``vs``) to the `\mathbf{K}`-labelling
1145
+ ``labelling`` of the poset ``self``.
1146
+
1147
+ See the documentation of :meth:`birational_free_labelling`
1148
+ for a definition of birational toggles and `\mathbf{K}`-labellings
1149
+ and for an explanation of how `\mathbf{K}`-labellings are to be
1150
+ encoded to be understood by Sage. This implementation allows
1151
+ `\mathbf{K}` to be a semifield, not just a field. The birational
1152
+ `v`-toggle is only a rational map, so an exception (most
1153
+ likely, :exc:`ZeroDivisionError`) will be thrown if the
1154
+ denominator is zero.
1155
+
1156
+ INPUT:
1157
+
1158
+ - ``vs`` -- an iterable comprising elements of ``self``
1159
+ (which must have ``self`` as parent if ``self`` is a
1160
+ ``facade=False`` poset)
1161
+
1162
+ - ``labelling`` -- a `\mathbf{K}`-labelling of ``self`` in the
1163
+ sense as defined in the documentation of
1164
+ :meth:`birational_free_labelling`
1165
+
1166
+ OUTPUT:
1167
+
1168
+ The `\mathbf{K}`-labelling `T_{v_n} T_{v_{n-1}} \cdots T_{v_1} f`
1169
+ of ``self``, where `f` is ``labelling`` and
1170
+ `(v_1, v_2, \ldots, v_n)` is ``vs`` (written as list).
1171
+
1172
+ EXAMPLES::
1173
+
1174
+ sage: P = posets.SymmetricGroupBruhatOrderPoset(3)
1175
+ sage: sorted(list(P))
1176
+ ['123', '132', '213', '231', '312', '321']
1177
+ sage: TT = TropicalSemiring(ZZ)
1178
+ sage: t = (TT, {'123': TT(4), '132': TT(2), '213': TT(3),
1179
+ ....: '231': TT(1), '321': TT(1), '312': TT(2)}, TT(7), TT(1))
1180
+ sage: tA = P.birational_toggles(['123', '231', '312'], t); tA
1181
+ (Tropical semiring over Integer Ring, {...}, 7, 1)
1182
+ sage: sorted(tA[1].items())
1183
+ [('123', 6), ('132', 2), ('213', 3), ('231', 2), ('312', 1), ('321', 1)]
1184
+ sage: tAB = P.birational_toggles(['132', '213', '321'], tA); tAB
1185
+ (Tropical semiring over Integer Ring, {...}, 7, 1)
1186
+ sage: sorted(tAB[1].items())
1187
+ [('123', 6), ('132', 6), ('213', 5), ('231', 2), ('312', 1), ('321', 1)]
1188
+
1189
+ sage: P = Poset({1: [2, 3], 2: [4], 3: [4]})
1190
+ sage: Qx = PolynomialRing(QQ, 'x').fraction_field()
1191
+ sage: x = Qx.gen()
1192
+ sage: t = (Qx, {1: 1, 2: x, 3: (x+1)/x, 4: x^2}, 1, 1)
1193
+ sage: t1 = P.birational_toggles((i for i in range(1, 5)), t); t1
1194
+ (Fraction Field of Univariate Polynomial Ring in x over Rational Field,
1195
+ {...},
1196
+ 1,
1197
+ 1)
1198
+ sage: sorted(t1[1].items())
1199
+ [(1, (x^2 + x)/(x^2 + x + 1)),
1200
+ (2, (x^3 + x^2)/(x^2 + x + 1)),
1201
+ (3, x^4/(x^2 + x + 1)), (4, 1)]
1202
+ sage: t2 = P.birational_toggles(reversed(range(1, 5)), t)
1203
+ sage: sorted(t2[1].items())
1204
+ [(1, 1/x^2), (2, (x^2 + x + 1)/x^4), (3, (x^2 + x + 1)/(x^3 + x^2)),
1205
+ (4, (x^2 + x + 1)/x^3)]
1206
+
1207
+ Facade set to ``False`` works::
1208
+
1209
+ sage: P = Poset({'x': ['y', 'w'], 'y': ['z'], 'w': ['z']}, facade=False)
1210
+ sage: lex = ['x', 'y', 'w', 'z']
1211
+ sage: t = P.birational_free_labelling(linear_extension=lex)
1212
+ sage: sorted(P.birational_toggles([P('x'), P('y')], t)[1].items())
1213
+ [(x, a*x2*x3/(x1*x2 + x1*x3)), (y, a*x3*x4/(x1*x2 + x1*x3)), (w, x3), (z, x4)]
1214
+ """
1215
+ l = labelling
1216
+ for v in vs:
1217
+ l = self.birational_toggle(v, l)
1218
+ return l
1219
+
1220
+ def birational_rowmotion(self, labelling):
1221
+ r"""
1222
+ Return the result of applying birational rowmotion to the
1223
+ `\mathbf{K}`-labelling ``labelling`` of the poset ``self``.
1224
+
1225
+ See the documentation of :meth:`birational_free_labelling`
1226
+ for a definition of birational rowmotion and
1227
+ `\mathbf{K}`-labellings and for an explanation of how
1228
+ `\mathbf{K}`-labellings are to be encoded to be understood
1229
+ by Sage. This implementation allows `\mathbf{K}` to be a
1230
+ semifield, not just a field. Birational rowmotion is only
1231
+ a rational map, so an exception (most likely,
1232
+ :exc:`ZeroDivisionError`) will be thrown if the
1233
+ denominator is zero.
1234
+
1235
+ INPUT:
1236
+
1237
+ - ``labelling`` -- a `\mathbf{K}`-labelling of ``self`` in the
1238
+ sense as defined in the documentation of
1239
+ :meth:`birational_free_labelling`
1240
+
1241
+ OUTPUT:
1242
+
1243
+ The image of the `\mathbf{K}`-labelling `f` under birational
1244
+ rowmotion.
1245
+
1246
+ EXAMPLES::
1247
+
1248
+ sage: P = Poset({1: [2, 3], 2: [4], 3: [4]})
1249
+ sage: lex = [1, 2, 3, 4]
1250
+ sage: t = P.birational_free_labelling(linear_extension=lex); t
1251
+ (Fraction Field of Multivariate Polynomial Ring in a, x1, x2, x3, x4, b over Rational Field,
1252
+ {...},
1253
+ a,
1254
+ b)
1255
+ sage: sorted(t[1].items())
1256
+ [(1, x1), (2, x2), (3, x3), (4, x4)]
1257
+ sage: t = P.birational_rowmotion(t); t
1258
+ (Fraction Field of Multivariate Polynomial Ring in a, x1, x2, x3, x4, b over Rational Field,
1259
+ {...},
1260
+ a,
1261
+ b)
1262
+ sage: sorted(t[1].items())
1263
+ [(1, a*b/x4), (2, (x1*x2*b + x1*x3*b)/(x2*x4)),
1264
+ (3, (x1*x2*b + x1*x3*b)/(x3*x4)), (4, (x2*b + x3*b)/x4)]
1265
+
1266
+ A result of [GR2013]_ states that applying birational rowmotion
1267
+ `n+m` times to a `\mathbf{K}`-labelling `f` of the poset
1268
+ `[n] \times [m]` gives back `f`. Let us check this::
1269
+
1270
+ sage: def test_rectangle_periodicity(n, m, k):
1271
+ ....: P = posets.ChainPoset(n).product(posets.ChainPoset(m))
1272
+ ....: t0 = P.birational_free_labelling(P)
1273
+ ....: t = t0
1274
+ ....: for i in range(k):
1275
+ ....: t = P.birational_rowmotion(t)
1276
+ ....: return t == t0
1277
+ sage: test_rectangle_periodicity(2, 2, 4) # needs sage.modules
1278
+ True
1279
+ sage: test_rectangle_periodicity(2, 2, 2) # needs sage.modules
1280
+ False
1281
+ sage: test_rectangle_periodicity(2, 3, 5) # long time # needs sage.modules
1282
+ True
1283
+
1284
+ While computations with the birational free labelling quickly
1285
+ run out of memory due to the complexity of the rational
1286
+ functions involved, it is computationally cheap to check
1287
+ properties of birational rowmotion on examples in the tropical
1288
+ semiring::
1289
+
1290
+ sage: def test_rectangle_periodicity_tropical(n, m, k):
1291
+ ....: P = posets.ChainPoset(n).product(posets.ChainPoset(m))
1292
+ ....: TT = TropicalSemiring(ZZ)
1293
+ ....: t0 = (TT, {v: TT(randint(0, 99)) for v in P}, TT(0), TT(124))
1294
+ ....: t = t0
1295
+ ....: for i in range(k):
1296
+ ....: t = P.birational_rowmotion(t)
1297
+ ....: return t == t0
1298
+ sage: test_rectangle_periodicity_tropical(7, 6, 13) # needs sage.modules
1299
+ True
1300
+
1301
+ Tropicalization is also what relates birational rowmotion to
1302
+ classical rowmotion on order ideals. In fact, if `T` denotes
1303
+ the :class:`tropical semiring
1304
+ <sage.rings.semirings.tropical_semiring.TropicalSemiring>` of
1305
+ `\ZZ` and `P` is a finite poset, then we can define an embedding
1306
+ `\phi` from the set `J(P)` of all order ideals of `P` into the
1307
+ set `T^{\widehat{P}}` of all `T`-labellings of `P` by sending
1308
+ every `I \in J(P)` to the indicator function of `I` extended by
1309
+ the value `1` at the element `0` and the value `0` at the
1310
+ element `1`. This map `\phi` has the property that
1311
+ `R \circ \phi = \phi \circ r`, where `R` denotes birational
1312
+ rowmotion, and `r` denotes :meth:`classical rowmotion <rowmotion>`
1313
+ on `J(P)`. An example::
1314
+
1315
+ sage: P = posets.IntegerPartitions(5)
1316
+ sage: TT = TropicalSemiring(ZZ)
1317
+ sage: def indicator_labelling(I):
1318
+ ....: # send order ideal `I` to a `T`-labelling of `P`.
1319
+ ....: dct = {v: TT(v in I) for v in P}
1320
+ ....: return (TT, dct, TT(1), TT(0))
1321
+ sage: all(indicator_labelling(P.rowmotion(I)) # needs sage.modules
1322
+ ....: == P.birational_rowmotion(indicator_labelling(I))
1323
+ ....: for I in P.order_ideals_lattice(facade=True))
1324
+ True
1325
+
1326
+ TESTS:
1327
+
1328
+ Facade set to false works::
1329
+
1330
+ sage: P = Poset({1: [2, 3], 2: [4], 3: [4]}, facade=False)
1331
+ sage: lex = [1, 2, 3, 4]
1332
+ sage: t = P.birational_free_labelling(linear_extension=lex); t
1333
+ (Fraction Field of Multivariate Polynomial Ring in a, x1, x2, x3, x4, b over Rational Field,
1334
+ {...},
1335
+ a,
1336
+ b)
1337
+ sage: t = P.birational_rowmotion(t); t
1338
+ (Fraction Field of Multivariate Polynomial Ring in a, x1, x2, x3, x4, b over Rational Field,
1339
+ {...},
1340
+ a,
1341
+ b)
1342
+ sage: t[1][P(2)]
1343
+ (x1*x2*b + x1*x3*b)/(x2*x4)
1344
+ sage: t = P.birational_rowmotion(t)
1345
+ sage: t[1][P(2)]
1346
+ a*b/x3
1347
+ """
1348
+ l = labelling
1349
+ for v in reversed(self.linear_extension()):
1350
+ l = self.birational_toggle(v, l)
1351
+ return l
1352
+
1353
+ def panyushev_orbits(self, element_constructor=set):
1354
+ r"""
1355
+ Return the Panyushev orbits of antichains in ``self``.
1356
+
1357
+ The Panyushev orbit of an antichain is its orbit under
1358
+ Panyushev complementation (see
1359
+ :meth:`panyushev_complement`).
1360
+
1361
+ INPUT:
1362
+
1363
+ - ``element_constructor`` -- (default: ``set``) a type
1364
+ constructor (``set``, ``tuple``, ``list``, ``frozenset``,
1365
+ ``iter``, etc.) which is to be applied to the antichains
1366
+ before they are returned
1367
+
1368
+ OUTPUT:
1369
+
1370
+ - the partition of the set of all antichains of ``self`` into
1371
+ orbits under Panyushev complementation. This is returned as
1372
+ a list of lists ``L`` such that for each ``L`` and ``i``,
1373
+ cyclically:
1374
+ ``self.order_ideal_complement_generators(L[i]) == L[i+1]``.
1375
+ The entries ``L[i]`` are sets by default, but depending on
1376
+ the optional keyword variable ``element_constructors``
1377
+ they can also be tuples, lists etc.
1378
+
1379
+ EXAMPLES::
1380
+
1381
+ sage: # needs sage.modules
1382
+ sage: P = Poset( ( [1,2,3], [ [1,3], [2,3] ] ) )
1383
+ sage: orb = P.panyushev_orbits()
1384
+ sage: sorted(sorted(o) for o in orb)
1385
+ [[set(), {1, 2}, {3}], [{2}, {1}]]
1386
+ sage: orb = P.panyushev_orbits(element_constructor=list)
1387
+ sage: sorted(sorted(o) for o in orb)
1388
+ [[[], [1, 2], [3]], [[1], [2]]]
1389
+ sage: orb = P.panyushev_orbits(element_constructor=frozenset)
1390
+ sage: sorted(sorted(o) for o in orb)
1391
+ [[frozenset(), frozenset({1, 2}), frozenset({3})],
1392
+ [frozenset({2}), frozenset({1})]]
1393
+ sage: orb = P.panyushev_orbits(element_constructor=tuple)
1394
+ sage: sorted(sorted(o) for o in orb)
1395
+ [[(), (1, 2), (3,)], [(1,), (2,)]]
1396
+ sage: P = Poset( {} )
1397
+ sage: P.panyushev_orbits()
1398
+ [[set()]]
1399
+ """
1400
+ # TODO: implement a generic function taking a set and
1401
+ # bijections on this set, and returning the orbits.
1402
+ AC = set(self.antichains(element_constructor=frozenset))
1403
+ orbits = []
1404
+ while AC:
1405
+ A = AC.pop()
1406
+ orbit = [A]
1407
+ while True:
1408
+ A = frozenset(self.order_ideal_complement_generators(A))
1409
+ if A not in AC:
1410
+ break
1411
+ orbit.append(A)
1412
+ AC.remove(A)
1413
+ orbits.append([element_constructor(elt) for elt in orbit])
1414
+ return orbits
1415
+
1416
+ def rowmotion_orbits(self, element_constructor=set):
1417
+ r"""
1418
+ Return the rowmotion orbits of order ideals in ``self``.
1419
+
1420
+ The rowmotion orbit of an order ideal is its orbit under
1421
+ rowmotion (see :meth:`rowmotion`).
1422
+
1423
+ INPUT:
1424
+
1425
+ - ``element_constructor`` -- (default: ``set``) a type
1426
+ constructor (``set``, ``tuple``, ``list``, ``frozenset``,
1427
+ ``iter``, etc.) which is to be applied to the antichains
1428
+ before they are returned
1429
+
1430
+ OUTPUT:
1431
+
1432
+ - the partition of the set of all order ideals of ``self``
1433
+ into orbits under rowmotion. This is returned as
1434
+ a list of lists ``L`` such that for each ``L`` and ``i``,
1435
+ cyclically: ``self.rowmotion(L[i]) == L[i+1]``.
1436
+ The entries ``L[i]`` are sets by default, but depending on
1437
+ the optional keyword variable ``element_constructors``
1438
+ they can also be tuples, lists etc.
1439
+
1440
+ EXAMPLES::
1441
+
1442
+ sage: # needs sage.modules
1443
+ sage: P = Poset( {1: [2, 3], 2: [], 3: [], 4: [2]} )
1444
+ sage: sorted(len(o) for o in P.rowmotion_orbits())
1445
+ [3, 5]
1446
+ sage: orb = P.rowmotion_orbits(element_constructor=list)
1447
+ sage: sorted(sorted(e) for e in orb)
1448
+ [[[], [4, 1], [4, 1, 2, 3]], [[1], [1, 3], [4], [4, 1, 2], [4, 1, 3]]]
1449
+ sage: orb = P.rowmotion_orbits(element_constructor=tuple)
1450
+ sage: sorted(sorted(e) for e in orb)
1451
+ [[(), (4, 1), (4, 1, 2, 3)], [(1,), (1, 3), (4,), (4, 1, 2), (4, 1, 3)]]
1452
+ sage: P = Poset({})
1453
+ sage: P.rowmotion_orbits(element_constructor=tuple)
1454
+ [[()]]
1455
+ """
1456
+ pan_orbits = self.panyushev_orbits(element_constructor=list)
1457
+ return [[element_constructor(self.order_ideal(oideal))
1458
+ for oideal in orbit] for orbit in pan_orbits]
1459
+
1460
+ def rowmotion_orbits_plots(self):
1461
+ r"""
1462
+ Return plots of the rowmotion orbits of order ideals in ``self``.
1463
+
1464
+ The rowmotion orbit of an order ideal is its orbit under
1465
+ rowmotion (see :meth:`rowmotion`).
1466
+
1467
+ EXAMPLES::
1468
+
1469
+ sage: # needs sage.modules sage.plot
1470
+ sage: P = Poset( {1: [2, 3], 2: [], 3: [], 4: [2]} )
1471
+ sage: P.rowmotion_orbits_plots()
1472
+ Graphics Array of size 2 x 5
1473
+ sage: P = Poset({})
1474
+ sage: P.rowmotion_orbits_plots()
1475
+ Graphics Array of size 1 x 1
1476
+ """
1477
+ from sage.plot.plot import graphics_array
1478
+ plot_of_orb_plots = []
1479
+ max_orbit_size = 0
1480
+ for orb in self.rowmotion_orbits():
1481
+ orb_plots = []
1482
+ max_orbit_size = max(len(orb), max_orbit_size)
1483
+ for oi in orb:
1484
+ oiplot = self.order_ideal_plot(oi)
1485
+ orb_plots.append(oiplot)
1486
+ plot_of_orb_plots.append(orb_plots)
1487
+ return graphics_array(plot_of_orb_plots, ncols=max_orbit_size)
1488
+
1489
+ def toggling_orbits(self, vs, element_constructor=set):
1490
+ r"""
1491
+ Return the orbits of order ideals in ``self`` under the
1492
+ operation of toggling the vertices ``vs[0], vs[1], ...``
1493
+ in this order.
1494
+
1495
+ See :meth:`~sage.categories.posets.Posets.ParentMethods.order_ideal_toggle` for a definition of toggling.
1496
+
1497
+ .. WARNING::
1498
+
1499
+ The orbits are those under the composition of toggles,
1500
+ *not* under the single toggles themselves. Thus, for
1501
+ example, if ``vs == [1,2]``, then the orbits have the
1502
+ form `(I, T_2 T_1 I, T_2 T_1 T_2 T_1 I, \ldots)`
1503
+ (where `I` denotes an order ideal and `T_i` means
1504
+ toggling at `i`) rather than
1505
+ `(I, T_1 I, T_2 T_1 I, T_1 T_2 T_1 I, \ldots)`.
1506
+
1507
+ INPUT:
1508
+
1509
+ - ``vs`` -- a list (or other iterable) of elements of ``self``
1510
+ (but since the output depends on the order, sets should
1511
+ not be used as ``vs``).
1512
+
1513
+ OUTPUT:
1514
+
1515
+ A partition of the order ideals of ``self``, as a list of
1516
+ sets ``L`` such that for each ``L`` and ``i``, cyclically:
1517
+ ``self.order_ideal_toggles(L[i], vs) == L[i+1]``.
1518
+
1519
+ EXAMPLES::
1520
+
1521
+ sage: P = Poset( {1: [2, 4], 2: [], 3: [4], 4: []} )
1522
+ sage: sorted(len(o) for o in P.toggling_orbits([1, 2])) # needs sage.modules
1523
+ [2, 3, 3]
1524
+ sage: P = Poset( {1: [3], 2: [1, 4], 3: [], 4: [3]} )
1525
+ sage: sorted(len(o) for o in P.toggling_orbits((1, 2, 4, 3))) # needs sage.modules
1526
+ [3, 3]
1527
+ """
1528
+ # TODO: implement a generic function taking a set and
1529
+ # bijections on this set, and returning the orbits.
1530
+ OI = set(self.order_ideals_lattice(facade=True))
1531
+ orbits = []
1532
+ while OI:
1533
+ A = OI.pop()
1534
+ orbit = [ A ]
1535
+ while True:
1536
+ A = self.order_ideal_toggles(A, vs)
1537
+ if A not in OI:
1538
+ break
1539
+ orbit.append( A )
1540
+ OI.remove( A )
1541
+ orbits.append([element_constructor(_) for _ in orbit])
1542
+ return orbits
1543
+
1544
+ def toggling_orbits_plots(self, vs):
1545
+ r"""
1546
+ Return plots of the orbits of order ideals in ``self`` under the
1547
+ operation of toggling the vertices ``vs[0], vs[1], ...``
1548
+ in this order.
1549
+
1550
+ See :meth:`toggling_orbits` for more information.
1551
+
1552
+ EXAMPLES::
1553
+
1554
+ sage: # needs sage.modules sage.plot
1555
+ sage: P = Poset( {1: [2, 3], 2: [], 3: [], 4: [2]} )
1556
+ sage: P.toggling_orbits_plots([1,2,3,4])
1557
+ Graphics Array of size 2 x 5
1558
+ sage: P = Poset({})
1559
+ sage: P.toggling_orbits_plots([])
1560
+ Graphics Array of size 1 x 1
1561
+ """
1562
+ from sage.plot.plot import graphics_array
1563
+ plot_of_orb_plots = []
1564
+ max_orbit_size = 0
1565
+ for orb in self.toggling_orbits(vs):
1566
+ orb_plots = []
1567
+ max_orbit_size = max(len(orb), max_orbit_size)
1568
+ for oi in orb:
1569
+ oiplot = self.order_ideal_plot(oi)
1570
+ orb_plots.append(oiplot)
1571
+ plot_of_orb_plots.append(orb_plots)
1572
+ return graphics_array(plot_of_orb_plots, ncols=max_orbit_size)
1573
+
1574
+ def panyushev_orbit_iter(self, antichain, element_constructor=set,
1575
+ stop=True, check=True):
1576
+ r"""
1577
+ Iterate over the Panyushev orbit of an antichain
1578
+ ``antichain`` of ``self``.
1579
+
1580
+ The Panyushev orbit of an antichain is its orbit under
1581
+ Panyushev complementation (see
1582
+ :meth:`panyushev_complement`).
1583
+
1584
+ INPUT:
1585
+
1586
+ - ``antichain`` -- an antichain of ``self``, given as an
1587
+ iterable
1588
+
1589
+ - ``element_constructor`` -- a type constructor (default: ``set``).
1590
+ Can be ``set``, ``tuple``, ``list``, ``frozenset``, ``iter``,
1591
+ etc. To be applied to the antichains before they are yielded.
1592
+
1593
+ - ``stop`` -- boolean (default: ``True``); whether the iterator
1594
+ should stop once it completes its cycle (this happens when it is
1595
+ set to ``True``) or go on forever (this happens when it is set to
1596
+ ``False``).
1597
+
1598
+ - ``check`` -- boolean (default: ``True``); whether to check
1599
+ ``antichain`` for being an antichain
1600
+
1601
+ OUTPUT:
1602
+
1603
+ - an iterator over the orbit of the antichain ``antichain``
1604
+ under Panyushev complementation. This iterator `I` has the
1605
+ property that ``I[0] == antichain`` and each `i` satisfies
1606
+ ``self.order_ideal_complement_generators(I[i]) == I[i+1]``,
1607
+ where ``I[i+1]`` has to be understood as ``I[0]`` if it is
1608
+ undefined.
1609
+ The entries ``I[i]`` are sets by default, but depending on
1610
+ the optional keyword variable ``element_constructors``
1611
+ they can also be tuples, lists etc.
1612
+
1613
+ EXAMPLES::
1614
+
1615
+ sage: P = Poset( ( [1,2,3], [ [1,3], [2,3] ] ) )
1616
+ sage: list(P.panyushev_orbit_iter(set([1, 2])))
1617
+ [{1, 2}, {3}, set()]
1618
+ sage: list(P.panyushev_orbit_iter([1, 2]))
1619
+ [{1, 2}, {3}, set()]
1620
+ sage: list(P.panyushev_orbit_iter([2, 1]))
1621
+ [{1, 2}, {3}, set()]
1622
+ sage: list(P.panyushev_orbit_iter(set([1, 2]), element_constructor=list))
1623
+ [[1, 2], [3], []]
1624
+ sage: list(P.panyushev_orbit_iter(set([1, 2]), element_constructor=frozenset))
1625
+ [frozenset({1, 2}), frozenset({3}), frozenset()]
1626
+ sage: list(P.panyushev_orbit_iter(set([1, 2]), element_constructor=tuple))
1627
+ [(1, 2), (3,), ()]
1628
+
1629
+ sage: P = Poset( {} )
1630
+ sage: list(P.panyushev_orbit_iter([]))
1631
+ [set()]
1632
+
1633
+ sage: P = Poset({ 1: [2, 3], 2: [4], 3: [4], 4: [] })
1634
+ sage: Piter = P.panyushev_orbit_iter([2], stop=False)
1635
+ sage: next(Piter)
1636
+ {2}
1637
+ sage: next(Piter)
1638
+ {3}
1639
+ sage: next(Piter)
1640
+ {2}
1641
+ sage: next(Piter)
1642
+ {3}
1643
+ """
1644
+ # TODO: implement a generic function taking a set and
1645
+ # bijections on this set, and returning an orbit of a given
1646
+ # element.
1647
+ if check:
1648
+ if not self.is_antichain_of_poset(antichain):
1649
+ raise ValueError("the given antichain is not an antichain")
1650
+ starter = set(antichain) # sanitize input
1651
+ yield element_constructor(starter)
1652
+ next = starter
1653
+ if stop:
1654
+ while True:
1655
+ next = self.order_ideal_complement_generators(next)
1656
+ if next == starter:
1657
+ break
1658
+ yield element_constructor(next)
1659
+ else:
1660
+ while True:
1661
+ next = self.order_ideal_complement_generators(next)
1662
+ yield element_constructor(next)
1663
+
1664
+ def rowmotion_orbit_iter(self, oideal, element_constructor=set, stop=True, check=True):
1665
+ r"""
1666
+ Iterate over the rowmotion orbit of an order ideal
1667
+ ``oideal`` of ``self``.
1668
+
1669
+ The rowmotion orbit of an order ideal is its orbit under
1670
+ rowmotion (see :meth:`rowmotion`).
1671
+
1672
+ INPUT:
1673
+
1674
+ - ``oideal`` -- an order ideal of ``self``, given as an
1675
+ iterable
1676
+
1677
+ - ``element_constructor`` -- (defaults to ``set``) a type
1678
+ constructor (``set``, ``tuple``, ``list``, ``frozenset``,
1679
+ ``iter``, etc.) which is to be applied to the order
1680
+ ideals before they are yielded
1681
+
1682
+ - ``stop`` -- boolean (default: ``True``);
1683
+ whether the iterator should stop once it completes its
1684
+ cycle (this happens when it is set to ``True``) or go on
1685
+ forever (this happens when it is set to ``False``)
1686
+
1687
+ - ``check`` -- boolean (default: ``True``);
1688
+ whether ``oideal`` should be checked for being an
1689
+ order ideal
1690
+
1691
+ OUTPUT:
1692
+
1693
+ - an iterator over the orbit of the order ideal ``oideal``
1694
+ under rowmotion. This iterator `I` has the property that
1695
+ ``I[0] == oideal`` and that every `i` satisfies
1696
+ ``self.rowmotion(I[i]) == I[i+1]``, where ``I[i+1]`` has
1697
+ to be understood as ``I[0]`` if it is undefined.
1698
+ The entries ``I[i]`` are sets by default, but depending on
1699
+ the optional keyword variable ``element_constructors``
1700
+ they can also be tuples, lists etc.
1701
+
1702
+ EXAMPLES::
1703
+
1704
+ sage: P = Poset( ( [1,2,3], [ [1,3], [2,3] ] ) )
1705
+ sage: list(P.rowmotion_orbit_iter(set([1, 2])))
1706
+ [{1, 2}, {1, 2, 3}, set()]
1707
+ sage: list(P.rowmotion_orbit_iter([1, 2]))
1708
+ [{1, 2}, {1, 2, 3}, set()]
1709
+ sage: list(P.rowmotion_orbit_iter([2, 1]))
1710
+ [{1, 2}, {1, 2, 3}, set()]
1711
+ sage: list(P.rowmotion_orbit_iter(set([1, 2]), element_constructor=list))
1712
+ [[1, 2], [1, 2, 3], []]
1713
+ sage: list(P.rowmotion_orbit_iter(set([1, 2]), element_constructor=frozenset))
1714
+ [frozenset({1, 2}), frozenset({1, 2, 3}), frozenset()]
1715
+ sage: list(P.rowmotion_orbit_iter(set([1, 2]), element_constructor=tuple))
1716
+ [(1, 2), (1, 2, 3), ()]
1717
+
1718
+ sage: P = Poset( {} )
1719
+ sage: list(P.rowmotion_orbit_iter([]))
1720
+ [set()]
1721
+
1722
+ sage: P = Poset({ 1: [2, 3], 2: [4], 3: [4], 4: [] })
1723
+ sage: Piter = P.rowmotion_orbit_iter([1, 2, 3], stop=False)
1724
+ sage: next(Piter)
1725
+ {1, 2, 3}
1726
+ sage: next(Piter)
1727
+ {1, 2, 3, 4}
1728
+ sage: next(Piter)
1729
+ set()
1730
+ sage: next(Piter)
1731
+ {1}
1732
+ sage: next(Piter)
1733
+ {1, 2, 3}
1734
+
1735
+ sage: P = Poset({ 1: [4], 2: [4, 5], 3: [5] })
1736
+ sage: list(P.rowmotion_orbit_iter([1, 2], element_constructor=list))
1737
+ [[1, 2], [1, 2, 3, 4], [2, 3, 5], [1], [2, 3], [1, 2, 3, 5], [1, 2, 4], [3]]
1738
+ """
1739
+ # TODO: implement a generic function taking a set and
1740
+ # bijections on this set, and returning an orbit of a given
1741
+ # element.
1742
+ if check:
1743
+ if not self.is_order_ideal(oideal):
1744
+ raise ValueError("the given order ideal is not an order ideal")
1745
+ starter = set(oideal) # sanitize input
1746
+ yield element_constructor(starter)
1747
+ next = starter
1748
+ if stop:
1749
+ while True:
1750
+ next = self.rowmotion(next)
1751
+ if next == starter:
1752
+ break
1753
+ yield element_constructor(next)
1754
+ else:
1755
+ while True:
1756
+ next = self.rowmotion(next)
1757
+ yield element_constructor(next)
1758
+
1759
+ def toggling_orbit_iter(self, vs, oideal, element_constructor=set, stop=True, check=True):
1760
+ r"""
1761
+ Iterate over the orbit of an order ideal ``oideal`` of
1762
+ ``self`` under the operation of toggling the vertices
1763
+ ``vs[0], vs[1], ...`` in this order.
1764
+
1765
+ See :meth:`~sage.categories.posets.Posets.ParentMethods.order_ideal_toggle` for a definition of toggling.
1766
+
1767
+ .. WARNING::
1768
+
1769
+ The orbit is that under the composition of toggles,
1770
+ *not* under the single toggles themselves. Thus, for
1771
+ example, if ``vs == [1,2]``, then the orbit has the
1772
+ form `(I, T_2 T_1 I, T_2 T_1 T_2 T_1 I, \ldots)`
1773
+ (where `I` denotes ``oideal`` and `T_i` means
1774
+ toggling at `i`) rather than
1775
+ `(I, T_1 I, T_2 T_1 I, T_1 T_2 T_1 I, \ldots)`.
1776
+
1777
+ INPUT:
1778
+
1779
+ - ``vs`` -- list (or other iterable) of elements of ``self``
1780
+ (but since the output depends on the order, sets should
1781
+ not be used as ``vs``).
1782
+
1783
+ - ``oideal`` -- an order ideal of ``self``, given as an
1784
+ iterable
1785
+
1786
+ - ``element_constructor`` -- (default: ``set``) a type
1787
+ constructor (``set``, ``tuple``, ``list``, ``frozenset``,
1788
+ ``iter``, etc.) which is to be applied to the order
1789
+ ideals before they are yielded.
1790
+
1791
+ - ``stop`` -- boolean (default: ``True``);
1792
+ whether the iterator should stop once it completes its
1793
+ cycle (this happens when it is set to ``True``) or go on
1794
+ forever (this happens when it is set to ``False``).
1795
+
1796
+ - ``check`` -- boolean (default: ``True``);
1797
+ whether ``oideal`` should be checked for being an
1798
+ order ideal.
1799
+
1800
+ OUTPUT:
1801
+
1802
+ - an iterator over the orbit of the order ideal ``oideal``
1803
+ under toggling the vertices in the list ``vs`` in this
1804
+ order. This iterator `I` has the property that
1805
+ ``I[0] == oideal`` and that every `i` satisfies
1806
+ ``self.order_ideal_toggles(I[i], vs) == I[i+1]``, where
1807
+ ``I[i+1]`` has to be understood as ``I[0]`` if it is
1808
+ undefined.
1809
+ The entries ``I[i]`` are sets by default, but depending on
1810
+ the optional keyword variable ``element_constructors``
1811
+ they can also be tuples, lists etc.
1812
+
1813
+ EXAMPLES::
1814
+
1815
+ sage: P = Poset( ( [1,2,3], [ [1,3], [2,3] ] ) )
1816
+ sage: list(P.toggling_orbit_iter([1, 3, 1], set([1, 2])))
1817
+ [{1, 2}]
1818
+ sage: list(P.toggling_orbit_iter([1, 2, 3], set([1, 2])))
1819
+ [{1, 2}, set(), {1, 2, 3}]
1820
+ sage: list(P.toggling_orbit_iter([3, 2, 1], set([1, 2])))
1821
+ [{1, 2}, {1, 2, 3}, set()]
1822
+ sage: list(P.toggling_orbit_iter([3, 2, 1], set([1, 2]),
1823
+ ....: element_constructor=list))
1824
+ [[1, 2], [1, 2, 3], []]
1825
+ sage: list(P.toggling_orbit_iter([3, 2, 1], set([1, 2]),
1826
+ ....: element_constructor=frozenset))
1827
+ [frozenset({1, 2}), frozenset({1, 2, 3}), frozenset()]
1828
+ sage: list(P.toggling_orbit_iter([3, 2, 1], set([1, 2]),
1829
+ ....: element_constructor=tuple))
1830
+ [(1, 2), (1, 2, 3), ()]
1831
+ sage: list(P.toggling_orbit_iter([3, 2, 1], [2, 1],
1832
+ ....: element_constructor=tuple))
1833
+ [(1, 2), (1, 2, 3), ()]
1834
+
1835
+ sage: P = Poset( {} )
1836
+ sage: list(P.toggling_orbit_iter([], []))
1837
+ [set()]
1838
+
1839
+ sage: P = Poset({ 1: [2, 3], 2: [4], 3: [4], 4: [] })
1840
+ sage: Piter = P.toggling_orbit_iter([1, 2, 4, 3], [1, 2, 3], stop=False)
1841
+ sage: next(Piter)
1842
+ {1, 2, 3}
1843
+ sage: next(Piter)
1844
+ {1}
1845
+ sage: next(Piter)
1846
+ set()
1847
+ sage: next(Piter)
1848
+ {1, 2, 3}
1849
+ sage: next(Piter)
1850
+ {1}
1851
+ """
1852
+ # TODO: implement a generic function taking a set and
1853
+ # bijections on this set, and returning an orbit of a given
1854
+ # element.
1855
+ if check:
1856
+ if not self.is_order_ideal(oideal):
1857
+ raise ValueError("the given order ideal is not an order ideal")
1858
+ starter = set(oideal) # sanitize input
1859
+ yield element_constructor(starter)
1860
+ next = starter
1861
+ if stop:
1862
+ while True:
1863
+ next = self.order_ideal_toggles(next, vs)
1864
+ if next == starter:
1865
+ break
1866
+ yield element_constructor(next)
1867
+ else:
1868
+ while True:
1869
+ next = self.order_ideal_toggles(next, vs)
1870
+ yield element_constructor(next)
1871
+
1872
+ def order_ideals_lattice(self, as_ideals=True, facade=None):
1873
+ r"""
1874
+ Return the lattice of order ideals of a poset ``self``,
1875
+ ordered by inclusion.
1876
+
1877
+ The lattice of order ideals of a poset `P` is usually
1878
+ denoted by `J(P)`. Its underlying set is the set of order
1879
+ ideals of `P`, and its partial order is given by
1880
+ inclusion.
1881
+
1882
+ The order ideals of `P` are in a canonical bijection
1883
+ with the antichains of `P`. The bijection maps every
1884
+ order ideal to the antichain formed by its maximal
1885
+ elements. By setting the ``as_ideals`` keyword variable to
1886
+ ``False``, one can make this method apply this bijection
1887
+ before returning the lattice.
1888
+
1889
+ INPUT:
1890
+
1891
+ - ``as_ideals`` -- boolean (default: ``True``); if ``True`` returns
1892
+ a poset on the set of order ideals, otherwise on the set
1893
+ of antichains
1894
+ - ``facade`` -- boolean or ``None`` (default); whether to
1895
+ return a facade lattice or not. By default return facade
1896
+ lattice if the poset is a facade poset.
1897
+
1898
+ EXAMPLES::
1899
+
1900
+ sage: # needs sage.modules
1901
+ sage: P = posets.PentagonPoset()
1902
+ sage: P.cover_relations()
1903
+ [[0, 1], [0, 2], [1, 4], [2, 3], [3, 4]]
1904
+ sage: J = P.order_ideals_lattice(); J
1905
+ Finite lattice containing 8 elements
1906
+ sage: sorted(sorted(e) for e in J)
1907
+ [[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 2], [0, 2, 3]]
1908
+
1909
+ As a lattice on antichains::
1910
+
1911
+ sage: J2 = P.order_ideals_lattice(False); J2 # needs sage.modules
1912
+ Finite lattice containing 8 elements
1913
+ sage: sorted(J2) # needs sage.modules
1914
+ [(), (0,), (1,), (1, 2), (1, 3), (2,), (3,), (4,)]
1915
+
1916
+ TESTS::
1917
+
1918
+ sage: # needs sage.modules
1919
+ sage: J = posets.DiamondPoset(4, facade=True).order_ideals_lattice(); J
1920
+ Finite lattice containing 6 elements
1921
+ sage: sorted(sorted(e) for e in J)
1922
+ [[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 2]]
1923
+ sage: sorted(sorted(sorted(e) for e in c) for c in J.cover_relations())
1924
+ [[[], [0]], [[0], [0, 1]], [[0], [0, 2]], [[0, 1], [0, 1, 2]], [[0, 1, 2], [0, 1, 2, 3]], [[0, 1, 2], [0, 2]]]
1925
+
1926
+ sage: P = Poset({1: [2]})
1927
+ sage: J_facade = P.order_ideals_lattice() # needs sage.modules
1928
+ sage: J_nonfacade = P.order_ideals_lattice(facade=False) # needs sage.modules
1929
+ sage: type(J_facade[0]) == type(J_nonfacade[0]) # needs sage.modules
1930
+ False
1931
+ """
1932
+ from sage.combinat.posets.lattices import LatticePoset
1933
+ if facade is None:
1934
+ facade = self._is_facade
1935
+ if as_ideals:
1936
+ from sage.misc.call import attrcall
1937
+ from sage.sets.set import Set
1938
+ ideals = [Set(self.order_ideal(antichain))
1939
+ for antichain in self.antichains()]
1940
+ return LatticePoset((ideals, attrcall("issubset")),
1941
+ facade=facade)
1942
+ else:
1943
+ from sage.misc.cachefunc import cached_function
1944
+ antichains = [tuple(a) for a in self.antichains()]
1945
+
1946
+ @cached_function
1947
+ def is_above(a, xb):
1948
+ return any(self.is_lequal(xa, xb) for xa in a)
1949
+
1950
+ def compare(a, b):
1951
+ return all(is_above(a, xb) for xb in b)
1952
+ return LatticePoset((antichains, compare), facade=facade)
1953
+
1954
+ @abstract_method(optional=True)
1955
+ def antichains(self):
1956
+ r"""
1957
+ Return all antichains of ``self``.
1958
+
1959
+ EXAMPLES::
1960
+
1961
+ sage: A = posets.PentagonPoset().antichains(); A # needs sage.modules
1962
+ Set of antichains of Finite lattice containing 5 elements
1963
+ sage: list(A) # needs sage.modules
1964
+ [[], [0], [1], [1, 2], [1, 3], [2], [3], [4]]
1965
+ """
1966
+
1967
+ def directed_subsets(self, direction):
1968
+ r"""
1969
+ Return the order filters (resp. order ideals) of ``self``, as lists.
1970
+
1971
+ If ``direction`` is ``'up'``, returns the order filters (upper sets).
1972
+
1973
+ If ``direction`` is ``'down'``, returns the order ideals (lower sets).
1974
+
1975
+ INPUT:
1976
+
1977
+ - ``direction`` -- ``'up'`` or ``'down'``
1978
+
1979
+ EXAMPLES::
1980
+
1981
+ sage: P = Poset((divisors(12), attrcall("divides")), facade=True)
1982
+ sage: A = P.directed_subsets('up')
1983
+ sage: sorted(list(A)) # needs sage.modules
1984
+ [[], [1, 2, 4, 3, 6, 12], [2, 4, 3, 6, 12], [2, 4, 6, 12], [3, 6, 12],
1985
+ [4, 3, 6, 12], [4, 6, 12], [4, 12], [6, 12], [12]]
1986
+
1987
+ TESTS::
1988
+
1989
+ sage: list(Poset().directed_subsets('up'))
1990
+ [[]]
1991
+ """
1992
+ if direction != 'up' and direction != 'down':
1993
+ raise ValueError("direction must be either 'up' or 'down'")
1994
+ return self.antichains().map(lambda elements: self.directed_subset(elements, direction))