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,1205 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Fully commutative stable Grothendieck crystal
5
+
6
+ AUTHORS:
7
+
8
+ - Jianping Pan (2020-08-31): initial version
9
+
10
+ - Wencin Poh (2020-08-31): initial version
11
+
12
+ - Anne Schilling (2020-08-31): initial version
13
+ """
14
+
15
+ # ****************************************************************************
16
+ # Copyright (C) 2020 Jianping Pan <jppan at math dot ucdavis dot edu>
17
+ # Wencin Poh <wpoh at ucdavis dot edu>
18
+ # Anne Schilling <anne at math dot ucdavis dot edu>
19
+ #
20
+ # This program is free software: you can redistribute it and/or modify
21
+ # it under the terms of the GNU General Public License as published by
22
+ # the Free Software Foundation, either version 2 of the License, or
23
+ # (at your option) any later version.
24
+ # https://www.gnu.org/licenses/
25
+ # ****************************************************************************
26
+
27
+ from sage.structure.element import Element
28
+ from sage.structure.parent import Parent
29
+ from sage.structure.richcmp import richcmp_by_eq_and_lt
30
+ from sage.structure.unique_representation import UniqueRepresentation
31
+ from sage.categories.classical_crystals import ClassicalCrystals
32
+ from sage.categories.enumerated_sets import EnumeratedSets
33
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
34
+ from sage.combinat.root_system.cartan_type import CartanType
35
+ from sage.combinat import permutation
36
+ from sage.rings.integer import Integer
37
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
38
+ from sage.misc.lazy_attribute import lazy_attribute
39
+ from sage.misc.lazy_import import lazy_import
40
+
41
+ lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup')
42
+
43
+
44
+ class DecreasingHeckeFactorization(Element, metaclass=InheritComparisonClasscallMetaclass):
45
+ """
46
+ Class of decreasing factorizations in the 0-Hecke monoid.
47
+
48
+ INPUT:
49
+
50
+ - ``t`` -- decreasing factorization inputted as list of lists
51
+
52
+ - ``max_value`` -- maximal value of entries
53
+
54
+ EXAMPLES::
55
+
56
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
57
+ sage: t = [[3, 2], [], [2, 1]]
58
+ sage: h = DecreasingHeckeFactorization(t, 3); h
59
+ (3, 2)()(2, 1)
60
+ sage: h.excess
61
+ 1
62
+ sage: h.factors
63
+ 3
64
+ sage: h.max_value
65
+ 3
66
+ sage: h.value
67
+ ((3, 2), (), (2, 1))
68
+
69
+ sage: u = [[3, 2, 1], [3], [2, 1]]
70
+ sage: h = DecreasingHeckeFactorization(u); h
71
+ (3, 2, 1)(3)(2, 1)
72
+ sage: h.weight()
73
+ (2, 1, 3)
74
+ sage: h.parent()
75
+ Decreasing Hecke factorizations with 3 factors associated to [2, 1, 3, 2, 1] with excess 1
76
+ """
77
+ @staticmethod
78
+ def __classcall_private__(self, t, max_value=None, parent=None):
79
+ """
80
+ Assign the correct parent for ``t`` and call ``t`` as an element of that parent.
81
+
82
+ EXAMPLES::
83
+
84
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
85
+ sage: h1 = DecreasingHeckeFactorization([[3, 1], [], [3, 2]])
86
+ sage: h1.parent()
87
+ Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 1
88
+ sage: h2 = DecreasingHeckeFactorization(h1)
89
+ sage: h1 == h2
90
+ True
91
+
92
+ sage: h1 = DecreasingHeckeFactorization([[3, 1], [2, 1], [2, 1]])
93
+ sage: F = h1.parent(); F
94
+ Decreasing Hecke factorizations with 3 factors associated to [1, 3, 2, 1] with excess 2
95
+ sage: h2 = F(h1)
96
+ sage: h1 == h2
97
+ True
98
+
99
+ TESTS::
100
+
101
+ sage: DecreasingHeckeFactorization([[]])
102
+ ()
103
+ """
104
+ _check_decreasing_hecke_factorization(t)
105
+ if isinstance(t, DecreasingHeckeFactorization):
106
+ u = t.value
107
+ if parent is None:
108
+ parent = t.parent()
109
+ else:
110
+ u = t
111
+ if parent is None:
112
+ if max_value is None:
113
+ letters = [x for factor in t for x in factor]
114
+ max_value = max(letters) if letters else 1
115
+ from sage.monoids.hecke_monoid import HeckeMonoid
116
+ S = SymmetricGroup(max_value+1)
117
+ H = HeckeMonoid(S)
118
+ word = H.from_reduced_word(x for factor in t for x in factor).reduced_word()
119
+ factors = len(t)
120
+ excess = sum(len(l) for l in t) - len(word)
121
+
122
+ p = permutation.from_reduced_word(word)
123
+ if p.has_pattern([3,2,1]):
124
+ word = S.from_reduced_word(word)
125
+ parent = DecreasingHeckeFactorizations(word, factors, excess)
126
+ else:
127
+ word = S.from_reduced_word(word)
128
+ parent = FullyCommutativeStableGrothendieckCrystal(word, factors, excess)
129
+ return parent.element_class(parent, u)
130
+
131
+ def __init__(self, parent, t):
132
+ """
133
+ Initialize a decreasing factorization for ``self`` given the relevant data.
134
+
135
+ EXAMPLES::
136
+
137
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
138
+ sage: t = [[2, 1], [2], [], [1]]
139
+ sage: h1 = DecreasingHeckeFactorization(t); h1
140
+ (2, 1)(2)()(1)
141
+ sage: h1.excess
142
+ 1
143
+ sage: h2 = DecreasingHeckeFactorization(t, 2)
144
+ sage: h2.value
145
+ ((2, 1), (2,), (), (1,))
146
+ sage: h1 == h2
147
+ True
148
+
149
+ sage: t = [[2, 1], [2], [], [3, 1]]
150
+ sage: h = DecreasingHeckeFactorization(t, 5)
151
+ sage: h.max_value
152
+ 5
153
+ sage: h.factors
154
+ 4
155
+ sage: h.w
156
+ (1, 2, 1, 3)
157
+
158
+ TESTS::
159
+
160
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
161
+ sage: t1 = [[], [3, 1], [], [2, 1], [1]]
162
+ sage: t2 = [[], [3, 1], [], [2, 1], [2]]
163
+ sage: h1 = DecreasingHeckeFactorization(t1, 3)
164
+ sage: h2 = DecreasingHeckeFactorization(t2, 3)
165
+ sage: h3 = DecreasingHeckeFactorization(t1)
166
+ sage: h1 == h2, h1 == h3
167
+ (False, True)
168
+ sage: h1 != h2, h1 != h3
169
+ (True, False)
170
+ """
171
+ Element.__init__(self, parent)
172
+ self.factors = parent.factors
173
+ self.max_value = parent.max_value
174
+ self.w = parent.w
175
+ self.excess = parent.excess
176
+ self.value = tuple(tuple(factors) for factors in t)
177
+
178
+ def _repr_(self):
179
+ """
180
+ Return the representation of ``self``.
181
+
182
+ EXAMPLES::
183
+
184
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
185
+ sage: t = [[], [2, 1], [2], [], [2]]
186
+ sage: h = DecreasingHeckeFactorization(t); h
187
+ ()(2, 1)(2)()(2)
188
+ """
189
+ return "".join("("+repr(list(factor))[1:-1]+")" for factor in self.value)
190
+
191
+ def __hash__(self):
192
+ """
193
+ Return hash of ``self``.
194
+
195
+ EXAMPLES::
196
+
197
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
198
+ sage: t = [[], [2, 1], [2], [], [2]]
199
+ sage: h1 = DecreasingHeckeFactorization(t)
200
+ sage: h2 = DecreasingHeckeFactorization(t, 3)
201
+ sage: h3 = DecreasingHeckeFactorization(t, 2)
202
+ sage: hash(h1) == hash(h2)
203
+ False
204
+ sage: hash(h1) == hash(h3)
205
+ True
206
+ """
207
+ return hash((self.max_value, self.value))
208
+
209
+ _richcmp_ = richcmp_by_eq_and_lt("__eq__", "__lt__")
210
+
211
+ def __eq__(self, other):
212
+ """
213
+ Return ``True`` if ``self`` equals ``other`` and ``False`` otherwise.
214
+
215
+ EXAMPLES::
216
+
217
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
218
+ sage: t = [[], [2, 1], [2], [], [2]]
219
+ sage: h1 = DecreasingHeckeFactorization(t)
220
+ sage: h2 = DecreasingHeckeFactorization(t, 3)
221
+ sage: h1 == h2
222
+ True
223
+ """
224
+ return isinstance(self, type(other)) and self.value == other.value
225
+
226
+ def __lt__(self, other):
227
+ """
228
+ Return ``True`` if ``self`` comes before ``other`` and ``False``
229
+ otherwise.
230
+
231
+ We say that `h_1` comes before `h_2` if either weight of `h_1 <` weight of `h_2`
232
+ lexicographically, or if both weights of `h_1` and `h_2` are equal,
233
+ but `h_1 < h_2` lexicographically.
234
+ This ordering is mainly used for sorting or comparison.
235
+
236
+ EXAMPLES::
237
+
238
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
239
+ sage: t1 = [[], [2, 1], [], [2, 1], [1]]
240
+ sage: t2 = [[], [2, 1], [], [2, 1], [2]]
241
+ sage: t3 = [[], [2, 1], [2], [1], [1]]
242
+ sage: h1 = DecreasingHeckeFactorization(t1)
243
+ sage: h2 = DecreasingHeckeFactorization(t2)
244
+ sage: h3 = DecreasingHeckeFactorization(t3)
245
+ sage: h1 < h2
246
+ True
247
+ sage: h1 < h3
248
+ False
249
+ """
250
+ return (self.weight(), self.value) < (other.weight(), other.value)
251
+
252
+ def _latex_(self):
253
+ r"""
254
+ Return LaTeX code for ``self``.
255
+
256
+ EXAMPLES::
257
+
258
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
259
+ sage: t = [[2], [2, 1], [], [4, 3, 1]]
260
+ sage: h = DecreasingHeckeFactorization(t, 6)
261
+ sage: latex(h)
262
+ \left(2\right)\left(2, 1\right)\left(\;\right)\left(4, 3, 1\right)
263
+ """
264
+ s = ""
265
+ for factor in self.value:
266
+ if factor:
267
+ s += r"\left("+repr(list(factor))[1:-1]+r"\right)"
268
+ else:
269
+ s += r"\left(\;\right)"
270
+ return s
271
+
272
+ def weight(self):
273
+ """
274
+ Return the weight of ``self``.
275
+
276
+ EXAMPLES::
277
+
278
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
279
+ sage: t = [[2], [2, 1], [], [4, 3, 1]]
280
+ sage: h = DecreasingHeckeFactorization(t, 6)
281
+ sage: h.weight()
282
+ (3, 0, 2, 1)
283
+ """
284
+ return tuple([len(l) for l in reversed(self.value)])
285
+
286
+ def to_word(self):
287
+ """
288
+ Return the word associated to ``self`` in the 0-Hecke monoid.
289
+
290
+ EXAMPLES::
291
+
292
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
293
+ sage: t = [[2], [], [2, 1], [4, 3, 1]]
294
+ sage: h = DecreasingHeckeFactorization(t)
295
+ sage: h.to_word()
296
+ [2, 2, 1, 4, 3, 1]
297
+ """
298
+ return [j for factors in self.value for j in factors]
299
+
300
+ def to_increasing_hecke_biword(self):
301
+ """
302
+ Return the associated increasing Hecke biword of ``self``.
303
+
304
+ EXAMPLES::
305
+
306
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
307
+ sage: t = [[2], [], [2, 1],[4, 3, 1]]
308
+ sage: h = DecreasingHeckeFactorization(t, 4)
309
+ sage: h.to_increasing_hecke_biword()
310
+ [[1, 1, 1, 2, 2, 4], [1, 3, 4, 1, 2, 2]]
311
+ """
312
+ L = [[],[]]
313
+ for j in range(len(self.value)):
314
+ L[1] += list(self.value[-j-1][::-1])
315
+ L[0] += [j+1]*len(self.value[-j-1])
316
+ return L
317
+
318
+
319
+ class DecreasingHeckeFactorizations(UniqueRepresentation, Parent):
320
+ """
321
+ Set of decreasing factorizations in the 0-Hecke monoid.
322
+
323
+ INPUT:
324
+
325
+ - ``w`` -- an element in the symmetric group
326
+
327
+ - ``factors`` -- the number of factors in the factorization
328
+
329
+ - ``excess`` -- the total number of letters in the factorization minus the length of a reduced word for ``w``
330
+
331
+ EXAMPLES::
332
+
333
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
334
+ sage: S = SymmetricGroup(3+1)
335
+ sage: w = S.from_reduced_word([1, 3, 2, 1])
336
+ sage: F = DecreasingHeckeFactorizations(w, 3, 3); F
337
+ Decreasing Hecke factorizations with 3 factors associated to [1, 3, 2, 1] with excess 3
338
+ sage: F.list()
339
+ [(3, 1)(3, 1)(3, 2, 1), (3, 1)(3, 2, 1)(2, 1), (3, 2, 1)(2, 1)(2, 1)]
340
+ """
341
+ @staticmethod
342
+ def __classcall_private__(cls, w, factors, excess):
343
+ """
344
+ Classcall to mend the input.
345
+
346
+ EXAMPLES::
347
+
348
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
349
+ sage: S = SymmetricGroup(3+1)
350
+ sage: w = S.from_reduced_word([1, 2 ,1])
351
+ sage: F = DecreasingHeckeFactorizations(w, 4, 1); F
352
+ Decreasing Hecke factorizations with 4 factors associated to [1, 2, 1] with excess 1
353
+
354
+ sage: from sage.monoids.hecke_monoid import HeckeMonoid
355
+ sage: H = HeckeMonoid(SymmetricGroup(3+1))
356
+ sage: w = H.from_reduced_word([1, 2 ,1])
357
+ sage: G = DecreasingHeckeFactorizations(w, 4, 1); G
358
+ Decreasing Hecke factorizations with 4 factors associated to [1, 2, 1] with excess 1
359
+ sage: F is G
360
+ True
361
+ """
362
+ from sage.monoids.hecke_monoid import HeckeMonoid
363
+ if isinstance(w.parent(), SymmetricGroup):
364
+ H = HeckeMonoid(w.parent())
365
+ w = H.from_reduced_word(w.reduced_word())
366
+ if (not w.reduced_word()) and excess != 0:
367
+ raise ValueError("excess must be 0 for the empty word")
368
+ return super().__classcall__(cls, w, factors, excess)
369
+
370
+ def __init__(self, w, factors, excess):
371
+ """
372
+ Initialize a set for ``self`` given reduced word ``w`` in the symmetric group,
373
+ number of factors ``factors`` and``excess`` extra letters.
374
+
375
+ EXAMPLES::
376
+
377
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
378
+ sage: S = SymmetricGroup(3+1)
379
+ sage: w = S.from_reduced_word([2, 1, 3, 2, 1])
380
+ sage: F = DecreasingHeckeFactorizations(w, 4, 2)
381
+ sage: F.w
382
+ (2, 1, 3, 2, 1)
383
+ sage: F.factors
384
+ 4
385
+ sage: F.excess
386
+ 2
387
+ sage: F.H
388
+ 0-Hecke monoid of the Symmetric group of order 4! as a permutation group
389
+
390
+ TESTS::
391
+
392
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
393
+ sage: S = SymmetricGroup(2+1)
394
+ sage: w = S.from_reduced_word([1, 2, 1])
395
+ sage: F = DecreasingHeckeFactorizations(w, 3, 1)
396
+ sage: TestSuite(F).run()
397
+ """
398
+ Parent.__init__(self, category=FiniteEnumeratedSets())
399
+ self.w = tuple(w.reduced_word())
400
+ self.factors = factors
401
+ self.H = w.parent()
402
+ self.max_value = len(self.H.gens())
403
+ self.excess = excess
404
+
405
+ def _repr_(self):
406
+ """
407
+ Return a representation of ``self``.
408
+
409
+ EXAMPLES::
410
+
411
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
412
+ sage: S = SymmetricGroup(3+1)
413
+ sage: w = S.from_reduced_word([2, 1, 3, 2])
414
+ sage: DecreasingHeckeFactorizations(w, 3, 1)
415
+ Decreasing Hecke factorizations with 3 factors associated to [2, 1, 3, 2] with excess 1
416
+ """
417
+ return "Decreasing Hecke factorizations with {} factors associated to {} with excess {}".format(self.factors, list(self.w), self.excess)
418
+
419
+ def list(self):
420
+ """
421
+ Return list of all elements of ``self``.
422
+
423
+ EXAMPLES::
424
+
425
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
426
+ sage: S = SymmetricGroup(3+1)
427
+ sage: w = S.from_reduced_word([1, 3, 2, 1])
428
+ sage: F = DecreasingHeckeFactorizations(w, 3, 3)
429
+ sage: F.list()
430
+ [(3, 1)(3, 1)(3, 2, 1), (3, 1)(3, 2, 1)(2, 1), (3, 2, 1)(2, 1)(2, 1)]
431
+ """
432
+ return _generate_decreasing_hecke_factorizations(self.w, self.factors, self.excess, parent=self)
433
+
434
+ # temporary workaround while an_element is overridden by Parent
435
+ _an_element_ = EnumeratedSets.ParentMethods._an_element_
436
+
437
+ Element = DecreasingHeckeFactorization
438
+
439
+
440
+ class FullyCommutativeStableGrothendieckCrystal(UniqueRepresentation, Parent):
441
+ """
442
+ The crystal on fully commutative decreasing factorizations in the 0-Hecke
443
+ monoid, as introduced by [MPPS2020]_.
444
+
445
+ INPUT:
446
+
447
+ - ``w`` -- an element in the symmetric group or a (skew) shape
448
+
449
+ - ``factors`` -- the number of factors in the factorization
450
+
451
+ - ``excess`` -- the total number of letters in the factorization minus the
452
+ length of a reduced word for ``w``
453
+
454
+ - ``shape`` -- boolean (default: ``False``); indicator for input ``w``,
455
+ ``True`` if ``w`` is entered as a (skew) shape and ``False`` otherwise
456
+
457
+ EXAMPLES::
458
+
459
+ sage: S = SymmetricGroup(3+1)
460
+ sage: w = S.from_reduced_word([1, 3, 2])
461
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2); B
462
+ Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 2
463
+ sage: B.list()
464
+ [(1)(3, 1)(3, 2),
465
+ (3, 1)(1)(3, 2),
466
+ (3, 1)(3, 1)(2),
467
+ (3)(3, 1)(3, 2),
468
+ (3, 1)(3)(3, 2),
469
+ (3, 1)(3, 2)(2)]
470
+
471
+ We can also access the crystal by specifying a skew shape::
472
+
473
+ sage: crystals.FullyCommutativeStableGrothendieck([[2, 2], [1]], 4, 1, shape=True)
474
+ Fully commutative stable Grothendieck crystal of type A_3 associated to [2, 1, 3] with excess 1
475
+
476
+ We can compute the highest weight elements::
477
+
478
+ sage: hw = [w for w in B if w.is_highest_weight()]
479
+ sage: hw
480
+ [(1)(3, 1)(3, 2), (3)(3, 1)(3, 2)]
481
+ sage: hw[0].weight()
482
+ (2, 2, 1)
483
+
484
+ The crystal operators themselves move elements between adjacent factors::
485
+
486
+ sage: b = hw[0]; b
487
+ (1)(3, 1)(3, 2)
488
+ sage: b.f(2)
489
+ (3, 1)(1)(3, 2)
490
+ """
491
+ @staticmethod
492
+ def __classcall_private__(cls, w, factors, excess, shape=False):
493
+ """
494
+ Classcall to mend the input.
495
+
496
+ EXAMPLES::
497
+
498
+ sage: A = crystals.FullyCommutativeStableGrothendieck([[3, 3], [2, 1]], 4, 1, shape=True); A
499
+ Fully commutative stable Grothendieck crystal of type A_3 associated to [3, 2, 4] with excess 1
500
+ sage: B = crystals.FullyCommutativeStableGrothendieck(SkewPartition([[3, 3], [2, 1]]), 4, 1, shape=True)
501
+ sage: A is B
502
+ True
503
+
504
+ sage: C = crystals.FullyCommutativeStableGrothendieck((2, 1), 3, 2, shape=True); C
505
+ Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 2
506
+ sage: D = crystals.FullyCommutativeStableGrothendieck(Partition([2, 1]), 3, 2, shape=True)
507
+ sage: C is D
508
+ True
509
+ """
510
+ from sage.monoids.hecke_monoid import HeckeMonoid
511
+ if shape:
512
+ from sage.combinat.partition import _Partitions
513
+ from sage.combinat.skew_partition import SkewPartition
514
+ cond1 = isinstance(w, (tuple, list)) and len(w) == 2 and w[0] in _Partitions and w[1] in _Partitions
515
+ cond2 = isinstance(w, SkewPartition)
516
+ if cond1 or cond2:
517
+ sh = SkewPartition([w[0], w[1]])
518
+ elif w in _Partitions:
519
+ sh = SkewPartition([w, []])
520
+ else:
521
+ raise ValueError("w needs to be a (skew) partition")
522
+ word = _to_reduced_word(sh)
523
+ max_value = max(word) if word else 1
524
+ H = HeckeMonoid(SymmetricGroup(max_value+1))
525
+ w = H.from_reduced_word(word)
526
+ else:
527
+ if isinstance(w.parent(), SymmetricGroup):
528
+ H = HeckeMonoid(w.parent())
529
+ w = H.from_reduced_word(w.reduced_word())
530
+ if (not w.reduced_word()) and excess != 0:
531
+ raise ValueError("excess must be 0 for the empty word")
532
+ return super().__classcall__(cls, w, factors, excess)
533
+
534
+ def __init__(self, w, factors, excess):
535
+ """
536
+ Initialize a crystal for ``self`` given reduced word ``w`` in the symmetric group,
537
+ number of factors ``factors`` and``excess`` extra letters.
538
+
539
+ EXAMPLES::
540
+
541
+ sage: S = SymmetricGroup(3+1)
542
+ sage: w = S.from_reduced_word([1, 3, 2])
543
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
544
+ sage: B.w
545
+ (1, 3, 2)
546
+ sage: B.factors
547
+ 3
548
+ sage: B.excess
549
+ 2
550
+ sage: B.H
551
+ 0-Hecke monoid of the Symmetric group of order 4! as a permutation group
552
+
553
+ The reduced word ``w`` should be fully commutative, that is, its
554
+ associated permutation should avoid the pattern 321::
555
+
556
+ sage: S = SymmetricGroup(3+1)
557
+ sage: w = S.from_reduced_word([1, 2, 1])
558
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
559
+ Traceback (most recent call last):
560
+ ...
561
+ ValueError: w should be fully commutative
562
+
563
+ TESTS::
564
+
565
+ sage: S = SymmetricGroup(3+1)
566
+ sage: w = S.from_reduced_word([2, 3, 1])
567
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
568
+ sage: TestSuite(B).run()
569
+ """
570
+ # Check if w is fully commutative
571
+ word = w.reduced_word()
572
+ p = permutation.from_reduced_word(word)
573
+ if p.has_pattern([3,2,1]):
574
+ raise ValueError("w should be fully commutative")
575
+
576
+ Parent.__init__(self, category=ClassicalCrystals())
577
+ self.w = tuple(word)
578
+ self.factors = factors
579
+ self.H = w.parent()
580
+ self.max_value = len(self.H.gens())
581
+ self.excess = excess
582
+ self._cartan_type = CartanType(['A', self.factors-1])
583
+
584
+ @lazy_attribute
585
+ def module_generators(self):
586
+ """
587
+ Return generators for ``self`` as a crystal.
588
+
589
+ EXAMPLES::
590
+
591
+ sage: S = SymmetricGroup(3+1)
592
+ sage: w = S.from_reduced_word([1, 3, 2])
593
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
594
+ sage: B.module_generators
595
+ ((1)(3, 1)(3, 2), (3)(3, 1)(3, 2))
596
+ sage: C = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
597
+ sage: C.module_generators
598
+ (()(1)(3, 1)(3, 2),
599
+ ()(3)(3, 1)(3, 2),
600
+ (1)(1)(1)(3, 2),
601
+ (1)(1)(3)(3, 2),
602
+ (1)(3)(3)(3, 2))
603
+ """
604
+ return tuple(self(x).to_highest_weight()[0] for x in _lowest_weights(self.w, self.factors, self.excess, parent=self))
605
+
606
+ def _repr_(self):
607
+ """
608
+ Return a representation of ``self``.
609
+
610
+ EXAMPLES::
611
+
612
+ sage: S = SymmetricGroup(3+1)
613
+ sage: w = S.from_reduced_word([2, 1, 3, 2])
614
+ sage: crystals.FullyCommutativeStableGrothendieck(w, 3, 1)
615
+ Fully commutative stable Grothendieck crystal of type A_2 associated to [2, 1, 3, 2] with excess 1
616
+ """
617
+ return "Fully commutative stable Grothendieck crystal of type A_{} associated to {} with excess {}".format(self.factors-1, list(self.w), self.excess)
618
+
619
+ class Element(DecreasingHeckeFactorization):
620
+ def __init__(self, parent, t):
621
+ """
622
+ Create an instance ``self`` of element ``t``.
623
+
624
+ This method takes into account the constraints on the word,
625
+ the number of factors, and excess statistic associated to the parent class.
626
+
627
+ EXAMPLES::
628
+
629
+ sage: S = SymmetricGroup(3+1)
630
+ sage: w = S.from_reduced_word([1, 3, 2])
631
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
632
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
633
+ sage: h = DecreasingHeckeFactorization([[3, 1], [3], [3, 2]], 4)
634
+ sage: u = B(h); u.value
635
+ ((3, 1), (3,), (3, 2))
636
+ sage: v = B([[3, 1], [3], [3, 2]]); v.value
637
+ ((3, 1), (3,), (3, 2))
638
+ """
639
+ u = t
640
+ if isinstance(t, DecreasingHeckeFactorization):
641
+ u = t.value
642
+ _check_decreasing_hecke_factorization(t)
643
+ _check_containment(t, parent)
644
+ DecreasingHeckeFactorization.__init__(self, parent, u)
645
+
646
+ def e(self, i):
647
+ """
648
+ Return the action of `e_i` on ``self`` using the rules described in [MPPS2020]_.
649
+
650
+ EXAMPLES::
651
+
652
+ sage: S = SymmetricGroup(4+1)
653
+ sage: w = S.from_reduced_word([2, 1, 4, 3, 2])
654
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 3)
655
+ sage: h = B([[4, 2], [4, 2, 1], [3, 2], [2]]); h
656
+ (4, 2)(4, 2, 1)(3, 2)(2)
657
+ sage: h.e(1)
658
+ (4, 2)(4, 2, 1)(3)(3, 2)
659
+ sage: h.e(2)
660
+ (4, 2)(2, 1)(4, 3, 2)(2)
661
+ sage: h.e(3)
662
+ """
663
+ P = self.parent()
664
+ m = P.factors
665
+ L = list(self.value[m-i-1])
666
+ R = list(self.value[m-i])
667
+ b = self.bracketing(i)
668
+ if not b[0]:
669
+ return None
670
+ y = b[0][-1]
671
+ if y-1 in L and y-1 in R:
672
+ # special case: (--x+1--)(--x+1,x--) -->> (--x+1,x--)(--x--)
673
+ L.remove(y-1)
674
+ else:
675
+ L.remove(y)
676
+ R.append(y)
677
+ L.sort(reverse=True)
678
+ R.sort(reverse=True)
679
+ s = [self.value[j] for j in range(m-i-1)]+[L]+[R]+[self.value[j] for j in range(m-i+1, m)]
680
+ return P.element_class(P, s)
681
+
682
+ def f(self, i):
683
+ """
684
+ Return the action of `f_i` on ``self`` using the rules described in [MPPS2020]_.
685
+
686
+ EXAMPLES::
687
+
688
+ sage: S = SymmetricGroup(4+1)
689
+ sage: w = S.from_reduced_word([3, 2, 1, 4, 3])
690
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 3)
691
+ sage: h = B([[3, 2], [2, 1], [4, 3], [3, 1]]); h
692
+ (3, 2)(2, 1)(4, 3)(3, 1)
693
+ sage: h.f(1)
694
+ (3, 2)(2, 1)(4, 3, 1)(3)
695
+ sage: h.f(2)
696
+ sage: h.f(3)
697
+ (3, 2, 1)(1)(4, 3)(3, 1)
698
+ """
699
+ P = self.parent()
700
+ m = P.factors
701
+ L = list(self.value[m-i-1])
702
+ R = list(self.value[m-i])
703
+ b = self.bracketing(i)
704
+ if not b[1]:
705
+ return None
706
+ x = b[1][0]
707
+ if x+1 in L and x+1 in R:
708
+ # special case: (--x+1--)(--x+1,x--) -->> (--x+1,x--)(--x--)
709
+ R.remove(x+1)
710
+ else:
711
+ R.remove(x)
712
+ L.append(x)
713
+ L.sort(reverse=True)
714
+ R.sort(reverse=True)
715
+ s = [self.value[j] for j in range(m-i-1)]+[L]+[R]+[self.value[j] for j in range(m-i+1, m)]
716
+ return P.element_class(P, s)
717
+
718
+ def bracketing(self, i):
719
+ """
720
+ Remove all bracketed letters between `i`-th and `(i+1)`-th entry.
721
+
722
+ EXAMPLES::
723
+
724
+ sage: S = SymmetricGroup(4+1)
725
+ sage: w = S.from_reduced_word([3, 2, 1, 4, 3])
726
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
727
+ sage: h = B([[3], [4, 2, 1], [4, 3, 1]])
728
+ sage: h.bracketing(1)
729
+ [[], []]
730
+ sage: h.bracketing(2)
731
+ [[], [2, 1]]
732
+ """
733
+ P = self.parent()
734
+ m = P.factors
735
+ L = list(self.value[m-i-1])
736
+ R = list(self.value[m-i])
737
+ right_n = list(R)
738
+ left_n = list(L)
739
+ left_unbracketed = []
740
+ while left_n:
741
+ m = max(left_n)
742
+ left_n.remove(m)
743
+ l = [j for j in right_n if j >= m]
744
+ if l:
745
+ right_n.remove(min(l))
746
+ else:
747
+ left_unbracketed += [m]
748
+ return [list(left_unbracketed), list(right_n)]
749
+
750
+
751
+ ####################
752
+ # Helper functions #
753
+ ####################
754
+
755
+ def _check_decreasing_hecke_factorization(t):
756
+ """
757
+ Check if ``t`` is a suitable data type for a decreasing factorization in a 0-Hecke monoid.
758
+
759
+ EXAMPLES::
760
+
761
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _check_decreasing_hecke_factorization
762
+ sage: _check_decreasing_hecke_factorization([[3, 2], [2, 1], [4]])
763
+ sage: _check_decreasing_hecke_factorization([[3, 2, 2], [2, 1], [4]])
764
+ Traceback (most recent call last):
765
+ ...
766
+ ValueError: each nonempty factor should be a strictly decreasing sequence
767
+ sage: _check_decreasing_hecke_factorization([[3, 'a'], [2, 1], [4]])
768
+ Traceback (most recent call last):
769
+ ...
770
+ ValueError: each nonempty factor should contain integers
771
+ sage: _check_decreasing_hecke_factorization([[3, 2], [2, 1], 4])
772
+ Traceback (most recent call last):
773
+ ...
774
+ ValueError: each factor in t should be a list or tuple
775
+ """
776
+ if not isinstance(t, DecreasingHeckeFactorization):
777
+ if not isinstance(t, (tuple, list)):
778
+ raise ValueError("t should be a list or tuple")
779
+ for factor in t:
780
+ if not isinstance(factor, (tuple, list)):
781
+ raise ValueError("each factor in t should be a list or tuple")
782
+ if not all(isinstance(x,(int, Integer)) for x in factor):
783
+ raise ValueError("each nonempty factor should contain integers")
784
+ for i in range(len(factor)-1):
785
+ if factor[i] <= factor[i+1]:
786
+ raise ValueError("each nonempty factor should be a strictly decreasing sequence")
787
+
788
+
789
+ def _check_containment(t, parent):
790
+ """
791
+ Check if ``t`` is an element of ``parent``.
792
+
793
+ EXAMPLES::
794
+
795
+ sage: S = SymmetricGroup(3+1)
796
+ sage: w = S.from_reduced_word([1, 3, 2])
797
+ sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
798
+
799
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization, _check_containment
800
+ sage: h1 = DecreasingHeckeFactorization([[3, 1], [3], [3, 2]], 4)
801
+ sage: _check_containment(h1, B)
802
+
803
+ sage: h2 = DecreasingHeckeFactorization([[3, 1], [3], [], [3, 2]])
804
+ sage: _check_containment(h2, B)
805
+ Traceback (most recent call last):
806
+ ...
807
+ ValueError: number of factors do not match
808
+
809
+ sage: h3 = [[3, 1], [2], [3, 2]]
810
+ sage: _check_containment(h3, B)
811
+ Traceback (most recent call last):
812
+ ...
813
+ ValueError: self and parent must be specified based on equivalent words
814
+
815
+ sage: h4 = DecreasingHeckeFactorization([[3, 1], [3, 1], [3, 2]], 3)
816
+ sage: _check_containment(h4, B)
817
+ Traceback (most recent call last):
818
+ ...
819
+ ValueError: number of excess letters do not match
820
+ """
821
+ if isinstance(t, DecreasingHeckeFactorization):
822
+ factors = t.factors
823
+ w = t.w
824
+ excess = t.excess
825
+ else:
826
+ factors = len(t)
827
+ max_value = parent.max_value
828
+ from sage.monoids.hecke_monoid import HeckeMonoid
829
+ H = HeckeMonoid(SymmetricGroup(max_value+1))
830
+ w = tuple(H.from_reduced_word(x for factor in t for x in factor).reduced_word())
831
+ excess = sum(len(l) for l in t) - len(w)
832
+
833
+ if factors != parent.factors:
834
+ raise ValueError("number of factors do not match")
835
+ if w != parent.w:
836
+ raise ValueError("self and parent must be specified based on equivalent words")
837
+ if excess != parent.excess:
838
+ raise ValueError("number of excess letters do not match")
839
+
840
+
841
+ def _generate_decreasing_hecke_factorizations(w, factors, ex, weight=None, parent=None):
842
+ """
843
+ Generate all decreasing factorizations of word ``w`` in a 0-Hecke monoid
844
+ with fixed excess and number of factors.
845
+
846
+ INPUT:
847
+
848
+ - ``w`` -- a reduced word, expressed as an iterable
849
+
850
+ - ``factors`` -- number of factors for each decreasing factorization
851
+
852
+ - ``ex`` -- number of extra letters in each decreasing factorizations
853
+
854
+ - ``weight`` -- (default: ``None``) if ``None``, returns all possible
855
+ decreasing factorizations, otherwise return all those with the specified
856
+ weight
857
+
858
+ EXAMPLES::
859
+
860
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _generate_decreasing_hecke_factorizations
861
+ sage: _generate_decreasing_hecke_factorizations([1, 2, 1], 3, 1)
862
+ [()(2, 1)(2, 1),
863
+ (2)(1)(2, 1),
864
+ (1)(2)(2, 1),
865
+ (1)(1)(2, 1),
866
+ (2, 1)()(2, 1),
867
+ (2)(2, 1)(2),
868
+ (1)(2, 1)(2),
869
+ (1)(2, 1)(1),
870
+ (2, 1)(2)(2),
871
+ (2, 1)(2)(1),
872
+ (2, 1)(1)(2),
873
+ (2, 1)(2, 1)()]
874
+
875
+ sage: _generate_decreasing_hecke_factorizations([1, 2, 1], 3, 1, weight=[1, 1, 2])
876
+ [(2, 1)(2)(2), (2, 1)(2)(1), (2, 1)(1)(2)]
877
+ """
878
+ if parent is None:
879
+ max_value = max(w) if w else 1
880
+ S = SymmetricGroup(max_value+1)
881
+ v = S.from_reduced_word(w)
882
+ parent = DecreasingHeckeFactorizations(v, factors, ex)
883
+
884
+ _canonical_word = lambda w, ex: [list(w)[0]]*ex + list(w)
885
+ wt = lambda t:[len(factor) for factor in reversed(t)]
886
+
887
+ L = _list_equivalent_words(_canonical_word(w, ex))
888
+ Factors = []
889
+ for word in L:
890
+ F = _list_all_decreasing_runs(word, factors)
891
+ for f in F:
892
+ t = [[word[j] for j in range(len(word)) if f[j] == i] for i in range(factors, 0, -1)]
893
+ if weight is None or weight == wt(t):
894
+ Factors.append(parent.element_class(parent, t))
895
+ return sorted(Factors, reverse=True)
896
+
897
+
898
+ def _list_all_decreasing_runs(word, m):
899
+ """
900
+ List all possible decreasing runs into ``m`` factors for ``word`` in a
901
+ 0-Hecke monoid.
902
+
903
+ EXAMPLES::
904
+
905
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _list_all_decreasing_runs
906
+ sage: _list_all_decreasing_runs([2, 1, 2, 1], 3)
907
+ [[2, 2, 1, 1], [3, 2, 1, 1], [3, 3, 1, 1], [3, 3, 2, 1], [3, 3, 2, 2]]
908
+ """
909
+ from sage.combinat.integer_vector import IntegerVectors
910
+ J = _jumps(word)
911
+ jump_vector = [1]+[int(j in J) for j in range(1, len(word))]
912
+ I = sorted(IntegerVectors(m-1-len(J), len(word)+1), reverse=True)
913
+ P = [[elt[i]+jump_vector[i] for i in range(len(word))] for elt in I]
914
+ V = [[m+1-sum(elt[:i+1]) for i in range(len(elt))] for elt in P]
915
+ return V
916
+
917
+
918
+ def _to_reduced_word(P):
919
+ """
920
+ Return a reduced word associated to skew partition ``P``.
921
+
922
+ EXAMPLES::
923
+
924
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
925
+ sage: P = SkewPartition([[2, 2], [1]])
926
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
927
+ sage: _to_reduced_word(P)
928
+ [2, 1, 3]
929
+
930
+ sage: P = SkewPartition([[], []])
931
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
932
+ sage: _to_reduced_word(P)
933
+ []
934
+
935
+ sage: P = SkewPartition([[2, 1], []])
936
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
937
+ sage: _to_reduced_word(P)
938
+ [1, 3, 2]
939
+ """
940
+ cells = P.cells()
941
+ if not cells:
942
+ return []
943
+ m = max(cell[0] for cell in cells) + 1
944
+ n = max(cell[1] for cell in cells) + 1
945
+ L = []
946
+ for i in range(m, -1, -1):
947
+ for j in range(n, -1, -1):
948
+ if (i, j) in cells:
949
+ L += [j-i+m]
950
+ return L
951
+
952
+
953
+ def _lowest_weights(w, factors, ex, parent=None):
954
+ """
955
+ Generate all decreasing factorizations in the 0-Hecke monoid that correspond
956
+ to some valid semistandard Young tableaux.
957
+
958
+ The semistandard Young tableaux should have at most ``factors`` columns and their
959
+ column reading words should be equivalent to ``w`` in a 0-Hecke monoid.
960
+
961
+ INPUT:
962
+
963
+ - ``w`` -- a fully commutative reduced word, expressed as an iterable
964
+
965
+ - ``factors`` -- number of factors for each decreasing factorization
966
+
967
+ - ``ex`` -- number of extra letters in each decreasing factorizations
968
+
969
+ - ``parent`` -- (default: ``None``) parent of the decreasing
970
+ factorizations, automatically assigned if it is None
971
+
972
+ EXAMPLES::
973
+
974
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _lowest_weights
975
+ sage: _lowest_weights([1, 2, 1], 3, 1)
976
+ Traceback (most recent call last):
977
+ ...
978
+ ValueError: the word w should be fully commutative
979
+
980
+ sage: _lowest_weights([2, 1, 3, 2], 4, 3)
981
+ [(2, 1)(3, 1)(3, 1)(2), (2, 1)(3, 1)(3, 2)(2)]
982
+
983
+ sage: _lowest_weights([2, 1, 3, 2], 5, 3)
984
+ [(2, 1)(3, 1)(3, 1)(2)(),
985
+ (2, 1)(3, 1)(3, 2)(2)(),
986
+ (2, 1)(3, 1)(1)(1)(2),
987
+ (2, 1)(3, 1)(1)(2)(2),
988
+ (2, 1)(3, 1)(2)(2)(2),
989
+ (2, 1)(3, 2)(2)(2)(2)]
990
+
991
+ sage: _lowest_weights([1, 3], 3, 1)
992
+ [(3, 1)(1)(), (3, 1)(3)(), (1)(1)(3), (1)(3)(3)]
993
+
994
+ sage: _lowest_weights([3, 2, 1], 5, 2)
995
+ [(3, 2, 1)(1)(1)()()]
996
+ """
997
+ p = permutation.from_reduced_word(w)
998
+ if p.has_pattern([3,2,1]):
999
+ raise ValueError("the word w should be fully commutative")
1000
+ if parent is None:
1001
+ k = max(w)
1002
+ S = SymmetricGroup(k+1)
1003
+ word = S.from_reduced_word(w)
1004
+ parent = FullyCommutativeStableGrothendieckCrystal(word, factors, ex)
1005
+
1006
+ _canonical_word = lambda w, ex: [list(w)[0]]*ex + list(w)
1007
+ L = _list_equivalent_words(_canonical_word(w, ex))
1008
+
1009
+ M = []
1010
+ for v in L:
1011
+ if _is_valid_column_word(v, factors):
1012
+ J = [0] + _jumps(v) + [len(v)]
1013
+ t = [v[J[i]:J[i+1]] for i in range(len(J)-1)]
1014
+ if len(J) < factors+1:
1015
+ t += [()]*(factors+1-len(J))
1016
+ M.append(parent.element_class(parent, t))
1017
+ return sorted(M)
1018
+
1019
+
1020
+ def _jumps(w):
1021
+ """
1022
+ Detect all positions where letters weakly increase in ``w``.
1023
+
1024
+ EXAMPLES::
1025
+
1026
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _jumps
1027
+ sage: w = [4, 1, 2, 1, 4, 3, 2, 1, 3, 2, 2]
1028
+ sage: _jumps(w)
1029
+ [2, 4, 8, 10]
1030
+ """
1031
+ return [i+1 for i in range(len(w)-1) if w[i] <= w[i+1]]
1032
+
1033
+
1034
+ def _is_valid_column_word(w, m=None):
1035
+ """
1036
+ Determine if ``w`` is actually a valid column reading word of some
1037
+ semistandard Young tableau with at most ``m`` columns.
1038
+
1039
+ If ``m`` is None, then we determine if ``w`` is a valid column reading word
1040
+ of some semistandard Young tableau.
1041
+
1042
+ EXAMPLES::
1043
+
1044
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _is_valid_column_word
1045
+ sage: w = [3, 2, 2, 1, 1]
1046
+ sage: _is_valid_column_word(w)
1047
+ False
1048
+
1049
+ sage: w = [3, 2, 1, 1, 1]
1050
+ sage: _is_valid_column_word(w,3)
1051
+ True
1052
+
1053
+ sage: w = [3, 2, 1, 1, 1]
1054
+ sage: _is_valid_column_word(w,2)
1055
+ False
1056
+
1057
+ sage: w = [3, 2, 1, 3, 1]
1058
+ sage: _is_valid_column_word(w,2)
1059
+ True
1060
+ """
1061
+ J = [0] + _jumps(w) + [len(w)]
1062
+ L = [w[J[i+1]-1:J[i]:-1] for i in range(len(J)-1)]
1063
+ if all(len(L[i]) >= len(L[i+1]) for i in range(len(L)-1)):
1064
+ if m is None or len(_jumps(w)) <= m-1:
1065
+ # By construction the sequences along rows of L are strictly
1066
+ # decreasing, so it remains to verify that the sequences along
1067
+ # columns of L are weakly increasing
1068
+ return all(L[i+1][j] >= L[i][j] for i in range(len(L)-1)
1069
+ for j in range(len(L[i+1])))
1070
+ return False
1071
+
1072
+
1073
+ def _list_equivalent_words(w):
1074
+ """
1075
+ List all words equivalent to ``w`` in a 0-Hecke monoid.
1076
+
1077
+ EXAMPLES::
1078
+
1079
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _list_equivalent_words
1080
+ sage: _list_equivalent_words([1, 1, 2, 1])
1081
+ [(1, 1, 2, 1),
1082
+ (1, 2, 1, 1),
1083
+ (1, 2, 1, 2),
1084
+ (1, 2, 2, 1),
1085
+ (2, 1, 1, 2),
1086
+ (2, 1, 2, 1),
1087
+ (2, 1, 2, 2),
1088
+ (2, 2, 1, 2)]
1089
+
1090
+ sage: _list_equivalent_words([2,1,3,1,2])
1091
+ [(2, 1, 1, 3, 2),
1092
+ (2, 1, 3, 1, 2),
1093
+ (2, 1, 3, 2, 2),
1094
+ (2, 1, 3, 3, 2),
1095
+ (2, 2, 1, 3, 2),
1096
+ (2, 2, 3, 1, 2),
1097
+ (2, 3, 1, 1, 2),
1098
+ (2, 3, 1, 2, 2),
1099
+ (2, 3, 1, 3, 2),
1100
+ (2, 3, 3, 1, 2)]
1101
+ """
1102
+ if all(isinstance(i, (int, Integer)) for i in w):
1103
+ u = w
1104
+ else:
1105
+ raise ValueError("w needs to be a tuple of integers")
1106
+
1107
+ def _applicable_relations(word):
1108
+ """
1109
+ Return all positions where a relation can be applied on ``word``
1110
+ along with the type of relation.
1111
+ """
1112
+ L = []
1113
+ for i in range(len(word)-2):
1114
+ p, q, r = word[i:(i+2)+1]
1115
+ if abs(p-q) > 1:
1116
+ L += [[i,"pq=qp"]]
1117
+ elif abs(p-q) == 1:
1118
+ if p == r: # p != q by the abs test
1119
+ L += [[i,"pqp=qpq"]]
1120
+ elif r != p: # We must have p == q
1121
+ L += [[i,"ppq=pqq"]]
1122
+ if q == r and r != p:
1123
+ L += [[i,"pqq=ppq"]]
1124
+ if len(word) > 1 and abs(word[-2]-word[-1]) > 1:
1125
+ L += [[len(word)-2,"pq=qp"]]
1126
+ return L
1127
+
1128
+ V = set()
1129
+ queue = [tuple(u)]
1130
+ while queue:
1131
+ v = queue.pop(0)
1132
+ if tuple(v) not in V:
1133
+ V.add(tuple(v))
1134
+ L = _applicable_relations(v)
1135
+ for pair in L:
1136
+ position, move = pair
1137
+ t = _apply_relations(v, position, move)
1138
+ queue += [tuple(t)]
1139
+ return sorted(v for v in list(V))
1140
+
1141
+
1142
+ def _apply_relations(word, position, move):
1143
+ """
1144
+ Apply a particular type of ``move`` on ``word`` at the specified
1145
+ ``position`` using a relation in a 0-Hecke monoid .
1146
+
1147
+ EXAMPLES::
1148
+
1149
+ sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _apply_relations
1150
+ sage: w = [2, 1, 3, 4]
1151
+ sage: _apply_relations(w, position=1, move='pq=qp')
1152
+ [2, 3, 1, 4]
1153
+
1154
+ sage: w = [1, 3, 2, 1, 2, 4]
1155
+ sage: _apply_relations(w, position=2, move='pqp=qpq')
1156
+ [1, 3, 1, 2, 1, 4]
1157
+
1158
+ sage: w = [2, 3, 1, 2, 2, 3]
1159
+ sage: _apply_relations(w, position=3, move='pp=p')
1160
+ [2, 3, 1, 2, 3]
1161
+
1162
+ sage: w = [2, 3, 1, 2, 3]
1163
+ sage: _apply_relations(w, position=3, move='p=pp')
1164
+ [2, 3, 1, 2, 2, 3]
1165
+
1166
+ sage: w = [2, 3, 1, 2, 2, 3]
1167
+ sage: _apply_relations(w, position=2, move='pqq=ppq')
1168
+ [2, 3, 1, 1, 2, 3]
1169
+
1170
+ sage: w = [2, 3, 1, 1, 2, 3]
1171
+ sage: _apply_relations(w, position=2, move='ppq=pqq')
1172
+ [2, 3, 1, 2, 2, 3]
1173
+ """
1174
+ w = list(word)
1175
+ # Type 1
1176
+ if move == "pq=qp":
1177
+ p = w[position]
1178
+ q = w[position+1]
1179
+ w[position] = q
1180
+ w[position+1] = p
1181
+ # Type 2
1182
+ elif move == "pqp=qpq":
1183
+ p = w[position]
1184
+ q = w[position+1]
1185
+ w[position] = q
1186
+ w[position+1] = p
1187
+ w[position+2] = q
1188
+ # Type 3
1189
+ elif move == "pqq=ppq":
1190
+ p = w[position]
1191
+ q = w[position+2]
1192
+ w[position+1] = p
1193
+ # Type 4
1194
+ elif move == "ppq=pqq":
1195
+ p = w[position]
1196
+ q = w[position+2]
1197
+ w[position+1] = q
1198
+ # Type 5
1199
+ elif move == "pp=p":
1200
+ p = w[position]
1201
+ w = w[:position+1] + w[position+2:]
1202
+ elif move == "p=pp":
1203
+ p = w[position]
1204
+ w = w[:position+1] + [p] + w[position+1:]
1205
+ return w