passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,1590 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ r"""
3
+ Ordered set partitions
4
+
5
+ AUTHORS:
6
+
7
+ - Mike Hansen
8
+ - MuPAD-Combinat developers (for algorithms and design inspiration)
9
+ - Travis Scrimshaw (2013-02-28): Removed ``CombinatorialClass`` and added
10
+ entry point through :class:`OrderedSetPartition`.
11
+ """
12
+ # ****************************************************************************
13
+ # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
14
+ #
15
+ # Distributed under the terms of the GNU General Public License (GPL)
16
+ #
17
+ # This code is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
+ # General Public License for more details.
21
+ #
22
+ # The full text of the GPL is available at:
23
+ #
24
+ # https://www.gnu.org/licenses/
25
+ # ****************************************************************************
26
+ from itertools import product
27
+
28
+ from sage.arith.misc import factorial, multinomial
29
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
30
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
31
+ from sage.combinat.combinat import stirling_number2
32
+ from sage.combinat.combinatorial_map import combinatorial_map
33
+ from sage.combinat.composition import Composition, Compositions
34
+ from sage.combinat.words.finite_word import FiniteWord_class
35
+ from sage.combinat.words.words import Words
36
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
37
+ from sage.misc.persist import register_unpickle_override
38
+ from sage.rings.integer import Integer
39
+ from sage.rings.integer_ring import ZZ
40
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
41
+ from sage.sets.set import Set, Set_generic
42
+ from sage.structure.list_clone import ClonableArray
43
+ from sage.structure.element import parent
44
+ from sage.structure.parent import Parent
45
+ from sage.structure.richcmp import richcmp
46
+ from sage.structure.unique_representation import UniqueRepresentation
47
+
48
+
49
+ class OrderedSetPartition(ClonableArray,
50
+ metaclass=InheritComparisonClasscallMetaclass):
51
+ r"""
52
+ An ordered partition of a set.
53
+
54
+ An ordered set partition `p` of a set `s` is a list of pairwise
55
+ disjoint nonempty subsets of `s` such that the union of these
56
+ subsets is `s`. These subsets are called the parts of the partition.
57
+
58
+ We represent an ordered set partition as a list of sets. By
59
+ extension, an ordered set partition of a nonnegative integer `n` is
60
+ the set partition of the integers from `1` to `n`. The number of
61
+ ordered set partitions of `n` is called the `n`-th ordered Bell
62
+ number.
63
+
64
+ There is a natural integer composition associated with an ordered
65
+ set partition, that is the sequence of sizes of all its parts in
66
+ order.
67
+
68
+ The number `T_n` of ordered set partitions of
69
+ `\{ 1, 2, \ldots, n \}` is the so-called `n`-th *Fubini number*
70
+ (also known as the `n`-th ordered Bell number; see
71
+ :wikipedia:`Ordered Bell number`). Its exponential generating
72
+ function is
73
+
74
+ .. MATH::
75
+
76
+ \sum_n \frac{T_n}{n!} x^n = \frac{1}{2-e^x}.
77
+
78
+ (See sequence :oeis:`A000670` in OEIS.)
79
+
80
+ INPUT:
81
+
82
+ - ``parts`` -- an object or iterable that defines an ordered set partition
83
+ (e.g., a list of pairwise disjoint sets) or a packed word (e.g., a list
84
+ of letters on some alphabet). If there is ambiguity and if the input should
85
+ be treated as a packed word, the keyword ``from_word`` should be used.
86
+
87
+ EXAMPLES:
88
+
89
+ There are 13 ordered set partitions of `\{1,2,3\}`::
90
+
91
+ sage: OrderedSetPartitions(3).cardinality()
92
+ 13
93
+
94
+ Here is the list of them::
95
+
96
+ sage: OrderedSetPartitions(3).list()
97
+ [[{1}, {2}, {3}],
98
+ [{1}, {3}, {2}],
99
+ [{2}, {1}, {3}],
100
+ [{3}, {1}, {2}],
101
+ [{2}, {3}, {1}],
102
+ [{3}, {2}, {1}],
103
+ [{1}, {2, 3}],
104
+ [{2}, {1, 3}],
105
+ [{3}, {1, 2}],
106
+ [{1, 2}, {3}],
107
+ [{1, 3}, {2}],
108
+ [{2, 3}, {1}],
109
+ [{1, 2, 3}]]
110
+
111
+ There are 12 ordered set partitions of `\{1,2,3,4\}` whose underlying
112
+ composition is `[1,2,1]`::
113
+
114
+ sage: OrderedSetPartitions(4,[1,2,1]).list()
115
+ [[{1}, {2, 3}, {4}],
116
+ [{1}, {2, 4}, {3}],
117
+ [{1}, {3, 4}, {2}],
118
+ [{2}, {1, 3}, {4}],
119
+ [{2}, {1, 4}, {3}],
120
+ [{3}, {1, 2}, {4}],
121
+ [{4}, {1, 2}, {3}],
122
+ [{3}, {1, 4}, {2}],
123
+ [{4}, {1, 3}, {2}],
124
+ [{2}, {3, 4}, {1}],
125
+ [{3}, {2, 4}, {1}],
126
+ [{4}, {2, 3}, {1}]]
127
+
128
+ Since :issue:`14140`, we can create an ordered set partition directly by
129
+ :class:`OrderedSetPartition` which creates the parent object by taking the
130
+ union of the partitions passed in. However it is recommended and
131
+ (marginally) faster to create the parent first and then create the ordered
132
+ set partition from that. ::
133
+
134
+ sage: s = OrderedSetPartition([[1,3],[2,4]]); s
135
+ [{1, 3}, {2, 4}]
136
+ sage: s.parent()
137
+ Ordered set partitions of {1, 2, 3, 4}
138
+
139
+ We can construct the ordered set partition from a word,
140
+ which we consider as packed::
141
+
142
+ sage: OrderedSetPartition([2,4,1,2])
143
+ [{3}, {1, 4}, {2}]
144
+ sage: OrderedSetPartition(from_word=[2,4,1,2])
145
+ [{3}, {1, 4}, {2}]
146
+ sage: OrderedSetPartition(from_word='bdab')
147
+ [{3}, {1, 4}, {2}]
148
+
149
+ .. WARNING::
150
+
151
+ The elements of the underlying set should be hashable.
152
+
153
+ REFERENCES:
154
+
155
+ :wikipedia:`Ordered_partition_of_a_set`
156
+ """
157
+ @staticmethod
158
+ def __classcall_private__(cls, parts=None, from_word=None, check=True):
159
+ """
160
+ Create a set partition from ``parts`` with the appropriate parent.
161
+
162
+ EXAMPLES::
163
+
164
+ sage: s = OrderedSetPartition([[1,3],[2,4]]); s
165
+ [{1, 3}, {2, 4}]
166
+ sage: s.parent()
167
+ Ordered set partitions of {1, 2, 3, 4}
168
+ sage: t = OrderedSetPartition([[2,4],[1,3]]); t
169
+ [{2, 4}, {1, 3}]
170
+ sage: s != t
171
+ True
172
+ sage: OrderedSetPartition()
173
+ []
174
+ sage: OrderedSetPartition([])
175
+ []
176
+ sage: OrderedSetPartition('')
177
+ []
178
+ sage: OrderedSetPartition('bdab') == OrderedSetPartition(from_word='bdab')
179
+ True
180
+ sage: OrderedSetPartition('bdab') == OrderedSetPartition(Word('bdab'))
181
+ True
182
+ """
183
+ if parts is None and from_word is None:
184
+ P = OrderedSetPartitions([])
185
+ return P.element_class(P, [])
186
+ W = Words(infinite=False)
187
+ if from_word:
188
+ return OrderedSetPartitions().from_finite_word(W(from_word))
189
+ # if `parts` looks like a sequence of "letters" then treat it like a word.
190
+ if parts in W or (parts and (parts[0] in ZZ or isinstance(parts[0], str))):
191
+ return OrderedSetPartitions().from_finite_word(W(parts))
192
+ P = OrderedSetPartitions(set(x for p in parts for x in p))
193
+ return P.element_class(P, parts, check=check)
194
+
195
+ def __init__(self, parent, s, check=True):
196
+ """
197
+ Initialize ``self``.
198
+
199
+ EXAMPLES::
200
+
201
+ sage: OS = OrderedSetPartitions(4)
202
+ sage: s = OS([[1, 3], [2, 4]])
203
+ sage: TestSuite(s).run()
204
+ """
205
+ ClonableArray.__init__(self, parent,
206
+ [frozenset(part) for part in s], check=check)
207
+
208
+ def _repr_(self):
209
+ """
210
+ Return a string representation of ``self``.
211
+
212
+ .. TODO::
213
+
214
+ Sort the repr output of Sage's :class:`Set` and remove
215
+ this method.
216
+
217
+ EXAMPLES::
218
+
219
+ sage: OrderedSetPartition([[1,3],[2,4]])
220
+ [{1, 3}, {2, 4}]
221
+ """
222
+ return '[' + ', '.join('{' + repr(sorted(x))[1:-1] + '}' for x in self) + ']'
223
+
224
+ def check(self):
225
+ """
226
+ Check that we are a valid ordered set partition.
227
+
228
+ EXAMPLES::
229
+
230
+ sage: OS = OrderedSetPartitions(4)
231
+ sage: s = OS([[1, 3], [2, 4]])
232
+ sage: s.check()
233
+ """
234
+ par = parent(self)
235
+ assert self in par, "%s not in %s" % (self, par)
236
+
237
+ def base_set(self):
238
+ """
239
+ Return the base set of ``self``.
240
+
241
+ This is the union of all parts of ``self``.
242
+
243
+ EXAMPLES::
244
+
245
+ sage: OrderedSetPartition([[1], [2,3], [4]]).base_set()
246
+ frozenset({1, 2, 3, 4})
247
+ sage: OrderedSetPartition([[1,2,3,4]]).base_set()
248
+ frozenset({1, 2, 3, 4})
249
+ sage: OrderedSetPartition([]).base_set()
250
+ frozenset()
251
+
252
+ TESTS::
253
+
254
+ sage: S = OrderedSetPartitions()
255
+ sage: x = S([['a', 'c', 'e'], ['b', 'd']])
256
+ sage: x.base_set()
257
+ frozenset({'a', 'b', 'c', 'd', 'e'})
258
+ """
259
+ try:
260
+ return parent(self)._set
261
+ except AttributeError: # in OrderedSetPartitions_all
262
+ return frozenset(x for part in self for x in part)
263
+
264
+ def base_set_cardinality(self):
265
+ """
266
+ Return the cardinality of the base set of ``self``.
267
+
268
+ This is the sum of the sizes of the parts of ``self``.
269
+
270
+ This is also known as the *size* (sometimes the *weight*) of
271
+ an ordered set partition.
272
+
273
+ EXAMPLES::
274
+
275
+ sage: OrderedSetPartition([[1], [2,3], [4]]).base_set_cardinality()
276
+ 4
277
+ sage: OrderedSetPartition([[1,2,3,4]]).base_set_cardinality()
278
+ 4
279
+
280
+ TESTS::
281
+
282
+ sage: S = OrderedSetPartitions()
283
+ sage: S([[1,4],[3],[2]]).base_set_cardinality()
284
+ 4
285
+ """
286
+ try:
287
+ return len(parent(self)._set)
288
+ except AttributeError: # in OrderedSetPartitions_all
289
+ return sum(len(part) for part in self)
290
+
291
+ size = base_set_cardinality
292
+
293
+ def length(self):
294
+ r"""
295
+ Return the number of parts of ``self``.
296
+
297
+ EXAMPLES::
298
+
299
+ sage: OS = OrderedSetPartitions(4)
300
+ sage: s = OS([[1, 3], [2, 4]])
301
+ sage: s.length()
302
+ 2
303
+ """
304
+ return len(self)
305
+
306
+ @combinatorial_map(name='to composition')
307
+ def to_composition(self):
308
+ r"""
309
+ Return the integer composition whose parts are the sizes of the sets
310
+ in ``self``.
311
+
312
+ EXAMPLES::
313
+
314
+ sage: S = OrderedSetPartitions(5)
315
+ sage: x = S([[3,5,4], [1, 2]])
316
+ sage: x.to_composition()
317
+ [3, 2]
318
+ sage: y = S([[3,1], [2], [5,4]])
319
+ sage: y.to_composition()
320
+ [2, 1, 2]
321
+ """
322
+ return Composition([len(p) for p in self])
323
+
324
+ @staticmethod
325
+ def sum(osps):
326
+ """
327
+ Return the concatenation of the given ordered set partitions
328
+ ``osps`` (provided they have no elements in common).
329
+
330
+ INPUT:
331
+
332
+ - ``osps`` -- list (or iterable) of ordered set partitions
333
+
334
+ EXAMPLES::
335
+
336
+ sage: OrderedSetPartition.sum([OrderedSetPartition([[4, 1], [3]]), OrderedSetPartition([[7], [2]]), OrderedSetPartition([[5, 6]])])
337
+ [{1, 4}, {3}, {7}, {2}, {5, 6}]
338
+
339
+ Any iterable can be provided as input::
340
+
341
+ sage: OrderedSetPartition.sum([OrderedSetPartition([[2*i,2*i+1]]) for i in [4,1,3]])
342
+ [{8, 9}, {2, 3}, {6, 7}]
343
+
344
+ Empty inputs are handled gracefully::
345
+
346
+ sage: OrderedSetPartition.sum([]) == OrderedSetPartition([])
347
+ True
348
+
349
+ TESTS::
350
+
351
+ sage: A = OrderedSetPartitions(3)([[2], [1, 3]])
352
+ sage: B = OrderedSetPartitions([5])([[5]])
353
+ sage: C = OrderedSetPartition.sum([A, B]); C
354
+ [{2}, {1, 3}, {5}]
355
+ sage: C.parent()
356
+ Ordered set partitions of {1, 2, 3, 5}
357
+ """
358
+ lset = set(x for osp in osps for x in osp.base_set())
359
+ return OrderedSetPartitions(lset)(sum((list(i) for i in osps), []))
360
+
361
+ def reversed(self):
362
+ r"""
363
+ Return the reversal of the ordered set partition ``self``.
364
+
365
+ The *reversal* of an ordered set partition
366
+ `(P_1, P_2, \ldots, P_k)` is defined to be the ordered
367
+ set partition `(P_k, P_{k-1}, \ldots, P_1)`.
368
+
369
+ EXAMPLES::
370
+
371
+ sage: OrderedSetPartition([[1, 3], [2]]).reversed()
372
+ [{2}, {1, 3}]
373
+ sage: OrderedSetPartition([[1, 5], [2, 4]]).reversed()
374
+ [{2, 4}, {1, 5}]
375
+ sage: OrderedSetPartition([[-1], [-2], [3, 4], [0]]).reversed()
376
+ [{0}, {3, 4}, {-2}, {-1}]
377
+ sage: OrderedSetPartition([]).reversed()
378
+ []
379
+ """
380
+ par = parent(self)
381
+ return par(list(reversed(self)))
382
+
383
+ def complement(self):
384
+ r"""
385
+ Return the complement of the ordered set partition ``self``.
386
+
387
+ This assumes that ``self`` is an ordered set partition of
388
+ an interval of `\ZZ`.
389
+
390
+ Let `(P_1, P_2, \ldots, P_k)` be an ordered set partition
391
+ of some interval `I` of `\ZZ`. Let `\omega` be the unique
392
+ strictly decreasing bijection `I \to I`. Then, the
393
+ *complement* of `(P_1, P_2, \ldots, P_k)` is defined to be
394
+ the ordered set partition
395
+ `(\omega(P_1), \omega(P_2), \ldots, \omega(P_k))`.
396
+
397
+ EXAMPLES::
398
+
399
+ sage: OrderedSetPartition([[1, 2], [3]]).complement()
400
+ [{2, 3}, {1}]
401
+ sage: OrderedSetPartition([[1, 3], [2]]).complement()
402
+ [{1, 3}, {2}]
403
+ sage: OrderedSetPartition([[2, 3]]).complement()
404
+ [{2, 3}]
405
+ sage: OrderedSetPartition([[1, 5], [2, 3], [4]]).complement()
406
+ [{1, 5}, {3, 4}, {2}]
407
+ sage: OrderedSetPartition([[-1], [-2], [1, 2], [0]]).complement()
408
+ [{1}, {2}, {-2, -1}, {0}]
409
+ sage: OrderedSetPartition([]).complement()
410
+ []
411
+ """
412
+ if len(self) <= 1:
413
+ return self
414
+ base_set = self.base_set()
415
+ m = min(base_set)
416
+ M = max(base_set)
417
+ mM = m + M
418
+ par = parent(self)
419
+ return par([[mM - i for i in part] for part in self])
420
+
421
+ def finer(self):
422
+ """
423
+ Return the set of ordered set partitions which are finer
424
+ than ``self``.
425
+
426
+ See :meth:`is_finer` for the definition of "finer".
427
+
428
+ EXAMPLES::
429
+
430
+ sage: C = OrderedSetPartition([[1, 3], [2]]).finer()
431
+ sage: C.cardinality()
432
+ 3
433
+ sage: C.list()
434
+ [[{1}, {3}, {2}], [{3}, {1}, {2}], [{1, 3}, {2}]]
435
+
436
+ sage: OrderedSetPartition([]).finer()
437
+ {[]}
438
+
439
+ sage: W = OrderedSetPartition([[4, 9], [-1, 2]])
440
+ sage: W.finer().list()
441
+ [[{9}, {4}, {2}, {-1}],
442
+ [{9}, {4}, {-1}, {2}],
443
+ [{9}, {4}, {-1, 2}],
444
+ [{4}, {9}, {2}, {-1}],
445
+ [{4}, {9}, {-1}, {2}],
446
+ [{4}, {9}, {-1, 2}],
447
+ [{4, 9}, {2}, {-1}],
448
+ [{4, 9}, {-1}, {2}],
449
+ [{4, 9}, {-1, 2}]]
450
+ """
451
+ par = parent(self)
452
+ if not self:
453
+ return FiniteEnumeratedSet([self])
454
+ return FiniteEnumeratedSet([par(sum((list(i) for i in C), []))
455
+ for C in product(*[OrderedSetPartitions(X) for X in self])])
456
+
457
+ def is_finer(self, co2):
458
+ """
459
+ Return ``True`` if the ordered set partition ``self`` is finer
460
+ than the ordered set partition ``co2``; otherwise, return ``False``.
461
+
462
+ If `A` and `B` are two ordered set partitions of the same set,
463
+ then `A` is said to be *finer* than `B` if `B` can be obtained
464
+ from `A` by (repeatedly) merging consecutive parts.
465
+ In this case, we say that `B` is *fatter* than `A`.
466
+
467
+ EXAMPLES::
468
+
469
+ sage: A = OrderedSetPartition([[1, 3], [2]])
470
+ sage: B = OrderedSetPartition([[1], [3], [2]])
471
+ sage: A.is_finer(B)
472
+ False
473
+ sage: B.is_finer(A)
474
+ True
475
+ sage: C = OrderedSetPartition([[3], [1], [2]])
476
+ sage: A.is_finer(C)
477
+ False
478
+ sage: C.is_finer(A)
479
+ True
480
+ sage: OrderedSetPartition([[2], [5], [1], [4]]).is_finer(OrderedSetPartition([[2, 5], [1, 4]]))
481
+ True
482
+ sage: OrderedSetPartition([[5], [2], [1], [4]]).is_finer(OrderedSetPartition([[2, 5], [1, 4]]))
483
+ True
484
+ sage: OrderedSetPartition([[2], [1], [5], [4]]).is_finer(OrderedSetPartition([[2, 5], [1, 4]]))
485
+ False
486
+ sage: OrderedSetPartition([[2, 5, 1], [4]]).is_finer(OrderedSetPartition([[2, 5], [1, 4]]))
487
+ False
488
+ """
489
+ co1 = self
490
+ if co1.base_set() != co2.base_set():
491
+ raise ValueError("ordered set partitions self (= %s) and co2 (= %s) must be of the same set" % (self, co2))
492
+
493
+ i1 = 0
494
+ for j2 in co2:
495
+ sum1 = set()
496
+ while len(sum1) < len(j2):
497
+ sum1 = sum1.union(co1[i1])
498
+ i1 += 1
499
+ if not sum1.issubset(j2):
500
+ return False
501
+
502
+ return True
503
+
504
+ def fatten(self, grouping):
505
+ r"""
506
+ Return the ordered set partition fatter than ``self``, obtained
507
+ by grouping together consecutive parts according to the integer
508
+ composition ``grouping``.
509
+
510
+ See :meth:`finer` for the definition of "fatter".
511
+
512
+ INPUT:
513
+
514
+ - ``grouping`` -- a composition whose sum is the length of ``self``
515
+
516
+ EXAMPLES:
517
+
518
+ Let us start with the ordered set partition::
519
+
520
+ sage: c = OrderedSetPartition([[2, 5], [1], [3, 4]])
521
+
522
+ With ``grouping`` equal to `(1, \ldots, 1)`, `c` is left unchanged::
523
+
524
+ sage: c.fatten(Composition([1,1,1]))
525
+ [{2, 5}, {1}, {3, 4}]
526
+
527
+ With ``grouping`` equal to `(\ell)` where `\ell` is the length of
528
+ `c`, this yields the coarsest ordered set partition above `c`::
529
+
530
+ sage: c.fatten(Composition([3]))
531
+ [{1, 2, 3, 4, 5}]
532
+
533
+ Other values for ``grouping`` yield (all the) other ordered
534
+ set partitions coarser than `c`::
535
+
536
+ sage: c.fatten(Composition([2,1]))
537
+ [{1, 2, 5}, {3, 4}]
538
+ sage: c.fatten(Composition([1,2]))
539
+ [{2, 5}, {1, 3, 4}]
540
+
541
+ TESTS::
542
+
543
+ sage: OrderedSetPartition([]).fatten(Composition([]))
544
+ []
545
+ sage: c.fatten(Composition([2,1])).__class__ == c.__class__
546
+ True
547
+ """
548
+ result = [None] * len(grouping)
549
+ j = 0
550
+ for i in range(len(grouping)):
551
+ result[i] = set().union(*self[j:j + grouping[i]])
552
+ j += grouping[i]
553
+ return parent(self)(result)
554
+
555
+ def fatter(self):
556
+ """
557
+ Return the set of ordered set partitions which are fatter
558
+ than ``self``.
559
+
560
+ See :meth:`finer` for the definition of "fatter".
561
+
562
+ EXAMPLES::
563
+
564
+ sage: C = OrderedSetPartition([[2, 5], [1], [3, 4]]).fatter()
565
+ sage: C.cardinality()
566
+ 4
567
+ sage: sorted(C)
568
+ [[{2, 5}, {1}, {3, 4}],
569
+ [{2, 5}, {1, 3, 4}],
570
+ [{1, 2, 5}, {3, 4}],
571
+ [{1, 2, 3, 4, 5}]]
572
+
573
+ sage: OrderedSetPartition([[4, 9], [-1, 2]]).fatter().list()
574
+ [[{4, 9}, {-1, 2}], [{-1, 2, 4, 9}]]
575
+
576
+ Some extreme cases::
577
+
578
+ sage: list(OrderedSetPartition([[5]]).fatter())
579
+ [[{5}]]
580
+ sage: list(Composition([]).fatter())
581
+ [[]]
582
+ sage: sorted(OrderedSetPartition([[1], [2], [3], [4]]).fatter())
583
+ [[{1}, {2}, {3}, {4}],
584
+ [{1}, {2}, {3, 4}],
585
+ [{1}, {2, 3}, {4}],
586
+ [{1}, {2, 3, 4}],
587
+ [{1, 2}, {3}, {4}],
588
+ [{1, 2}, {3, 4}],
589
+ [{1, 2, 3}, {4}],
590
+ [{1, 2, 3, 4}]]
591
+ """
592
+ return Compositions(len(self)).map(self.fatten)
593
+
594
+ @staticmethod
595
+ def bottom_up_osp(X, comp):
596
+ r"""
597
+ Return the ordered set partition obtained by listing the
598
+ elements of the set ``X`` in increasing order, and
599
+ placing bars between some of them according to the
600
+ integer composition ``comp`` (namely, the bars are placed
601
+ in such a way that the lengths of the resulting blocks are
602
+ exactly the entries of ``comp``).
603
+
604
+ INPUT:
605
+
606
+ - ``X`` -- a finite set (or list or tuple)
607
+
608
+ - ``comp`` -- a composition whose sum is the size of ``X``
609
+ (can be given as a list or tuple or composition)
610
+
611
+ EXAMPLES::
612
+
613
+ sage: buo = OrderedSetPartition.bottom_up_osp
614
+ sage: buo(Set([1, 4, 7, 9]), [2, 1, 1])
615
+ [{1, 4}, {7}, {9}]
616
+ sage: buo(Set([1, 4, 7, 9]), [1, 3])
617
+ [{1}, {4, 7, 9}]
618
+ sage: buo(Set([1, 4, 7, 9]), [1, 1, 1, 1])
619
+ [{1}, {4}, {7}, {9}]
620
+ sage: buo(range(8), [1, 4, 2, 1])
621
+ [{0}, {1, 2, 3, 4}, {5, 6}, {7}]
622
+ sage: buo([], [])
623
+ []
624
+
625
+ TESTS::
626
+
627
+ sage: buo = OrderedSetPartition.bottom_up_osp
628
+ sage: parent(buo(Set([1, 4, 7, 9]), [2, 1, 1]))
629
+ Ordered set partitions of {1, 4, 9, 7}
630
+ sage: buo((3, 5, 6), (2, 1))
631
+ [{3, 5}, {6}]
632
+ sage: buo([3, 5, 6], Composition([1, 2]))
633
+ [{3}, {5, 6}]
634
+ """
635
+ xs = sorted(X)
636
+ result = [None] * len(comp)
637
+ j = 0
638
+ for i in range(len(comp)):
639
+ result[i] = set(xs[j:j + comp[i]])
640
+ j += comp[i]
641
+ return OrderedSetPartitions(X)(result)
642
+
643
+ def strongly_finer(self):
644
+ """
645
+ Return the set of ordered set partitions which are strongly
646
+ finer than ``self``.
647
+
648
+ See :meth:`is_strongly_finer` for the definition of "strongly
649
+ finer".
650
+
651
+ EXAMPLES::
652
+
653
+ sage: C = OrderedSetPartition([[1, 3], [2]]).strongly_finer()
654
+ sage: C.cardinality()
655
+ 2
656
+ sage: C.list()
657
+ [[{1}, {3}, {2}], [{1, 3}, {2}]]
658
+
659
+ sage: OrderedSetPartition([]).strongly_finer()
660
+ {[]}
661
+
662
+ sage: W = OrderedSetPartition([[4, 9], [-1, 2]])
663
+ sage: W.strongly_finer().list()
664
+ [[{4}, {9}, {-1}, {2}],
665
+ [{4}, {9}, {-1, 2}],
666
+ [{4, 9}, {-1}, {2}],
667
+ [{4, 9}, {-1, 2}]]
668
+ """
669
+ par = parent(self)
670
+ if not self:
671
+ return FiniteEnumeratedSet([self])
672
+ buo = OrderedSetPartition.bottom_up_osp
673
+ return FiniteEnumeratedSet([par(sum((list(P) for P in C), []))
674
+ for C in product(*[[buo(X, comp) for comp in Compositions(len(X))] for X in self])])
675
+
676
+ def is_strongly_finer(self, co2):
677
+ r"""
678
+ Return ``True`` if the ordered set partition ``self`` is strongly
679
+ finer than the ordered set partition ``co2``; otherwise, return
680
+ ``False``.
681
+
682
+ If `A` and `B` are two ordered set partitions of the same set,
683
+ then `A` is said to be *strongly finer* than `B` if `B` can be
684
+ obtained from `A` by (repeatedly) merging consecutive parts,
685
+ provided that every time we merge two consecutive parts `C_i`
686
+ and `C_{i+1}`, we have `\max C_i < \min C_{i+1}`.
687
+ In this case, we say that `B` is *strongly fatter* than `A`.
688
+
689
+ EXAMPLES::
690
+
691
+ sage: A = OrderedSetPartition([[1, 3], [2]])
692
+ sage: B = OrderedSetPartition([[1], [3], [2]])
693
+ sage: A.is_strongly_finer(B)
694
+ False
695
+ sage: B.is_strongly_finer(A)
696
+ True
697
+ sage: C = OrderedSetPartition([[3], [1], [2]])
698
+ sage: A.is_strongly_finer(C)
699
+ False
700
+ sage: C.is_strongly_finer(A)
701
+ False
702
+ sage: OrderedSetPartition([[2], [5], [1], [4]]).is_strongly_finer(OrderedSetPartition([[2, 5], [1, 4]]))
703
+ True
704
+ sage: OrderedSetPartition([[5], [2], [1], [4]]).is_strongly_finer(OrderedSetPartition([[2, 5], [1, 4]]))
705
+ False
706
+ sage: OrderedSetPartition([[2], [1], [5], [4]]).is_strongly_finer(OrderedSetPartition([[2, 5], [1, 4]]))
707
+ False
708
+ sage: OrderedSetPartition([[2, 5, 1], [4]]).is_strongly_finer(OrderedSetPartition([[2, 5], [1, 4]]))
709
+ False
710
+ """
711
+ co1 = self
712
+ if co1.base_set() != co2.base_set():
713
+ raise ValueError("ordered set partitions self (= %s) and co2 (= %s) must be of the same set" % (self, co2))
714
+
715
+ i1 = 0
716
+ for j2 in co2:
717
+ sum1 = set()
718
+ while len(sum1) < len(j2):
719
+ next = co1[i1]
720
+ if sum1 and max(sum1) >= min(next):
721
+ return False
722
+ sum1 = sum1.union(next)
723
+ i1 += 1
724
+ if not sum1.issubset(j2):
725
+ return False
726
+
727
+ return True
728
+
729
+ def strongly_fatter(self):
730
+ """
731
+ Return the set of ordered set partitions which are strongly fatter
732
+ than ``self``.
733
+
734
+ See :meth:`strongly_finer` for the definition of "strongly fatter".
735
+
736
+ EXAMPLES::
737
+
738
+ sage: C = OrderedSetPartition([[2, 5], [1], [3, 4]]).strongly_fatter()
739
+ sage: C.cardinality()
740
+ 2
741
+ sage: sorted(C)
742
+ [[{2, 5}, {1}, {3, 4}], [{2, 5}, {1, 3, 4}]]
743
+
744
+ sage: OrderedSetPartition([[4, 9], [-1, 2]]).strongly_fatter().list()
745
+ [[{4, 9}, {-1, 2}]]
746
+
747
+ Some extreme cases::
748
+
749
+ sage: list(OrderedSetPartition([[5]]).strongly_fatter())
750
+ [[{5}]]
751
+ sage: list(OrderedSetPartition([]).strongly_fatter())
752
+ [[]]
753
+ sage: sorted(OrderedSetPartition([[1], [2], [3], [4]]).strongly_fatter())
754
+ [[{1}, {2}, {3}, {4}],
755
+ [{1}, {2}, {3, 4}],
756
+ [{1}, {2, 3}, {4}],
757
+ [{1}, {2, 3, 4}],
758
+ [{1, 2}, {3}, {4}],
759
+ [{1, 2}, {3, 4}],
760
+ [{1, 2, 3}, {4}],
761
+ [{1, 2, 3, 4}]]
762
+ sage: sorted(OrderedSetPartition([[1], [3], [2], [4]]).strongly_fatter())
763
+ [[{1}, {3}, {2}, {4}],
764
+ [{1}, {3}, {2, 4}],
765
+ [{1, 3}, {2}, {4}],
766
+ [{1, 3}, {2, 4}]]
767
+ sage: sorted(OrderedSetPartition([[4], [1], [5], [3]]).strongly_fatter())
768
+ [[{4}, {1}, {5}, {3}], [{4}, {1, 5}, {3}]]
769
+ """
770
+ c = [sorted(X) for X in self]
771
+ l = len(c) - 1
772
+ g = [-1] + [i for i in range(l) if c[i][-1] > c[i + 1][0]] + [l]
773
+ # g lists the positions of the blocks that cannot be merged
774
+ # with their right neighbors.
775
+ subcomps = [OrderedSetPartition(c[g[i] + 1: g[i + 1] + 1])
776
+ for i in range(len(g) - 1)]
777
+ # Now, self is the concatenation of the entries of subcomps.
778
+ # We can fatten each of the ordered set partitions setcomps
779
+ # arbitrarily, and then concatenate the results.
780
+ fattenings = [list(subcomp.fatter()) for subcomp in subcomps]
781
+ return FiniteEnumeratedSet([OrderedSetPartition(sum([list(gg) for gg in fattening], []))
782
+ for fattening in product(*fattenings)])
783
+
784
+ @combinatorial_map(name='to packed word')
785
+ def to_packed_word(self):
786
+ r"""
787
+ Return the packed word on alphabet `\{1,2,3,\ldots\}`
788
+ corresponding to ``self``.
789
+
790
+ A *packed word* on alphabet `\{1,2,3,\ldots\}` is any word whose
791
+ maximum letter is the same as its total number of distinct letters.
792
+ Let `P` be an ordered set partition of a set `X`.
793
+ The corresponding packed word `w_1 w_2 \cdots w_n` is constructed
794
+ by having letter `w_i = j` if the `i`-th smallest entry in `X`
795
+ occurs in the `j`-th block of `P`.
796
+
797
+ .. SEEALSO::
798
+
799
+ :meth:`Word.to_ordered_set_partition`
800
+
801
+ .. WARNING::
802
+
803
+ This assumes there is a total order on the underlying
804
+ set.
805
+
806
+ EXAMPLES::
807
+
808
+ sage: S = OrderedSetPartitions()
809
+ sage: x = S([[3,5], [2], [1,4,6]])
810
+ sage: x.to_packed_word()
811
+ word: 321313
812
+
813
+ sage: x = S([['a', 'c', 'e'], ['b', 'd']])
814
+ sage: x.to_packed_word()
815
+ word: 12121
816
+ """
817
+ X = sorted(self.base_set())
818
+ out = {}
819
+ for i in range(len(self)):
820
+ for letter in self[i]:
821
+ out[letter] = i
822
+ W = Words(infinite=False)
823
+ return W([out[letter] + 1 for letter in X])
824
+
825
+ def number_of_inversions(self):
826
+ r"""
827
+ Return the number of inversions in ``self``.
828
+
829
+ An inversion of an ordered set partition with blocks
830
+ `[B_1,B_2, \ldots, B_k]` is a pair of letters `i` and `j` with `i < j`
831
+ such that `i` is minimal in `B_m`, `j \in B_l`, and `l < m`.
832
+
833
+ REFERENCES:
834
+
835
+ - [Wilson2016]_
836
+
837
+ EXAMPLES::
838
+
839
+ sage: OrderedSetPartition([{2,5},{4,6},{1,3}]).number_of_inversions()
840
+ 5
841
+ sage: OrderedSetPartition([{1,3,8},{2,4},{5,6,7}]).number_of_inversions()
842
+ 3
843
+
844
+ TESTS::
845
+
846
+ sage: OrderedSetPartition([{1,3,8},{2,4},{5,6,7}]).number_of_inversions().parent()
847
+ Integer Ring
848
+ """
849
+ num_invs = 0
850
+ for m, part in enumerate(self):
851
+ i = min(part)
852
+ for ell in range(m):
853
+ num_invs += sum(1 for j in self[ell] if i < j)
854
+ return ZZ(num_invs)
855
+
856
+
857
+ class OrderedSetPartitions(UniqueRepresentation, Parent):
858
+ """
859
+ Return the combinatorial class of ordered set partitions of ``s``.
860
+
861
+ The optional argument ``c``, if specified, restricts the parts of
862
+ the partition to have certain sizes (the entries of ``c``).
863
+
864
+ EXAMPLES::
865
+
866
+ sage: OS = OrderedSetPartitions([1,2,3,4]); OS
867
+ Ordered set partitions of {1, 2, 3, 4}
868
+ sage: OS.cardinality()
869
+ 75
870
+ sage: OS.first()
871
+ [{1}, {2}, {3}, {4}]
872
+ sage: OS.last()
873
+ [{1, 2, 3, 4}]
874
+ sage: OS.random_element().parent() is OS
875
+ True
876
+
877
+ ::
878
+
879
+ sage: OS = OrderedSetPartitions([1,2,3,4], [2,2]); OS
880
+ Ordered set partitions of {1, 2, 3, 4} into parts of size [2, 2]
881
+ sage: OS.cardinality()
882
+ 6
883
+ sage: OS.first()
884
+ [{1, 2}, {3, 4}]
885
+ sage: OS.last()
886
+ [{3, 4}, {1, 2}]
887
+ sage: OS.list()
888
+ [[{1, 2}, {3, 4}],
889
+ [{1, 3}, {2, 4}],
890
+ [{1, 4}, {2, 3}],
891
+ [{2, 3}, {1, 4}],
892
+ [{2, 4}, {1, 3}],
893
+ [{3, 4}, {1, 2}]]
894
+
895
+ ::
896
+
897
+ sage: OS = OrderedSetPartitions("cat")
898
+ sage: OS # random
899
+ Ordered set partitions of {'a', 't', 'c'}
900
+ sage: sorted(OS.list(), key=str)
901
+ [[{'a', 'c', 't'}],
902
+ [{'a', 'c'}, {'t'}],
903
+ [{'a', 't'}, {'c'}],
904
+ [{'a'}, {'c', 't'}],
905
+ [{'a'}, {'c'}, {'t'}],
906
+ [{'a'}, {'t'}, {'c'}],
907
+ [{'c', 't'}, {'a'}],
908
+ [{'c'}, {'a', 't'}],
909
+ [{'c'}, {'a'}, {'t'}],
910
+ [{'c'}, {'t'}, {'a'}],
911
+ [{'t'}, {'a', 'c'}],
912
+ [{'t'}, {'a'}, {'c'}],
913
+ [{'t'}, {'c'}, {'a'}]]
914
+
915
+ TESTS::
916
+
917
+ sage: S = OrderedSetPartitions()
918
+ sage: x = S([[3,5], [2], [1,4,6]])
919
+ sage: x.parent()
920
+ Ordered set partitions
921
+ """
922
+ @staticmethod
923
+ def __classcall_private__(cls, s=None, c=None):
924
+ """
925
+ Choose the correct parent based upon input.
926
+
927
+ EXAMPLES::
928
+
929
+ sage: OrderedSetPartitions(4)
930
+ Ordered set partitions of {1, 2, 3, 4}
931
+ sage: OrderedSetPartitions(4, [1, 2, 1])
932
+ Ordered set partitions of {1, 2, 3, 4} into parts of size [1, 2, 1]
933
+ """
934
+ if s is None:
935
+ if c is not None:
936
+ raise NotImplementedError("cannot specify 'c' without specifying 's'")
937
+ return OrderedSetPartitions_all()
938
+ if isinstance(s, (int, Integer)):
939
+ if s < 0:
940
+ raise ValueError("s must be nonnegative")
941
+ s = frozenset(range(1, s + 1))
942
+ else:
943
+ s = frozenset(s)
944
+
945
+ if c is None:
946
+ return OrderedSetPartitions_s(s)
947
+
948
+ if isinstance(c, (int, Integer)):
949
+ return OrderedSetPartitions_sn(s, c)
950
+ if c not in Compositions(len(s)):
951
+ raise ValueError("c must be a composition of %s" % len(s))
952
+ return OrderedSetPartitions_scomp(s, Composition(c))
953
+
954
+ def __init__(self, s):
955
+ """
956
+ Initialize ``self``.
957
+
958
+ EXAMPLES::
959
+
960
+ sage: OS = OrderedSetPartitions(4)
961
+ sage: TestSuite(OS).run()
962
+ """
963
+ self._set = s
964
+ Parent.__init__(self, category=FiniteEnumeratedSets())
965
+
966
+ def _element_constructor_(self, s):
967
+ """
968
+ Construct an element of ``self`` from ``s``.
969
+
970
+ EXAMPLES::
971
+
972
+ sage: OS = OrderedSetPartitions(4)
973
+ sage: x = OS([[1,3],[2,4]]); x
974
+ [{1, 3}, {2, 4}]
975
+ sage: x.parent()
976
+ Ordered set partitions of {1, 2, 3, 4}
977
+ """
978
+ if isinstance(s, OrderedSetPartition):
979
+ raise ValueError("cannot convert %s into an element of %s" % (s, self))
980
+ return self.element_class(self, list(s)) # HERE the parent "self" is not good
981
+
982
+ Element = OrderedSetPartition
983
+
984
+ def __contains__(self, x):
985
+ """
986
+ TESTS::
987
+
988
+ sage: OS = OrderedSetPartitions([1,2,3,4])
989
+ sage: all(sp in OS for sp in OS)
990
+ True
991
+ sage: [[1,2], [], [3,4]] in OS
992
+ False
993
+ sage: [Set([1,2]), Set([3,4])] in OS
994
+ True
995
+ sage: [set([1,2]), set([3,4])] in OS
996
+ True
997
+
998
+ Make sure the set really matches::
999
+
1000
+ sage: [set([5,6]), set([3,4])] in OS
1001
+ False
1002
+ """
1003
+ # x must be a list
1004
+ if not isinstance(x, (OrderedSetPartition, list, tuple)):
1005
+ return False
1006
+
1007
+ # The total number of elements in the list
1008
+ # should be the same as the number is self._set
1009
+ if sum(map(len, x)) != len(self._set):
1010
+ return False
1011
+
1012
+ # Check to make sure each element of the list
1013
+ # is a nonempty set
1014
+ u = set()
1015
+ for s in x:
1016
+ if not s or not isinstance(s, (set, frozenset, Set_generic)):
1017
+ return False
1018
+ u = u.union(s)
1019
+
1020
+ # Make sure that the union of all the
1021
+ # sets is the original set
1022
+ if len(u) != len(self._set):
1023
+ return False
1024
+ return frozenset(u) == self._set
1025
+
1026
+ def from_finite_word(self, w, check=True):
1027
+ r"""
1028
+ Return the unique ordered set partition of `\{1, 2, \ldots, n\}` corresponding
1029
+ to a word `w` of length `n`.
1030
+
1031
+ .. SEEALSO::
1032
+
1033
+ :meth:`Word.to_ordered_set_partition`
1034
+
1035
+ EXAMPLES::
1036
+
1037
+ sage: A = OrderedSetPartitions().from_finite_word('abcabcabd'); A
1038
+ [{1, 4, 7}, {2, 5, 8}, {3, 6}, {9}]
1039
+ sage: B = OrderedSetPartitions().from_finite_word([1,2,3,1,2,3,1,2,4])
1040
+ sage: A == B
1041
+ True
1042
+
1043
+ TESTS::
1044
+
1045
+ sage: A = OrderedSetPartitions().from_finite_word('abcabca')
1046
+ sage: A.parent()
1047
+ Ordered set partitions
1048
+
1049
+ sage: A = OrderedSetPartitions(7).from_finite_word('abcabca')
1050
+ sage: A.parent()
1051
+ Ordered set partitions of {1, 2, 3, 4, 5, 6, 7}
1052
+ """
1053
+ # TODO: fix this if statement.
1054
+ # In fact, what we need is for the underlying alphabet to be sortable.
1055
+ if isinstance(w, (list, tuple, str, FiniteWord_class)):
1056
+ W = Words(infinite=False)
1057
+ if check:
1058
+ try:
1059
+ X = self._set
1060
+ if len(X) != len(w) or X != frozenset(range(1, len(w) + 1)):
1061
+ raise ValueError(f"result not in {self}")
1062
+ except AttributeError:
1063
+ pass
1064
+ return self.element_class(self, W(w).to_ordered_set_partition())
1065
+ raise TypeError(f"`from_finite_word` expects an object of type list/tuple/str/Word "
1066
+ f"representing a finite word, received {w}")
1067
+
1068
+
1069
+ class OrderedSetPartitions_s(OrderedSetPartitions):
1070
+ """
1071
+ Class of ordered partitions of a set `S`.
1072
+ """
1073
+
1074
+ def _repr_(self):
1075
+ """
1076
+ TESTS::
1077
+
1078
+ sage: OrderedSetPartitions([1,2,3,4])
1079
+ Ordered set partitions of {1, 2, 3, 4}
1080
+ """
1081
+ return "Ordered set partitions of %s" % Set(self._set)
1082
+
1083
+ def cardinality(self):
1084
+ """
1085
+ EXAMPLES::
1086
+
1087
+ sage: OrderedSetPartitions(0).cardinality()
1088
+ 1
1089
+ sage: OrderedSetPartitions(1).cardinality()
1090
+ 1
1091
+ sage: OrderedSetPartitions(2).cardinality()
1092
+ 3
1093
+ sage: OrderedSetPartitions(3).cardinality()
1094
+ 13
1095
+ sage: OrderedSetPartitions([1,2,3]).cardinality()
1096
+ 13
1097
+ sage: OrderedSetPartitions(4).cardinality()
1098
+ 75
1099
+ sage: OrderedSetPartitions(5).cardinality()
1100
+ 541
1101
+ """
1102
+ N = len(self._set)
1103
+ return sum(factorial(k) * stirling_number2(N, k)
1104
+ for k in range(N + 1))
1105
+
1106
+ def __iter__(self):
1107
+ """
1108
+ EXAMPLES::
1109
+
1110
+ sage: list(OrderedSetPartitions([1,2,3]))
1111
+ [[{1}, {2}, {3}],
1112
+ [{1}, {3}, {2}],
1113
+ [{2}, {1}, {3}],
1114
+ [{3}, {1}, {2}],
1115
+ [{2}, {3}, {1}],
1116
+ [{3}, {2}, {1}],
1117
+ [{1}, {2, 3}],
1118
+ [{2}, {1, 3}],
1119
+ [{3}, {1, 2}],
1120
+ [{1, 2}, {3}],
1121
+ [{1, 3}, {2}],
1122
+ [{2, 3}, {1}],
1123
+ [{1, 2, 3}]]
1124
+
1125
+ TESTS:
1126
+
1127
+ Test for :issue:`35654`::
1128
+
1129
+ sage: OrderedSetPartitions(set(),[0,0,0]).list()
1130
+ [[{}, {}, {}]]
1131
+ """
1132
+ for x in Compositions(len(self._set)):
1133
+ for z in OrderedSetPartitions(self._set, x):
1134
+ yield self.element_class(self, z, check=False)
1135
+
1136
+
1137
+ class OrderedSetPartitions_sn(OrderedSetPartitions):
1138
+ def __init__(self, s, n):
1139
+ """
1140
+ TESTS::
1141
+
1142
+ sage: OS = OrderedSetPartitions([1,2,3,4], 2)
1143
+ sage: OS == loads(dumps(OS))
1144
+ True
1145
+ """
1146
+ OrderedSetPartitions.__init__(self, s)
1147
+ self.n = n
1148
+
1149
+ def __contains__(self, x):
1150
+ """
1151
+ TESTS::
1152
+
1153
+ sage: OS = OrderedSetPartitions([1,2,3,4], 2)
1154
+ sage: all(sp in OS for sp in OS)
1155
+ True
1156
+ sage: OS.cardinality()
1157
+ 14
1158
+ sage: len([x for x in OrderedSetPartitions([1,2,3,4]) if x in OS])
1159
+ 14
1160
+ """
1161
+ return OrderedSetPartitions.__contains__(self, x) and len(x) == self.n
1162
+
1163
+ def __repr__(self):
1164
+ """
1165
+ TESTS::
1166
+
1167
+ sage: OrderedSetPartitions([1,2,3,4], 2)
1168
+ Ordered set partitions of {1, 2, 3, 4} into 2 parts
1169
+ """
1170
+ return "Ordered set partitions of %s into %s parts" % (Set(self._set),
1171
+ self.n)
1172
+
1173
+ def cardinality(self):
1174
+ """
1175
+ Return the cardinality of ``self``.
1176
+
1177
+ The number of ordered partitions of a set of size `n` into `k`
1178
+ parts is equal to `k! S(n,k)` where `S(n,k)` denotes the Stirling
1179
+ number of the second kind.
1180
+
1181
+ EXAMPLES::
1182
+
1183
+ sage: OrderedSetPartitions(4,2).cardinality()
1184
+ 14
1185
+ sage: OrderedSetPartitions(4,1).cardinality()
1186
+ 1
1187
+ """
1188
+ return factorial(self.n) * stirling_number2(len(self._set), self.n)
1189
+
1190
+ def __iter__(self):
1191
+ """
1192
+ EXAMPLES::
1193
+
1194
+ sage: [ p for p in OrderedSetPartitions([1,2,3,4], 2) ]
1195
+ [[{1, 2, 3}, {4}],
1196
+ [{1, 2, 4}, {3}],
1197
+ [{1, 3, 4}, {2}],
1198
+ [{2, 3, 4}, {1}],
1199
+ [{1, 2}, {3, 4}],
1200
+ [{1, 3}, {2, 4}],
1201
+ [{1, 4}, {2, 3}],
1202
+ [{2, 3}, {1, 4}],
1203
+ [{2, 4}, {1, 3}],
1204
+ [{3, 4}, {1, 2}],
1205
+ [{1}, {2, 3, 4}],
1206
+ [{2}, {1, 3, 4}],
1207
+ [{3}, {1, 2, 4}],
1208
+ [{4}, {1, 2, 3}]]
1209
+ """
1210
+ for x in Compositions(len(self._set), length=self.n):
1211
+ for z in OrderedSetPartitions_scomp(self._set, x):
1212
+ yield self.element_class(self, z, check=False)
1213
+
1214
+
1215
+ class OrderedSetPartitions_scomp(OrderedSetPartitions):
1216
+ def __init__(self, s, comp):
1217
+ """
1218
+ TESTS::
1219
+
1220
+ sage: OS = OrderedSetPartitions([1,2,3,4], [2,1,1])
1221
+ sage: OS == loads(dumps(OS))
1222
+ True
1223
+ """
1224
+ OrderedSetPartitions.__init__(self, s)
1225
+ self.c = Composition(comp)
1226
+
1227
+ def __repr__(self):
1228
+ """
1229
+ TESTS::
1230
+
1231
+ sage: OrderedSetPartitions([1,2,3,4], [2,1,1])
1232
+ Ordered set partitions of {1, 2, 3, 4} into parts of size [2, 1, 1]
1233
+ """
1234
+ return "Ordered set partitions of %s into parts of size %s" % (Set(self._set), self.c)
1235
+
1236
+ def __contains__(self, x):
1237
+ """
1238
+ TESTS::
1239
+
1240
+ sage: OS = OrderedSetPartitions([1,2,3,4], [2,1,1])
1241
+ sage: all(sp in OS for sp in OS)
1242
+ True
1243
+ sage: OS.cardinality()
1244
+ 12
1245
+ sage: len([x for x in OrderedSetPartitions([1,2,3,4]) if x in OS])
1246
+ 12
1247
+ """
1248
+ return OrderedSetPartitions.__contains__(self, x) and [len(z) for z in x] == self.c
1249
+
1250
+ def cardinality(self):
1251
+ r"""
1252
+ Return the cardinality of ``self``.
1253
+
1254
+ The number of ordered set partitions of a set of length `k` with
1255
+ composition shape `\mu` is equal to
1256
+
1257
+ .. MATH::
1258
+
1259
+ \frac{k!}{\prod_{\mu_i \neq 0} \mu_i!}.
1260
+
1261
+ EXAMPLES::
1262
+
1263
+ sage: OrderedSetPartitions(5,[2,3]).cardinality()
1264
+ 10
1265
+ sage: OrderedSetPartitions(0, []).cardinality()
1266
+ 1
1267
+ sage: OrderedSetPartitions(0, [0]).cardinality()
1268
+ 1
1269
+ sage: OrderedSetPartitions(0, [0,0]).cardinality()
1270
+ 1
1271
+ sage: OrderedSetPartitions(5, [2,0,3]).cardinality()
1272
+ 10
1273
+ """
1274
+ return multinomial(self.c)
1275
+
1276
+ def __iter__(self):
1277
+ """
1278
+ TESTS::
1279
+
1280
+ sage: [ p for p in OrderedSetPartitions([1,2,3,4], [2,1,1]) ]
1281
+ [[{1, 2}, {3}, {4}],
1282
+ [{1, 2}, {4}, {3}],
1283
+ [{1, 3}, {2}, {4}],
1284
+ [{1, 4}, {2}, {3}],
1285
+ [{1, 3}, {4}, {2}],
1286
+ [{1, 4}, {3}, {2}],
1287
+ [{2, 3}, {1}, {4}],
1288
+ [{2, 4}, {1}, {3}],
1289
+ [{3, 4}, {1}, {2}],
1290
+ [{2, 3}, {4}, {1}],
1291
+ [{2, 4}, {3}, {1}],
1292
+ [{3, 4}, {2}, {1}]]
1293
+
1294
+ sage: len(OrderedSetPartitions([1,2,3,4], [1,1,1,1]))
1295
+ 24
1296
+
1297
+ sage: [ x for x in OrderedSetPartitions([1,4,7], [3]) ]
1298
+ [[{1, 4, 7}]]
1299
+
1300
+ sage: [ x for x in OrderedSetPartitions([1,4,7], [1,2]) ]
1301
+ [[{1}, {4, 7}], [{4}, {1, 7}], [{7}, {1, 4}]]
1302
+
1303
+ sage: [ p for p in OrderedSetPartitions([], []) ]
1304
+ [[]]
1305
+
1306
+ sage: [ p for p in OrderedSetPartitions([1], [1]) ]
1307
+ [[{1}]]
1308
+
1309
+ Let us check that it works for large size (:issue:`16646`)::
1310
+
1311
+ sage: OrderedSetPartitions(42).first()
1312
+ [{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12},
1313
+ {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23},
1314
+ {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34},
1315
+ {35}, {36}, {37}, {38}, {39}, {40}, {41}, {42}]
1316
+
1317
+ EXAMPLES::
1318
+
1319
+ sage: list(OrderedSetPartitions(range(5), [2,1,2]))
1320
+ [[{0, 1}, {2}, {3, 4}],
1321
+ [{0, 1}, {3}, {2, 4}],
1322
+ ...
1323
+ [{2, 4}, {3}, {0, 1}],
1324
+ [{3, 4}, {2}, {0, 1}]]
1325
+ """
1326
+ part_sizes = self.c
1327
+ N = len(part_sizes)
1328
+ if not N:
1329
+ yield self.element_class(self, [], check=False)
1330
+ return
1331
+
1332
+ l = []
1333
+ lset = list(self._set)
1334
+ for i, j in enumerate(part_sizes):
1335
+ l.extend([i] * j)
1336
+
1337
+ pi = multiset_permutation_to_ordered_set_partition(l, N)
1338
+ converted = [frozenset(lset[i] for i in part) for part in pi]
1339
+ yield self.element_class(self, converted, check=False)
1340
+
1341
+ while multiset_permutation_next_lex(l):
1342
+ pi = multiset_permutation_to_ordered_set_partition(l, N)
1343
+ converted = [frozenset(lset[i] for i in part) for part in pi]
1344
+ yield self.element_class(self, converted, check=False)
1345
+
1346
+
1347
+ def multiset_permutation_to_ordered_set_partition(l, m):
1348
+ r"""
1349
+ Convert a multiset permutation to an ordered set partition.
1350
+
1351
+ INPUT:
1352
+
1353
+ - ``l`` -- a multiset permutation
1354
+ - ``m`` -- number of parts
1355
+
1356
+ EXAMPLES::
1357
+
1358
+ sage: from sage.combinat.set_partition_ordered import multiset_permutation_to_ordered_set_partition
1359
+ sage: l = [0, 0, 1, 1, 2]
1360
+ sage: multiset_permutation_to_ordered_set_partition(l, 3)
1361
+ [[0, 1], [2, 3], [4]]
1362
+ """
1363
+ p = [[] for _ in range(m)]
1364
+ for i, j in enumerate(l):
1365
+ p[j].append(i)
1366
+ return p
1367
+
1368
+
1369
+ def multiset_permutation_next_lex(l):
1370
+ r"""
1371
+ Return the next multiset permutation after ``l``.
1372
+
1373
+ EXAMPLES::
1374
+
1375
+ sage: from sage.combinat.set_partition_ordered import multiset_permutation_next_lex
1376
+ sage: l = [0, 0, 1, 1, 2]
1377
+ sage: while multiset_permutation_next_lex(l):
1378
+ ....: print(l)
1379
+ [0, 0, 1, 2, 1]
1380
+ [0, 0, 2, 1, 1]
1381
+ [0, 1, 0, 1, 2]
1382
+ [0, 1, 0, 2, 1]
1383
+ [0, 1, 1, 0, 2]
1384
+ [0, 1, 1, 2, 0]
1385
+ ...
1386
+ [1, 1, 2, 0, 0]
1387
+ [1, 2, 0, 0, 1]
1388
+ [1, 2, 0, 1, 0]
1389
+ [1, 2, 1, 0, 0]
1390
+ [2, 0, 0, 1, 1]
1391
+ [2, 0, 1, 0, 1]
1392
+ [2, 0, 1, 1, 0]
1393
+ [2, 1, 0, 0, 1]
1394
+ [2, 1, 0, 1, 0]
1395
+ [2, 1, 1, 0, 0]
1396
+
1397
+ TESTS:
1398
+
1399
+ Test for :issue:`35654`::
1400
+
1401
+ sage: multiset_permutation_next_lex([])
1402
+ 0
1403
+ """
1404
+ i = len(l) - 2
1405
+ while i >= 0 and l[i] >= l[i + 1]:
1406
+ i -= 1
1407
+ if i <= -1:
1408
+ return 0
1409
+ j = len(l) - 1
1410
+ while l[j] <= l[i]:
1411
+ j -= 1
1412
+ l[i], l[j] = l[j], l[i]
1413
+ l[i + 1:] = l[:i:-1]
1414
+ return 1
1415
+
1416
+
1417
+ class OrderedSetPartitions_all(OrderedSetPartitions):
1418
+ r"""
1419
+ Ordered set partitions of `\{1, \ldots, n\}` for all
1420
+ `n \in \ZZ_{\geq 0}`.
1421
+ """
1422
+
1423
+ def __init__(self):
1424
+ """
1425
+ Initialize ``self``.
1426
+
1427
+ EXAMPLES::
1428
+
1429
+ sage: OS = OrderedSetPartitions()
1430
+ sage: TestSuite(OS).run() # long time
1431
+ """
1432
+ Parent.__init__(self, category=InfiniteEnumeratedSets())
1433
+
1434
+ def subset(self, size=None, **kwargs):
1435
+ """
1436
+ Return the subset of ordered set partitions of a given
1437
+ size and additional keyword arguments.
1438
+
1439
+ EXAMPLES::
1440
+
1441
+ sage: P = OrderedSetPartitions()
1442
+ sage: P.subset(4)
1443
+ Ordered set partitions of {1, 2, 3, 4}
1444
+ """
1445
+ if size is None:
1446
+ return self
1447
+ return OrderedSetPartitions(size, **kwargs)
1448
+
1449
+ def __iter__(self):
1450
+ """
1451
+ Iterate over ``self``.
1452
+
1453
+ EXAMPLES::
1454
+
1455
+ sage: it = iter(OrderedSetPartitions())
1456
+ sage: [next(it) for _ in range(10)]
1457
+ [[], [{1}], [{1}, {2}], [{2}, {1}], [{1, 2}],
1458
+ [{1}, {2}, {3}], [{1}, {3}, {2}], [{2}, {1}, {3}],
1459
+ [{3}, {1}, {2}], [{2}, {3}, {1}]]
1460
+ """
1461
+ n = 0
1462
+ while True:
1463
+ for X in OrderedSetPartitions(n):
1464
+ yield self.element_class(self, list(X), check=False)
1465
+ n += 1
1466
+
1467
+ def _element_constructor_(self, s):
1468
+ """
1469
+ Construct an element of ``self`` from ``s``.
1470
+
1471
+ EXAMPLES::
1472
+
1473
+ sage: OS = OrderedSetPartitions()
1474
+ sage: OS([[1,3],[2,4]])
1475
+ [{1, 3}, {2, 4}]
1476
+ """
1477
+ if isinstance(s, OrderedSetPartition):
1478
+ gset = s.parent()._set
1479
+ if gset == frozenset(range(1, len(gset) + 1)):
1480
+ return self.element_class(self, list(s))
1481
+ raise ValueError("cannot convert %s into an element of %s" % (s, self))
1482
+ return self.element_class(self, list(s))
1483
+
1484
+ def __contains__(self, x):
1485
+ """
1486
+ TESTS::
1487
+
1488
+ sage: OS = OrderedSetPartitions([1,2,3,4])
1489
+ sage: AOS = OrderedSetPartitions()
1490
+ sage: all(sp in AOS for sp in OS)
1491
+ True
1492
+ sage: AOS.__contains__([[1,3], [4], [5,2]])
1493
+ True
1494
+ sage: AOS.__contains__([Set([1,3]), Set([4]), Set([5,2])])
1495
+ True
1496
+ sage: [Set([1,4]), Set([3])] in AOS
1497
+ False
1498
+ sage: [Set([1,3]), Set([4,2]), Set([2,5])] in AOS
1499
+ False
1500
+ sage: [Set([1,2]), Set()] in AOS
1501
+ False
1502
+ """
1503
+ if isinstance(x, OrderedSetPartition):
1504
+ if x.parent() is self:
1505
+ return True
1506
+ gset = x.parent()._set
1507
+ return gset == frozenset(range(1, len(gset) + 1))
1508
+
1509
+ # x must be a list or a tuple
1510
+ if not isinstance(x, (list, tuple)):
1511
+ return False
1512
+
1513
+ # Check to make sure each element of the list is a nonempty set
1514
+ if not all(s and isinstance(s, (set, frozenset, list, tuple, Set_generic)) for s in x):
1515
+ return False
1516
+
1517
+ if not all(isinstance(s, (set, frozenset, Set_generic)) or len(s) == len(set(s)) for s in x):
1518
+ return False
1519
+ X = set(y for p in x for y in p)
1520
+ return len(X) == sum(len(s) for s in x) and X == frozenset(range(1, len(X) + 1))
1521
+
1522
+ def _coerce_map_from_(self, X):
1523
+ """
1524
+ Return ``True`` if there is a coercion map from ``X``.
1525
+
1526
+ EXAMPLES::
1527
+
1528
+ sage: OSP = OrderedSetPartitions()
1529
+ sage: OSP._coerce_map_from_(OrderedSetPartitions(3))
1530
+ True
1531
+ sage: OSP._coerce_map_from_(OrderedSetPartitions(['a','b']))
1532
+ False
1533
+ """
1534
+ if X is self:
1535
+ return True
1536
+ if isinstance(X, OrderedSetPartitions):
1537
+ return X._set == frozenset(range(1, len(X._set) + 1))
1538
+ return super()._coerce_map_from_(X)
1539
+
1540
+ def _repr_(self):
1541
+ """
1542
+ TESTS::
1543
+
1544
+ sage: OrderedSetPartitions()
1545
+ Ordered set partitions
1546
+ """
1547
+ return "Ordered set partitions"
1548
+
1549
+ class Element(OrderedSetPartition):
1550
+ def _richcmp_(self, other, op):
1551
+ """
1552
+ TESTS::
1553
+
1554
+ sage: OSP = OrderedSetPartitions()
1555
+ sage: el1 = OSP([[1,3], [4], [2]])
1556
+ sage: el2 = OSP([[3,1], [2], [4]])
1557
+ sage: el1 == el1, el2 == el2, el1 == el2 # indirect doctest
1558
+ (True, True, False)
1559
+ sage: el1 <= el2, el1 >= el2, el2 <= el1 # indirect doctest
1560
+ (False, True, True)
1561
+ """
1562
+ return richcmp([sorted(s) for s in self],
1563
+ [sorted(s) for s in other], op)
1564
+
1565
+ ##########################################################
1566
+ # Deprecations
1567
+
1568
+
1569
+ class SplitNK(OrderedSetPartitions_scomp):
1570
+ def __setstate__(self, state):
1571
+ r"""
1572
+ For unpickling old ``SplitNK`` objects.
1573
+
1574
+ TESTS::
1575
+
1576
+ sage: loads(b"x\x9ck`J.NLO\xd5K\xce\xcfM\xca\xccK,\xd1+.\xc8\xc9,"
1577
+ ....: b"\x89\xcf\xcb\xe6\n\x061\xfc\xbcA\xccBF\xcd\xc6B\xa6\xda"
1578
+ ....: b"Bf\x8dP\xa6\xf8\xbcB\x16\x88\x96\xa2\xcc\xbc\xf4b\xbd\xcc"
1579
+ ....: b"\xbc\x92\xd4\xf4\xd4\"\xae\xdc\xc4\xec\xd4x\x18\xa7\x905"
1580
+ ....: b"\x94\xd1\xb45\xa8\x90\r\xa8>\xbb\x90=\x03\xc85\x02r9J\x93"
1581
+ ....: b"\xf4\x00\xb4\xc6%f")
1582
+ Ordered set partitions of {0, 1, 2, 3, 4} into parts of size [2, 3]
1583
+ """
1584
+ self.__class__ = OrderedSetPartitions_scomp
1585
+ n = state['_n']
1586
+ k = state['_k']
1587
+ OrderedSetPartitions_scomp.__init__(self, range(state['_n']), (k, n - k))
1588
+
1589
+
1590
+ register_unpickle_override("sage.combinat.split_nk", "SplitNK_nk", SplitNK)