passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
  3. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  4. passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
  5. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  6. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  7. passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
  8. passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
  9. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  10. sage/algebras/all.py +24 -0
  11. sage/algebras/all__sagemath_combinat.py +35 -0
  12. sage/algebras/askey_wilson.py +935 -0
  13. sage/algebras/associated_graded.py +345 -0
  14. sage/algebras/cellular_basis.py +350 -0
  15. sage/algebras/cluster_algebra.py +2766 -0
  16. sage/algebras/down_up_algebra.py +860 -0
  17. sage/algebras/free_algebra.py +1698 -0
  18. sage/algebras/free_algebra_element.py +345 -0
  19. sage/algebras/free_algebra_quotient.py +405 -0
  20. sage/algebras/free_algebra_quotient_element.py +295 -0
  21. sage/algebras/free_zinbiel_algebra.py +885 -0
  22. sage/algebras/hall_algebra.py +783 -0
  23. sage/algebras/hecke_algebras/all.py +4 -0
  24. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  25. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  28. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  29. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  30. sage/algebras/jordan_algebra.py +1773 -0
  31. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  32. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  33. sage/algebras/lie_conformal_algebras/all.py +18 -0
  34. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  35. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  36. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  37. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  38. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  39. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  40. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  41. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  45. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  46. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  47. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  48. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  49. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  50. sage/algebras/nil_coxeter_algebra.py +191 -0
  51. sage/algebras/q_commuting_polynomials.py +673 -0
  52. sage/algebras/q_system.py +608 -0
  53. sage/algebras/quantum_clifford.py +959 -0
  54. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  55. sage/algebras/quantum_groups/all.py +9 -0
  56. sage/algebras/quantum_groups/fock_space.py +2219 -0
  57. sage/algebras/quantum_groups/q_numbers.py +207 -0
  58. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  59. sage/algebras/quantum_groups/representations.py +591 -0
  60. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  61. sage/algebras/quantum_oscillator.py +623 -0
  62. sage/algebras/quaternion_algebra.py +20 -0
  63. sage/algebras/quaternion_algebra_element.py +55 -0
  64. sage/algebras/rational_cherednik_algebra.py +525 -0
  65. sage/algebras/schur_algebra.py +670 -0
  66. sage/algebras/shuffle_algebra.py +1011 -0
  67. sage/algebras/splitting_algebra.py +779 -0
  68. sage/algebras/tensor_algebra.py +709 -0
  69. sage/algebras/yangian.py +1082 -0
  70. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  71. sage/all__sagemath_combinat.py +44 -0
  72. sage/combinat/SJT.py +255 -0
  73. sage/combinat/affine_permutation.py +2405 -0
  74. sage/combinat/algebraic_combinatorics.py +55 -0
  75. sage/combinat/all.py +53 -0
  76. sage/combinat/all__sagemath_combinat.py +195 -0
  77. sage/combinat/alternating_sign_matrix.py +2063 -0
  78. sage/combinat/baxter_permutations.py +346 -0
  79. sage/combinat/bijectionist.py +3220 -0
  80. sage/combinat/binary_recurrence_sequences.py +1180 -0
  81. sage/combinat/blob_algebra.py +685 -0
  82. sage/combinat/catalog_partitions.py +27 -0
  83. sage/combinat/chas/all.py +23 -0
  84. sage/combinat/chas/fsym.py +1180 -0
  85. sage/combinat/chas/wqsym.py +2601 -0
  86. sage/combinat/cluster_complex.py +326 -0
  87. sage/combinat/colored_permutations.py +2039 -0
  88. sage/combinat/colored_permutations_representations.py +964 -0
  89. sage/combinat/composition_signed.py +142 -0
  90. sage/combinat/composition_tableau.py +855 -0
  91. sage/combinat/constellation.py +1729 -0
  92. sage/combinat/core.py +751 -0
  93. sage/combinat/counting.py +12 -0
  94. sage/combinat/crystals/affine.py +742 -0
  95. sage/combinat/crystals/affine_factorization.py +518 -0
  96. sage/combinat/crystals/affinization.py +331 -0
  97. sage/combinat/crystals/alcove_path.py +2013 -0
  98. sage/combinat/crystals/all.py +22 -0
  99. sage/combinat/crystals/bkk_crystals.py +141 -0
  100. sage/combinat/crystals/catalog.py +115 -0
  101. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  102. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  103. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  104. sage/combinat/crystals/crystals.py +257 -0
  105. sage/combinat/crystals/direct_sum.py +260 -0
  106. sage/combinat/crystals/elementary_crystals.py +1251 -0
  107. sage/combinat/crystals/fast_crystals.py +441 -0
  108. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  109. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  110. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  111. sage/combinat/crystals/induced_structure.py +695 -0
  112. sage/combinat/crystals/infinity_crystals.py +730 -0
  113. sage/combinat/crystals/kac_modules.py +863 -0
  114. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  115. sage/combinat/crystals/kyoto_path_model.py +497 -0
  116. sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
  117. sage/combinat/crystals/letters.pxd +79 -0
  118. sage/combinat/crystals/letters.pyx +3056 -0
  119. sage/combinat/crystals/littelmann_path.py +1518 -0
  120. sage/combinat/crystals/monomial_crystals.py +1262 -0
  121. sage/combinat/crystals/multisegments.py +462 -0
  122. sage/combinat/crystals/mv_polytopes.py +467 -0
  123. sage/combinat/crystals/pbw_crystal.py +511 -0
  124. sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
  125. sage/combinat/crystals/pbw_datum.pxd +4 -0
  126. sage/combinat/crystals/pbw_datum.pyx +487 -0
  127. sage/combinat/crystals/polyhedral_realization.py +372 -0
  128. sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
  129. sage/combinat/crystals/spins.pxd +21 -0
  130. sage/combinat/crystals/spins.pyx +756 -0
  131. sage/combinat/crystals/star_crystal.py +290 -0
  132. sage/combinat/crystals/subcrystal.py +464 -0
  133. sage/combinat/crystals/tensor_product.py +1177 -0
  134. sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
  135. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  136. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  137. sage/combinat/crystals/virtual_crystal.py +420 -0
  138. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  139. sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
  140. sage/combinat/debruijn_sequence.pyx +355 -0
  141. sage/combinat/decorated_permutation.py +270 -0
  142. sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
  143. sage/combinat/degree_sequences.pyx +588 -0
  144. sage/combinat/derangements.py +527 -0
  145. sage/combinat/descent_algebra.py +1008 -0
  146. sage/combinat/diagram.py +1551 -0
  147. sage/combinat/diagram_algebras.py +5886 -0
  148. sage/combinat/dyck_word.py +4349 -0
  149. sage/combinat/e_one_star.py +1623 -0
  150. sage/combinat/enumerated_sets.py +123 -0
  151. sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
  152. sage/combinat/expnums.pyx +148 -0
  153. sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
  154. sage/combinat/fast_vector_partitions.pyx +346 -0
  155. sage/combinat/fqsym.py +1977 -0
  156. sage/combinat/free_dendriform_algebra.py +954 -0
  157. sage/combinat/free_prelie_algebra.py +1141 -0
  158. sage/combinat/fully_commutative_elements.py +1077 -0
  159. sage/combinat/fully_packed_loop.py +1523 -0
  160. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  161. sage/combinat/gray_codes.py +311 -0
  162. sage/combinat/grossman_larson_algebras.py +667 -0
  163. sage/combinat/growth.py +4352 -0
  164. sage/combinat/hall_polynomial.py +188 -0
  165. sage/combinat/hillman_grassl.py +866 -0
  166. sage/combinat/integer_matrices.py +329 -0
  167. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  168. sage/combinat/k_tableau.py +4564 -0
  169. sage/combinat/kazhdan_lusztig.py +215 -0
  170. sage/combinat/key_polynomial.py +885 -0
  171. sage/combinat/knutson_tao_puzzles.py +2286 -0
  172. sage/combinat/lr_tableau.py +311 -0
  173. sage/combinat/matrices/all.py +24 -0
  174. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  175. sage/combinat/matrices/latin.py +2912 -0
  176. sage/combinat/misc.py +401 -0
  177. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  178. sage/combinat/ncsf_qsym/all.py +21 -0
  179. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  180. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  181. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  182. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  183. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  184. sage/combinat/ncsym/all.py +21 -0
  185. sage/combinat/ncsym/bases.py +855 -0
  186. sage/combinat/ncsym/dual.py +593 -0
  187. sage/combinat/ncsym/ncsym.py +2076 -0
  188. sage/combinat/necklace.py +551 -0
  189. sage/combinat/non_decreasing_parking_function.py +634 -0
  190. sage/combinat/nu_dyck_word.py +1474 -0
  191. sage/combinat/output.py +861 -0
  192. sage/combinat/parallelogram_polyomino.py +4326 -0
  193. sage/combinat/parking_functions.py +1602 -0
  194. sage/combinat/partition_algebra.py +1998 -0
  195. sage/combinat/partition_kleshchev.py +1982 -0
  196. sage/combinat/partition_shifting_algebras.py +584 -0
  197. sage/combinat/partition_tuple.py +3114 -0
  198. sage/combinat/path_tableaux/all.py +13 -0
  199. sage/combinat/path_tableaux/catalog.py +29 -0
  200. sage/combinat/path_tableaux/dyck_path.py +380 -0
  201. sage/combinat/path_tableaux/frieze.py +476 -0
  202. sage/combinat/path_tableaux/path_tableau.py +728 -0
  203. sage/combinat/path_tableaux/semistandard.py +510 -0
  204. sage/combinat/perfect_matching.py +779 -0
  205. sage/combinat/plane_partition.py +3300 -0
  206. sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
  207. sage/combinat/q_bernoulli.pyx +128 -0
  208. sage/combinat/quickref.py +81 -0
  209. sage/combinat/recognizable_series.py +2051 -0
  210. sage/combinat/regular_sequence.py +4316 -0
  211. sage/combinat/regular_sequence_bounded.py +543 -0
  212. sage/combinat/restricted_growth.py +81 -0
  213. sage/combinat/ribbon.py +20 -0
  214. sage/combinat/ribbon_shaped_tableau.py +489 -0
  215. sage/combinat/ribbon_tableau.py +1180 -0
  216. sage/combinat/rigged_configurations/all.py +46 -0
  217. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  218. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  219. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  222. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  223. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  224. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  225. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  226. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  227. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  228. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  229. sage/combinat/rigged_configurations/bijection.py +143 -0
  230. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  231. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  232. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  233. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  234. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  235. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  236. sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  238. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  240. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  241. sage/combinat/rsk.py +3438 -0
  242. sage/combinat/schubert_polynomial.py +508 -0
  243. sage/combinat/set_partition.py +3318 -0
  244. sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
  245. sage/combinat/set_partition_iterator.pyx +136 -0
  246. sage/combinat/set_partition_ordered.py +1590 -0
  247. sage/combinat/sf/abreu_nigro.py +346 -0
  248. sage/combinat/sf/all.py +52 -0
  249. sage/combinat/sf/character.py +576 -0
  250. sage/combinat/sf/classical.py +319 -0
  251. sage/combinat/sf/dual.py +996 -0
  252. sage/combinat/sf/elementary.py +549 -0
  253. sage/combinat/sf/hall_littlewood.py +1028 -0
  254. sage/combinat/sf/hecke.py +336 -0
  255. sage/combinat/sf/homogeneous.py +464 -0
  256. sage/combinat/sf/jack.py +1428 -0
  257. sage/combinat/sf/k_dual.py +1458 -0
  258. sage/combinat/sf/kfpoly.py +447 -0
  259. sage/combinat/sf/llt.py +789 -0
  260. sage/combinat/sf/macdonald.py +2019 -0
  261. sage/combinat/sf/monomial.py +525 -0
  262. sage/combinat/sf/multiplicative.py +113 -0
  263. sage/combinat/sf/new_kschur.py +1786 -0
  264. sage/combinat/sf/ns_macdonald.py +964 -0
  265. sage/combinat/sf/orthogonal.py +246 -0
  266. sage/combinat/sf/orthotriang.py +355 -0
  267. sage/combinat/sf/powersum.py +963 -0
  268. sage/combinat/sf/schur.py +880 -0
  269. sage/combinat/sf/sf.py +1653 -0
  270. sage/combinat/sf/sfa.py +7053 -0
  271. sage/combinat/sf/symplectic.py +253 -0
  272. sage/combinat/sf/witt.py +721 -0
  273. sage/combinat/shifted_primed_tableau.py +2735 -0
  274. sage/combinat/shuffle.py +830 -0
  275. sage/combinat/sidon_sets.py +146 -0
  276. sage/combinat/similarity_class_type.py +1721 -0
  277. sage/combinat/sine_gordon.py +618 -0
  278. sage/combinat/six_vertex_model.py +784 -0
  279. sage/combinat/skew_partition.py +2053 -0
  280. sage/combinat/skew_tableau.py +2989 -0
  281. sage/combinat/sloane_functions.py +8935 -0
  282. sage/combinat/specht_module.py +1403 -0
  283. sage/combinat/species/all.py +48 -0
  284. sage/combinat/species/characteristic_species.py +321 -0
  285. sage/combinat/species/composition_species.py +273 -0
  286. sage/combinat/species/cycle_species.py +284 -0
  287. sage/combinat/species/empty_species.py +155 -0
  288. sage/combinat/species/functorial_composition_species.py +148 -0
  289. sage/combinat/species/generating_series.py +673 -0
  290. sage/combinat/species/library.py +148 -0
  291. sage/combinat/species/linear_order_species.py +169 -0
  292. sage/combinat/species/misc.py +83 -0
  293. sage/combinat/species/partition_species.py +290 -0
  294. sage/combinat/species/permutation_species.py +268 -0
  295. sage/combinat/species/product_species.py +423 -0
  296. sage/combinat/species/recursive_species.py +476 -0
  297. sage/combinat/species/set_species.py +192 -0
  298. sage/combinat/species/species.py +820 -0
  299. sage/combinat/species/structure.py +539 -0
  300. sage/combinat/species/subset_species.py +243 -0
  301. sage/combinat/species/sum_species.py +225 -0
  302. sage/combinat/subword.py +564 -0
  303. sage/combinat/subword_complex.py +2122 -0
  304. sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
  305. sage/combinat/subword_complex_c.pyx +119 -0
  306. sage/combinat/super_tableau.py +821 -0
  307. sage/combinat/superpartition.py +1154 -0
  308. sage/combinat/symmetric_group_algebra.py +3774 -0
  309. sage/combinat/symmetric_group_representations.py +1830 -0
  310. sage/combinat/t_sequences.py +877 -0
  311. sage/combinat/tableau.py +9506 -0
  312. sage/combinat/tableau_residues.py +860 -0
  313. sage/combinat/tableau_tuple.py +5353 -0
  314. sage/combinat/tiling.py +2432 -0
  315. sage/combinat/triangles_FHM.py +777 -0
  316. sage/combinat/tutorial.py +1857 -0
  317. sage/combinat/vector_partition.py +337 -0
  318. sage/combinat/words/abstract_word.py +1722 -0
  319. sage/combinat/words/all.py +59 -0
  320. sage/combinat/words/alphabet.py +268 -0
  321. sage/combinat/words/finite_word.py +7201 -0
  322. sage/combinat/words/infinite_word.py +113 -0
  323. sage/combinat/words/lyndon_word.py +652 -0
  324. sage/combinat/words/morphic.py +351 -0
  325. sage/combinat/words/morphism.py +3878 -0
  326. sage/combinat/words/paths.py +2932 -0
  327. sage/combinat/words/shuffle_product.py +278 -0
  328. sage/combinat/words/suffix_trees.py +1873 -0
  329. sage/combinat/words/word.py +769 -0
  330. sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
  331. sage/combinat/words/word_char.pyx +847 -0
  332. sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
  333. sage/combinat/words/word_datatypes.pxd +4 -0
  334. sage/combinat/words/word_datatypes.pyx +1067 -0
  335. sage/combinat/words/word_generators.py +2026 -0
  336. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  337. sage/combinat/words/word_options.py +99 -0
  338. sage/combinat/words/words.py +2396 -0
  339. sage/data_structures/all__sagemath_combinat.py +1 -0
  340. sage/databases/all__sagemath_combinat.py +13 -0
  341. sage/databases/findstat.py +4897 -0
  342. sage/databases/oeis.py +2058 -0
  343. sage/databases/sloane.py +393 -0
  344. sage/dynamics/all__sagemath_combinat.py +14 -0
  345. sage/dynamics/cellular_automata/all.py +7 -0
  346. sage/dynamics/cellular_automata/catalog.py +34 -0
  347. sage/dynamics/cellular_automata/elementary.py +612 -0
  348. sage/dynamics/cellular_automata/glca.py +477 -0
  349. sage/dynamics/cellular_automata/solitons.py +1463 -0
  350. sage/dynamics/finite_dynamical_system.py +1249 -0
  351. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  352. sage/games/all.py +7 -0
  353. sage/games/hexad.py +704 -0
  354. sage/games/quantumino.py +591 -0
  355. sage/games/sudoku.py +889 -0
  356. sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
  357. sage/games/sudoku_backtrack.pyx +189 -0
  358. sage/groups/all__sagemath_combinat.py +1 -0
  359. sage/groups/indexed_free_group.py +489 -0
  360. sage/libs/all__sagemath_combinat.py +6 -0
  361. sage/libs/lrcalc/__init__.py +1 -0
  362. sage/libs/lrcalc/lrcalc.py +525 -0
  363. sage/libs/symmetrica/__init__.py +7 -0
  364. sage/libs/symmetrica/all.py +101 -0
  365. sage/libs/symmetrica/kostka.pxi +168 -0
  366. sage/libs/symmetrica/part.pxi +193 -0
  367. sage/libs/symmetrica/plet.pxi +42 -0
  368. sage/libs/symmetrica/sab.pxi +196 -0
  369. sage/libs/symmetrica/sb.pxi +332 -0
  370. sage/libs/symmetrica/sc.pxi +192 -0
  371. sage/libs/symmetrica/schur.pxi +956 -0
  372. sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
  373. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  374. sage/libs/symmetrica/symmetrica.pyx +39 -0
  375. sage/monoids/all.py +13 -0
  376. sage/monoids/automatic_semigroup.py +1054 -0
  377. sage/monoids/free_abelian_monoid.py +315 -0
  378. sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
  379. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  380. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  381. sage/monoids/free_monoid.py +335 -0
  382. sage/monoids/free_monoid_element.py +431 -0
  383. sage/monoids/hecke_monoid.py +65 -0
  384. sage/monoids/string_monoid.py +817 -0
  385. sage/monoids/string_monoid_element.py +547 -0
  386. sage/monoids/string_ops.py +143 -0
  387. sage/monoids/trace_monoid.py +972 -0
  388. sage/rings/all__sagemath_combinat.py +2 -0
  389. sage/sat/all.py +4 -0
  390. sage/sat/boolean_polynomials.py +405 -0
  391. sage/sat/converters/__init__.py +6 -0
  392. sage/sat/converters/anf2cnf.py +14 -0
  393. sage/sat/converters/polybori.py +611 -0
  394. sage/sat/solvers/__init__.py +5 -0
  395. sage/sat/solvers/cryptominisat.py +287 -0
  396. sage/sat/solvers/dimacs.py +783 -0
  397. sage/sat/solvers/picosat.py +228 -0
  398. sage/sat/solvers/sat_lp.py +156 -0
  399. sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
  400. sage/sat/solvers/satsolver.pxd +3 -0
  401. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,1602 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ r"""
3
+ Parking functions
4
+
5
+ INFORMALLY (reference [Beck]_):
6
+
7
+ Imagine a one-way cul-de-sac with `n` parking spots. We will give the
8
+ first parking spot the number 1, the next one number 2, etc., down to
9
+ the last one, number `n`. Initially they are all free, but there are
10
+ `n` cars approaching the street, and they would all like to park there.
11
+ To make life interesting, every car has a parking preference, and we
12
+ record the preferences in a sequence; For example, if `n = 3`, the
13
+ sequence `(2, 1, 1)` means that the first car would like to park at
14
+ spot number 2, the second car prefers parking spot number 1, and the
15
+ last car would also like to part at number 1. The street is very
16
+ narrow, so there is no way to back up. Now each car enters the street
17
+ and approaches its preferred parking spot; if it is free, it parks
18
+ there, and if not, it moves down the street to the first available
19
+ spot. We call a sequence a parking function (of length `n`) if all
20
+ cars end up finding a parking spot. For example, the sequence `(2, 1,
21
+ 1)` is a parking sequence (of length 3), whereas the sequence `(2, 3,
22
+ 2)` is not.
23
+
24
+ FORMALLY:
25
+
26
+ A parking function of size `n` is a sequence `(a_1, \ldots, a_n)` of
27
+ positive integers such that if `b_1 \leq b_2 \leq \cdots \leq b_n` is
28
+ the increasing rearrangement of `a_1, \ldots, a_n`, then `b_i \leq i`.
29
+
30
+ A parking function of size `n` is a pair `(L, D)` of two sequences `L`
31
+ and `D` where `L` is a permutation and `D` is an area sequence of a
32
+ Dyck path of size n such that `D[i] \geq 0`, `D[i+1] \leq D[i]+1` and
33
+ if `D[i+1] = D[i]+1` then `L[i+1] > L[i]`.
34
+
35
+ The number of parking functions of size `n` is equal to the number of
36
+ rooted forests on `n` vertices and is equal to `(n+1)^{n-1}`.
37
+
38
+ REFERENCES:
39
+
40
+ .. [Beck] \M. Beck, Stanford Math Circle - Parking Functions, October 2010,
41
+ http://math.stanford.edu/circle/parkingBeck.pdf
42
+
43
+ .. [Hag08] The `q,t` -- Catalan Numbers and the Space of Diagonal Harmonics:
44
+ With an Appendix on the Combinatorics of Macdonald Polynomials, James Haglund,
45
+ University of Pennsylvania, Philadelphia -- AMS, 2008, 167 pp.
46
+
47
+ .. [Shin] \H. Shin, Forests and Parking Functions, slides from talk September 24, 2008,
48
+ http://www.emis.de/journals/SLC/wpapers/s61vortrag/shin.pdf
49
+
50
+ .. [GXZ] \A. M. Garsia, G. Xin, M. Zabrocki, A three shuffle case of the
51
+ compositional parking function conjecture, :arxiv:`1208.5796v1`
52
+
53
+ AUTHORS:
54
+
55
+ - used non-decreasing_parking_functions code by Florent Hivert (2009 - 04)
56
+ - Dorota Mazur (2012 - 09)
57
+ """
58
+ # ****************************************************************************
59
+ # Copyright (C) 2012 Dorota Mazur <dorota@yorku.ca>
60
+ #
61
+ # Distributed under the terms of the GNU General Public License (GPL)
62
+ # as published by the Free Software Foundation; either version 2 of
63
+ # the License, or (at your option) any later version.
64
+ # https://www.gnu.org/licenses/
65
+ # ****************************************************************************
66
+ from __future__ import annotations
67
+ from collections.abc import Iterator
68
+
69
+ from sage.rings.integer import Integer
70
+ from sage.rings.rational_field import QQ
71
+ from sage.structure.list_clone import ClonableArray
72
+ from sage.combinat.permutation import Permutation, Permutations
73
+ from sage.combinat.non_decreasing_parking_function import is_a as check_NDPF
74
+ from sage.combinat.dyck_word import DyckWord
75
+ from sage.combinat.combinatorial_map import combinatorial_map
76
+ from sage.misc.prandom import randint
77
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
78
+ from sage.rings.finite_rings.integer_mod_ring import Zmod
79
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
80
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
81
+ from sage.categories.sets_with_grading import SetsWithGrading
82
+ from sage.structure.parent import Parent
83
+ from sage.structure.unique_representation import UniqueRepresentation
84
+
85
+
86
+ def is_a(x, n=None) -> bool:
87
+ r"""
88
+ Check whether a list is a parking function.
89
+
90
+ If a size `n` is specified, checks if a list is a parking function
91
+ of size `n`.
92
+
93
+ TESTS::
94
+
95
+ sage: from sage.combinat.parking_functions import is_a
96
+ sage: is_a([1,1,2])
97
+ True
98
+ sage: is_a([1,2,1])
99
+ True
100
+ sage: is_a([1,1,4])
101
+ False
102
+ sage: is_a([3,1,1], 3)
103
+ True
104
+ """
105
+ if not isinstance(x, list): # from Florent Hivert non_decreasing_parking_function
106
+ return False
107
+ A = sorted(x)
108
+ return check_NDPF(A, n)
109
+
110
+
111
+ class ParkingFunction(ClonableArray, metaclass=InheritComparisonClasscallMetaclass):
112
+ r"""
113
+ A Parking Function.
114
+
115
+ A *parking function* of size `n` is a sequence `(a_1, \ldots,a_n)`
116
+ of positive integers such that if `b_1 \leq b_2 \leq \cdots \leq b_n` is
117
+ the increasing rearrangement of `a_1, \ldots, a_n`, then `b_i \leq i`.
118
+
119
+ A *parking function* of size `n` is a pair `(L, D)` of two sequences
120
+ `L` and `D` where `L` is a permutation and `D` is an area sequence
121
+ of a Dyck Path of size `n` such that `D[i] \geq 0`, `D[i+1] \leq D[i]+1`
122
+ and if `D[i+1] = D[i]+1` then `L[i+1] > L[i]`.
123
+
124
+ The number of parking functions of size `n` is equal to the number
125
+ of rooted forests on `n` vertices and is equal to `(n+1)^{n-1}`.
126
+
127
+ INPUT:
128
+
129
+ - ``pf`` -- (default: ``None``) a list whose increasing rearrangement
130
+ satisfies `b_i \leq i`
131
+
132
+ - ``labelling`` -- (default: ``None``) a labelling of the Dyck path
133
+
134
+ - ``area_sequence`` -- (default: ``None``) an area sequence of a Dyck path
135
+
136
+ - ``labelled_dyck_word`` -- (default: ``None``) a Dyck word with 1s
137
+ replaced by labelling
138
+
139
+ OUTPUT: a parking function
140
+
141
+ EXAMPLES::
142
+
143
+ sage: ParkingFunction([])
144
+ []
145
+ sage: ParkingFunction([1])
146
+ [1]
147
+ sage: ParkingFunction([2])
148
+ Traceback (most recent call last):
149
+ ...
150
+ ValueError: [2] is not a parking function
151
+ sage: ParkingFunction([1,2])
152
+ [1, 2]
153
+ sage: ParkingFunction([1,1,2])
154
+ [1, 1, 2]
155
+ sage: ParkingFunction([1,4,1])
156
+ Traceback (most recent call last):
157
+ ...
158
+ ValueError: [1, 4, 1] is not a parking function
159
+ sage: ParkingFunction(labelling=[3,1,2], area_sequence=[0,0,1])
160
+ [2, 2, 1]
161
+ sage: ParkingFunction([2,2,1]).to_labelled_dyck_word()
162
+ [3, 0, 1, 2, 0, 0]
163
+ sage: ParkingFunction(labelled_dyck_word=[3,0,1,2,0,0])
164
+ [2, 2, 1]
165
+ sage: ParkingFunction(labelling=[3,1,2], area_sequence=[0,1,1])
166
+ Traceback (most recent call last):
167
+ ...
168
+ ValueError: [3, 1, 2] is not a valid labeling of area sequence [0, 1, 1]
169
+ """
170
+ @staticmethod
171
+ def __classcall_private__(cls, pf=None, labelling=None, area_sequence=None,
172
+ labelled_dyck_word=None):
173
+ """
174
+ Construct a parking function based on the input.
175
+
176
+ TESTS::
177
+
178
+ sage: PF = ParkingFunction([1,2])
179
+ sage: isinstance(PF, ParkingFunctions().element_class)
180
+ True
181
+ """
182
+ if isinstance(pf, ParkingFunction):
183
+ return pf
184
+ if pf is not None:
185
+ PF = ParkingFunctions()
186
+ return PF.element_class(PF, pf)
187
+ elif labelling is not None:
188
+ if (area_sequence is None):
189
+ raise ValueError("must also provide area sequence along with labelling")
190
+ if (len(area_sequence) != len(labelling)):
191
+ raise ValueError("%s must be the same size as the labelling %s" % (area_sequence, labelling))
192
+ if any(area_sequence[i] < area_sequence[i + 1] and labelling[i] > labelling[i + 1] for i in range(len(labelling) - 1)):
193
+ raise ValueError("%s is not a valid labeling of area sequence %s" % (labelling, area_sequence))
194
+ return from_labelling_and_area_sequence(labelling, area_sequence)
195
+ elif labelled_dyck_word is not None:
196
+ return from_labelled_dyck_word(labelled_dyck_word)
197
+ elif area_sequence is not None:
198
+ DW = DyckWord(area_sequence)
199
+ return ParkingFunction(labelling=list(range(1, DW.size() + 1)),
200
+ area_sequence=DW)
201
+
202
+ raise ValueError("did not manage to make this into a parking function")
203
+
204
+ def __init__(self, parent, lst):
205
+ """
206
+ TESTS::
207
+
208
+ sage: ParkingFunction([1, 1, 2, 2, 5, 6])
209
+ [1, 1, 2, 2, 5, 6]
210
+
211
+ sage: PF = ParkingFunction([1, 1, 2, 2, 5, 6])
212
+ sage: PF[0]
213
+ 1
214
+ sage: PF[2]
215
+ 2
216
+
217
+ sage: PF4 = ParkingFunctions(4)
218
+ sage: a = PF4.list()[36]
219
+ sage: b = PF4([1,3,2,1])
220
+ sage: type(a)
221
+ <class 'sage.combinat.parking_functions.ParkingFunctions_n_with_category.element_class'>
222
+ sage: type(b)
223
+ <class 'sage.combinat.parking_functions.ParkingFunctions_n_with_category.element_class'>
224
+
225
+ Some checks for more general inputs::
226
+
227
+ sage: PF = ParkingFunction((1, 1, 2, 2, 5, 6))
228
+ sage: PF = ParkingFunction(Permutation([4,2,3,1]))
229
+ """
230
+ if not isinstance(lst, list):
231
+ try:
232
+ lst = list(lst)
233
+ except TypeError:
234
+ raise TypeError('input must be convertible to a list')
235
+ if parent is None:
236
+ parent = ParkingFunctions_n(len(lst))
237
+ ClonableArray.__init__(self, parent, lst)
238
+
239
+ def check(self):
240
+ """
241
+ Check that ``self`` is a valid parking function.
242
+
243
+ EXAMPLES::
244
+
245
+ sage: PF = ParkingFunction([1, 1, 2, 2, 5, 6])
246
+ sage: PF.check()
247
+ """
248
+ if not check_NDPF(sorted(self), len(self)):
249
+ raise ValueError(f'{list(self)} is not a parking function')
250
+
251
+ def grade(self):
252
+ """
253
+ Return the length of the parking function.
254
+
255
+ EXAMPLES::
256
+
257
+ sage: PF = ParkingFunction([1, 1, 2, 2, 5, 6])
258
+ sage: PF.grade()
259
+ 6
260
+ """
261
+ return len(self)
262
+
263
+ def __call__(self, n):
264
+ """
265
+ Return the image of ``n`` under the parking function.
266
+
267
+ EXAMPLES::
268
+
269
+ sage: PF = ParkingFunction([1, 1, 2, 2, 5, 6])
270
+ sage: PF(3)
271
+ 2
272
+ sage: PF(6)
273
+ 6
274
+ """
275
+ return self[n - 1]
276
+
277
+ def diagonal_reading_word(self) -> Permutation:
278
+ r"""
279
+ Return a diagonal word of the labelled Dyck path corresponding to parking
280
+ function (see [Hag08]_ p. 75).
281
+
282
+ OUTPUT:
283
+
284
+ - returns a word, read diagonally from NE to SW of the pretty
285
+ print of the labelled Dyck path that corresponds to ``self``
286
+ and the same size as ``self``
287
+
288
+ EXAMPLES::
289
+
290
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
291
+ sage: PF.diagonal_reading_word()
292
+ [5, 1, 7, 4, 6, 3, 2]
293
+
294
+ ::
295
+
296
+ sage: ParkingFunction([1, 1, 1]).diagonal_reading_word()
297
+ [3, 2, 1]
298
+ sage: ParkingFunction([1, 2, 3]).diagonal_reading_word()
299
+ [3, 2, 1]
300
+ sage: ParkingFunction([1, 1, 3, 4]).diagonal_reading_word()
301
+ [2, 4, 3, 1]
302
+
303
+ ::
304
+
305
+ sage: ParkingFunction([1, 1, 1]).diagonal_word()
306
+ [3, 2, 1]
307
+ sage: ParkingFunction([1, 2, 3]).diagonal_word()
308
+ [3, 2, 1]
309
+ sage: ParkingFunction([1, 4, 3, 1]).diagonal_word()
310
+ [4, 2, 3, 1]
311
+ """
312
+ L = self.to_labelling_permutation()
313
+ D = self.to_area_sequence()
314
+ m = max(D)
315
+ data = [L[-j - 1] for i in range(m + 1)
316
+ for j in range(len(L)) if D[-j - 1] == m - i]
317
+ return Permutation(data) # type:ignore
318
+
319
+ diagonal_word = diagonal_reading_word
320
+
321
+ def parking_permutation(self) -> Permutation:
322
+ # indices are cars, entries are parking spaces
323
+ r"""
324
+ Return the sequence of parking spots that are taken by cars 1
325
+ through `n` and corresponding to the parking function.
326
+
327
+ For example, ``parking_permutation(PF) = [6, 1, 5, 2, 3, 4,
328
+ 7]`` means that spot 6 is taken by car 1, spot 1 by car 2,
329
+ spot 5 by car 3, spot 2 is taken by car 4, spot 3 is taken by
330
+ car 5, spot 4 is taken by car 6 and spot 7 is taken by car 7.
331
+
332
+ OUTPUT:
333
+
334
+ - the permutation of parking spots that corresponds to
335
+ the parking function and which is the same size as parking
336
+ function
337
+
338
+ EXAMPLES::
339
+
340
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
341
+ sage: PF.parking_permutation()
342
+ [6, 1, 5, 2, 3, 4, 7]
343
+
344
+ ::
345
+
346
+ sage: ParkingFunction([3,1,1,4]).parking_permutation()
347
+ [3, 1, 2, 4]
348
+ sage: ParkingFunction([4,1,1,1]).parking_permutation()
349
+ [4, 1, 2, 3]
350
+ sage: ParkingFunction([2,1,4,1]).parking_permutation()
351
+ [2, 1, 4, 3]
352
+ """
353
+ return self.cars_permutation().inverse()
354
+
355
+ @combinatorial_map(name='to car permutation')
356
+ def cars_permutation(self) -> Permutation:
357
+ # indices are parking spaces, entries are car labels
358
+ r"""
359
+ Return the sequence of cars that take parking spots 1 through `n`
360
+ and corresponding to the parking function.
361
+
362
+ For example, ``cars_permutation(PF) = [2, 4, 5, 6, 3, 1, 7]``
363
+ means that car 2 takes spots 1, car 4 takes spot 2, ..., car 1
364
+ takes spot 6 and car 7 takes spot 7.
365
+
366
+ OUTPUT:
367
+
368
+ - the permutation of cars corresponding to the parking function
369
+ and which is the same size as parking function
370
+
371
+ EXAMPLES::
372
+
373
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
374
+ sage: PF.cars_permutation()
375
+ [2, 4, 5, 6, 3, 1, 7]
376
+
377
+ ::
378
+
379
+ sage: ParkingFunction([3,1,1,4]).cars_permutation()
380
+ [2, 3, 1, 4]
381
+ sage: ParkingFunction([4,1,1,1]).cars_permutation()
382
+ [2, 3, 4, 1]
383
+ sage: ParkingFunction([2,1,4,1]).cars_permutation()
384
+ [2, 1, 4, 3]
385
+ """
386
+ out = {}
387
+ for i in range(len(self)):
388
+ j = 0
389
+ while self[i] + j in out:
390
+ j += 1
391
+ out[self[i] + j] = i
392
+ data = [out[i + 1] + 1 for i in range(len(self))]
393
+ return Permutation(data) # type:ignore
394
+
395
+ def jump_list(self) -> list: # cars displacements
396
+ r"""
397
+ Return the displacements of cars that corresponds to the parking function.
398
+
399
+ For example, ``jump_list(PF) = [0, 0, 0, 0, 1, 3, 2]``
400
+ means that car 1 through 4 parked in their preferred spots,
401
+ car 5 had to park one spot farther (jumped or was displaced by one
402
+ spot), car 6 had to jump 3 spots, and car 7 had to jump two spots.
403
+
404
+ OUTPUT:
405
+
406
+ - the displacements sequence of parked cars which corresponds
407
+ to the parking function and which is the same size as parking function
408
+
409
+ EXAMPLES::
410
+
411
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
412
+ sage: PF.jump_list()
413
+ [0, 0, 0, 0, 1, 3, 2]
414
+
415
+ ::
416
+
417
+ sage: ParkingFunction([3,1,1,4]).jump_list()
418
+ [0, 0, 1, 0]
419
+ sage: ParkingFunction([4,1,1,1]).jump_list()
420
+ [0, 0, 1, 2]
421
+ sage: ParkingFunction([2,1,4,1]).jump_list()
422
+ [0, 0, 0, 2]
423
+ """
424
+ pi = self.parking_permutation()
425
+ return [pi[i] - self[i] for i in range(len(self))]
426
+
427
+ def jump(self) -> Integer: # sum of all jumps, sum of all displacements
428
+ r"""
429
+ Return the sum of the differences between the parked and
430
+ preferred parking spots.
431
+
432
+ See [Shin]_ p. 18.
433
+
434
+ OUTPUT:
435
+
436
+ - the sum of the differences between the parked and preferred parking
437
+ spots
438
+
439
+ EXAMPLES::
440
+
441
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
442
+ sage: PF.jump()
443
+ 6
444
+
445
+ ::
446
+
447
+ sage: ParkingFunction([3,1,1,4]).jump()
448
+ 1
449
+ sage: ParkingFunction([4,1,1,1]).jump()
450
+ 3
451
+ sage: ParkingFunction([2,1,4,1]).jump()
452
+ 2
453
+ """
454
+ return sum(self.jump_list())
455
+
456
+ def lucky_cars(self): # the set of cars that can park in their preferred spots
457
+ r"""
458
+ Return the cars that can park in their preferred spots. For example,
459
+ ``lucky_cars(PF) = [1, 2, 7]`` means that cars 1, 2 and 7 parked in
460
+ their preferred spots and all the other cars did not.
461
+
462
+ OUTPUT: the cars that can park in their preferred spots
463
+
464
+ EXAMPLES::
465
+
466
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
467
+ sage: PF.lucky_cars()
468
+ [1, 2, 3, 4]
469
+
470
+ ::
471
+
472
+ sage: ParkingFunction([3,1,1,4]).lucky_cars()
473
+ [1, 2, 4]
474
+ sage: ParkingFunction([4,1,1,1]).lucky_cars()
475
+ [1, 2]
476
+ sage: ParkingFunction([2,1,4,1]).lucky_cars()
477
+ [1, 2, 3]
478
+ """
479
+ w = self.jump_list()
480
+ return [i + 1 for i in range(len(w)) if w[i] == 0]
481
+
482
+ def luck(self) -> Integer: # the number of lucky cars
483
+ r"""
484
+ Return the number of cars that parked in their preferred parking spots
485
+ (see [Shin]_ p. 33).
486
+
487
+ OUTPUT: the number of cars that parked in their preferred parking spots
488
+
489
+ EXAMPLES::
490
+
491
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
492
+ sage: PF.luck()
493
+ 4
494
+
495
+ ::
496
+
497
+ sage: ParkingFunction([3,1,1,4]).luck()
498
+ 3
499
+ sage: ParkingFunction([4,1,1,1]).luck()
500
+ 2
501
+ sage: ParkingFunction([2,1,4,1]).luck()
502
+ 3
503
+ """
504
+ return len(self.lucky_cars())
505
+
506
+ def primary_dinversion_pairs(self) -> list[tuple[int, int]]:
507
+ r"""
508
+ Return the primary descent inversion pairs of a labelled Dyck path
509
+ corresponding to the parking function.
510
+
511
+ OUTPUT:
512
+
513
+ The pairs `(i, j)` such that `i < j`, and `i`-th area = `j`-th area,
514
+ and `i`-th label < `j`-th label
515
+
516
+ EXAMPLES::
517
+
518
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
519
+ sage: PF.primary_dinversion_pairs()
520
+ [(0, 4), (1, 5), (2, 5)]
521
+
522
+ ::
523
+
524
+ sage: ParkingFunction([3,1,1,4]).primary_dinversion_pairs()
525
+ [(0, 3), (2, 3)]
526
+ sage: ParkingFunction([4,1,1,1]).primary_dinversion_pairs()
527
+ []
528
+ sage: ParkingFunction([2,1,4,1]).primary_dinversion_pairs()
529
+ [(0, 3)]
530
+ """
531
+ L = self.to_labelling_permutation()
532
+ D = self.to_area_sequence()
533
+ return [(i, j) for j in range(len(D)) for i in range(j)
534
+ if D[i] == D[j] and L[i] < L[j]]
535
+
536
+ def secondary_dinversion_pairs(self) -> list[tuple[int, int]]:
537
+ r"""
538
+ Return the secondary descent inversion pairs of a labelled Dyck path
539
+ corresponding to the parking function.
540
+
541
+ OUTPUT:
542
+
543
+ The pairs `(i, j)` such that `i < j`, and `i`-th area = `j`-th area +1,
544
+ and `i`-th label > `j`-th label
545
+
546
+ EXAMPLES::
547
+
548
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
549
+ sage: PF.secondary_dinversion_pairs()
550
+ [(1, 4), (2, 4), (3, 6)]
551
+
552
+ ::
553
+
554
+ sage: ParkingFunction([3,1,1,4]).secondary_dinversion_pairs()
555
+ [(1, 2)]
556
+ sage: ParkingFunction([4,1,1,1]).secondary_dinversion_pairs()
557
+ [(1, 3)]
558
+ sage: ParkingFunction([2,1,4,1]).secondary_dinversion_pairs()
559
+ [(1, 3)]
560
+ """
561
+ L = self.to_labelling_permutation()
562
+ D = self.to_area_sequence()
563
+ return [(i, j) for j in range(len(D)) for i in range(j)
564
+ if D[i] == D[j] + 1 and L[i] > L[j]]
565
+
566
+ def dinversion_pairs(self) -> list[tuple[int, int]]:
567
+ r"""
568
+ Return the descent inversion pairs of a labelled Dyck path
569
+ corresponding to the parking function.
570
+
571
+ OUTPUT: the primary and secondary diversion pairs
572
+
573
+ EXAMPLES::
574
+
575
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
576
+ sage: PF.dinversion_pairs()
577
+ [(0, 4), (1, 5), (2, 5), (1, 4), (2, 4), (3, 6)]
578
+
579
+ ::
580
+
581
+ sage: ParkingFunction([3,1,1,4]).dinversion_pairs()
582
+ [(0, 3), (2, 3), (1, 2)]
583
+ sage: ParkingFunction([4,1,1,1]).dinversion_pairs()
584
+ [(1, 3)]
585
+ sage: ParkingFunction([2,1,4,1]).dinversion_pairs()
586
+ [(0, 3), (1, 3)]
587
+ """
588
+ return self.primary_dinversion_pairs() + self.secondary_dinversion_pairs()
589
+
590
+ def dinv(self) -> int:
591
+ r"""
592
+ Return the number of inversions of a labelled Dyck path corresponding
593
+ to the parking function (see [Hag08]_ p. 74).
594
+
595
+ Same as the cardinality of :meth:`dinversion_pairs`.
596
+
597
+ OUTPUT: the number of dinversion pairs
598
+
599
+ EXAMPLES::
600
+
601
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
602
+ sage: PF.dinv()
603
+ 6
604
+
605
+ ::
606
+
607
+ sage: ParkingFunction([3,1,1,4]).dinv()
608
+ 3
609
+ sage: ParkingFunction([4,1,1,1]).dinv()
610
+ 1
611
+ sage: ParkingFunction([2,1,4,1]).dinv()
612
+ 2
613
+ """
614
+ return len(self.dinversion_pairs())
615
+
616
+ def area(self) -> Integer:
617
+ r"""
618
+ Return the area of the labelled Dyck path corresponding to the
619
+ parking function.
620
+
621
+ OUTPUT:
622
+
623
+ - the sum of squares under and over the main diagonal the Dyck Path,
624
+ corresponding to the parking function
625
+
626
+ EXAMPLES::
627
+
628
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
629
+ sage: PF.area()
630
+ 6
631
+
632
+ ::
633
+
634
+ sage: ParkingFunction([3,1,1,4]).area()
635
+ 1
636
+ sage: ParkingFunction([4,1,1,1]).area()
637
+ 3
638
+ sage: ParkingFunction([2,1,4,1]).area()
639
+ 2
640
+ """
641
+ return sum(self.to_area_sequence())
642
+
643
+ @combinatorial_map(name='to ides composition')
644
+ def ides_composition(self):
645
+ r"""
646
+ Return the
647
+ :meth:`~sage.combinat.permutation.Permutation.descents_composition`
648
+ of the inverse of the :meth:`diagonal_reading_word` of
649
+ corresponding parking function.
650
+
651
+ For example, ``ides_composition(PF) = [4, 2, 1]`` means that
652
+ the descents of the inverse of the permutation
653
+ :meth:`diagonal_reading_word` of the parking function with
654
+ word ``PF`` are at the 4th and 6th positions.
655
+
656
+ OUTPUT:
657
+
658
+ - the descents composition of the inverse of the
659
+ :meth:`diagonal_reading_word` of the parking function
660
+
661
+ EXAMPLES::
662
+
663
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
664
+ sage: PF.ides_composition()
665
+ [2, 1, 1, 2, 1]
666
+
667
+ ::
668
+
669
+ sage: ParkingFunction([3,1,1,4]).ides_composition()
670
+ [2, 2]
671
+ sage: ParkingFunction([4,1,1,1]).ides_composition()
672
+ [2, 1, 1]
673
+ sage: ParkingFunction([4,3,1,1]).ides_composition()
674
+ [3, 1]
675
+ """
676
+ return self.diagonal_reading_word().inverse().descents_composition()
677
+
678
+ def ides(self):
679
+ r"""
680
+ Return the :meth:`~sage.combinat.permutation.Permutation.descents`
681
+ sequence of the inverse of the :meth:`diagonal_reading_word`
682
+ of ``self``.
683
+
684
+ .. WARNING::
685
+
686
+ Here we use the standard convention that descent labels
687
+ start at `1`. This behaviour has been changed in
688
+ :issue:`20555`.
689
+
690
+ For example, ``ides(PF) = [2, 3, 4, 6]`` means that descents are at
691
+ the 2nd, 3rd, 4th and 6th positions in the inverse of the
692
+ :meth:`diagonal_reading_word` of the parking function (see [GXZ]_ p. 2).
693
+
694
+ OUTPUT:
695
+
696
+ - the descents sequence of the inverse of the
697
+ :meth:`diagonal_reading_word` of the parking function
698
+
699
+ EXAMPLES::
700
+
701
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
702
+ sage: PF.ides()
703
+ [2, 3, 4, 6]
704
+
705
+ ::
706
+
707
+ sage: ParkingFunction([3,1,1,4]).ides()
708
+ [2]
709
+ sage: ParkingFunction([4,1,1,1]).ides()
710
+ [2, 3]
711
+ sage: ParkingFunction([4,3,1,1]).ides()
712
+ [3]
713
+ """
714
+ return self.diagonal_reading_word().inverse().descents()
715
+
716
+ def touch_points(self):
717
+ r"""
718
+ Return the sequence of touch points which corresponds to the
719
+ labelled Dyck path after initial step.
720
+
721
+ For example, ``touch_points(PF) = [4, 7]`` means that after
722
+ the initial step, the path touches the main diagonal at points
723
+ `(4, 4)` and `(7, 7)`.
724
+
725
+ OUTPUT:
726
+
727
+ - the sequence of touch points after the initial step of the
728
+ labelled Dyck path that corresponds to the parking function
729
+
730
+ EXAMPLES::
731
+
732
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
733
+ sage: PF.touch_points()
734
+ [4, 7]
735
+
736
+ ::
737
+
738
+ sage: ParkingFunction([3,1,1,4]).touch_points()
739
+ [2, 3, 4]
740
+ sage: ParkingFunction([4,1,1,1]).touch_points()
741
+ [3, 4]
742
+ sage: ParkingFunction([2,1,4,1]).touch_points()
743
+ [3, 4]
744
+ """
745
+ return self.to_dyck_word().touch_points()
746
+
747
+ @combinatorial_map(name='to touch composition')
748
+ def touch_composition(self):
749
+ r"""
750
+ Return the composition of the labelled Dyck path corresponding
751
+ to the parking function.
752
+
753
+ For example, ``touch_composition(PF) = [4, 3]`` means that the
754
+ first touch is four diagonal units from the starting point,
755
+ and the second is three units further (see [GXZ]_ p. 2).
756
+
757
+ OUTPUT:
758
+
759
+ - the length between the corresponding touch points which
760
+ of the labelled Dyck path that corresponds to the parking function
761
+
762
+ EXAMPLES::
763
+
764
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
765
+ sage: PF.touch_composition()
766
+ [4, 3]
767
+
768
+ ::
769
+
770
+ sage: ParkingFunction([3,1,1,4]).touch_composition()
771
+ [2, 1, 1]
772
+ sage: ParkingFunction([4,1,1,1]).touch_composition()
773
+ [3, 1]
774
+ sage: ParkingFunction([2,1,4,1]).touch_composition()
775
+ [3, 1]
776
+ """
777
+ return self.to_dyck_word().touch_composition()
778
+
779
+ diagonal_composition = touch_composition
780
+
781
+ @combinatorial_map(name='to labelling permutation')
782
+ def to_labelling_permutation(self) -> Permutation:
783
+ r"""
784
+ Return the labelling of the support Dyck path of the parking function.
785
+
786
+ OUTPUT: the labelling of the Dyck path
787
+
788
+ EXAMPLES::
789
+
790
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
791
+ sage: PF.to_labelling_permutation()
792
+ [2, 6, 4, 5, 3, 7, 1]
793
+
794
+ ::
795
+
796
+ sage: ParkingFunction([3,1,1,4]).to_labelling_permutation()
797
+ [2, 3, 1, 4]
798
+ sage: ParkingFunction([4,1,1,1]).to_labelling_permutation()
799
+ [2, 3, 4, 1]
800
+ sage: ParkingFunction([2,1,4,1]).to_labelling_permutation()
801
+ [2, 4, 1, 3]
802
+ """
803
+ from sage.combinat.words.word import Word
804
+ return Word(self).standard_permutation().inverse()
805
+
806
+ def to_area_sequence(self) -> list:
807
+ r"""
808
+ Return the area sequence of the support Dyck path of the
809
+ parking function.
810
+
811
+ OUTPUT: the area sequence of the Dyck path
812
+
813
+ EXAMPLES::
814
+
815
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
816
+ sage: PF.to_area_sequence()
817
+ [0, 1, 1, 2, 0, 1, 1]
818
+
819
+ ::
820
+
821
+ sage: ParkingFunction([3,1,1,4]).to_area_sequence()
822
+ [0, 1, 0, 0]
823
+ sage: ParkingFunction([4,1,1,1]).to_area_sequence()
824
+ [0, 1, 2, 0]
825
+ sage: ParkingFunction([2,1,4,1]).to_area_sequence()
826
+ [0, 1, 1, 0]
827
+ """
828
+ w = sorted(self)
829
+ return [i + 1 - wi for i, wi in enumerate(w)]
830
+
831
+ def to_labelling_area_sequence_pair(self):
832
+ r"""
833
+ Return a pair consisting of a labelling and an area sequence
834
+ of a Dyck path which corresponds to the given parking
835
+ function.
836
+
837
+ OUTPUT:
838
+
839
+ - returns a pair ``(L, D)`` where ``L`` is a labelling and ``D`` is the
840
+ area sequence of the underlying Dyck path
841
+
842
+ EXAMPLES::
843
+
844
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
845
+ sage: PF.to_labelling_area_sequence_pair()
846
+ ([2, 6, 4, 5, 3, 7, 1], [0, 1, 1, 2, 0, 1, 1])
847
+
848
+ ::
849
+
850
+ sage: ParkingFunction([1, 1, 1]).to_labelling_area_sequence_pair()
851
+ ([1, 2, 3], [0, 1, 2])
852
+ sage: ParkingFunction([1, 2, 3]).to_labelling_area_sequence_pair()
853
+ ([1, 2, 3], [0, 0, 0])
854
+ sage: ParkingFunction([1, 1, 2]).to_labelling_area_sequence_pair()
855
+ ([1, 2, 3], [0, 1, 1])
856
+ sage: ParkingFunction([1, 1, 3, 1]).to_labelling_area_sequence_pair()
857
+ ([1, 2, 4, 3], [0, 1, 2, 1])
858
+ """
859
+ return (self.to_labelling_permutation(), self.to_area_sequence())
860
+
861
+ @combinatorial_map(name='to dyck word')
862
+ def to_dyck_word(self) -> DyckWord:
863
+ r"""
864
+ Return the support Dyck word of the parking function.
865
+
866
+ OUTPUT: the Dyck word of the corresponding parking function
867
+
868
+ .. SEEALSO:: :meth:`DyckWord`
869
+
870
+ EXAMPLES::
871
+
872
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
873
+ sage: PF.to_dyck_word()
874
+ [1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0]
875
+
876
+ ::
877
+
878
+ sage: ParkingFunction([3,1,1,4]).to_dyck_word()
879
+ [1, 1, 0, 0, 1, 0, 1, 0]
880
+ sage: ParkingFunction([4,1,1,1]).to_dyck_word()
881
+ [1, 1, 1, 0, 0, 0, 1, 0]
882
+ sage: ParkingFunction([2,1,4,1]).to_dyck_word()
883
+ [1, 1, 0, 1, 0, 0, 1, 0]
884
+ """
885
+ return DyckWord(area_sequence=self.to_area_sequence()) # type:ignore
886
+
887
+ def to_labelled_dyck_word(self):
888
+ r"""
889
+ Return the labelled Dyck word corresponding to the parking function.
890
+
891
+ This is a representation of the parking function as a list
892
+ where the entries of 1 in the Dyck word are replaced with the
893
+ corresponding label.
894
+
895
+ OUTPUT:
896
+
897
+ - the labelled Dyck word of the corresponding parking function
898
+ which is twice the size of parking function word
899
+
900
+ EXAMPLES::
901
+
902
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
903
+ sage: PF.to_labelled_dyck_word()
904
+ [2, 6, 0, 4, 5, 0, 0, 0, 3, 7, 0, 1, 0, 0]
905
+
906
+ ::
907
+
908
+ sage: ParkingFunction([3,1,1,4]).to_labelled_dyck_word()
909
+ [2, 3, 0, 0, 1, 0, 4, 0]
910
+ sage: ParkingFunction([4,1,1,1]).to_labelled_dyck_word()
911
+ [2, 3, 4, 0, 0, 0, 1, 0]
912
+ sage: ParkingFunction([2,1,4,1]).to_labelled_dyck_word()
913
+ [2, 4, 0, 1, 0, 0, 3, 0]
914
+ """
915
+ dw = self.to_dyck_word()
916
+ out = list(self.to_labelling_permutation())
917
+ for i in range(2 * len(out)):
918
+ if dw[i] == 0:
919
+ out.insert(i, 0)
920
+ return out
921
+
922
+ def to_labelling_dyck_word_pair(self) -> tuple[Permutation, DyckWord]:
923
+ r"""
924
+ Return the pair ``(L, D)`` where ``L`` is a labelling and
925
+ ``D`` is the Dyck word of the parking function.
926
+
927
+ OUTPUT:
928
+
929
+ - the pair ``(L, D)``, where ``L`` is the labelling and ``D`` is
930
+ the Dyck word of the parking function
931
+
932
+ .. SEEALSO:: :meth:`DyckWord`
933
+
934
+ EXAMPLES::
935
+
936
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
937
+ sage: PF.to_labelling_dyck_word_pair()
938
+ ([2, 6, 4, 5, 3, 7, 1], [1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0])
939
+
940
+ ::
941
+
942
+ sage: ParkingFunction([3,1,1,4]).to_labelling_dyck_word_pair()
943
+ ([2, 3, 1, 4], [1, 1, 0, 0, 1, 0, 1, 0])
944
+ sage: ParkingFunction([4,1,1,1]).to_labelling_dyck_word_pair()
945
+ ([2, 3, 4, 1], [1, 1, 1, 0, 0, 0, 1, 0])
946
+ sage: ParkingFunction([2,1,4,1]).to_labelling_dyck_word_pair()
947
+ ([2, 4, 1, 3], [1, 1, 0, 1, 0, 0, 1, 0])
948
+ """
949
+ return (self.to_labelling_permutation(), self.to_dyck_word())
950
+
951
+ @combinatorial_map(name='to non-decreasing parking function')
952
+ def to_NonDecreasingParkingFunction(self) -> PF:
953
+ r"""
954
+ Return the non-decreasing parking function which underlies the
955
+ parking function.
956
+
957
+ OUTPUT: a sorted parking function
958
+
959
+ .. SEEALSO:: :meth:`NonDecreasingParkingFunction`
960
+
961
+ EXAMPLES::
962
+
963
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
964
+ sage: PF.to_NonDecreasingParkingFunction()
965
+ [1, 1, 2, 2, 5, 5, 6]
966
+
967
+ ::
968
+
969
+ sage: ParkingFunction([3,1,1,4]).to_NonDecreasingParkingFunction()
970
+ [1, 1, 3, 4]
971
+ sage: ParkingFunction([4,1,1,1]).to_NonDecreasingParkingFunction()
972
+ [1, 1, 1, 4]
973
+ sage: ParkingFunction([2,1,4,1]).to_NonDecreasingParkingFunction()
974
+ [1, 1, 2, 4]
975
+ sage: ParkingFunction([4,1,2,1]).to_NonDecreasingParkingFunction()
976
+ [1, 1, 2, 4]
977
+ """
978
+ return ParkingFunction(sorted(self)) # type:ignore
979
+
980
+ def characteristic_quasisymmetric_function(self, q=None,
981
+ R=QQ['q', 't'].fraction_field()):
982
+ r"""
983
+ Return the characteristic quasisymmetric function of ``self``.
984
+
985
+ The characteristic function of the Parking Function is the sum
986
+ over all permutation labellings of the Dyck path `q^{dinv(PF)}
987
+ F_{ides(PF)}` where `ides(PF)` (:meth:`ides_composition`) is
988
+ the descent composition of diagonal reading word of the
989
+ parking function.
990
+
991
+ INPUT:
992
+
993
+ - ``q`` -- (default: ``q = R('q')``) a parameter for the
994
+ generating function power
995
+
996
+ - ``R`` -- (default: ``R = QQ['q','t'].fraction_field()``) the
997
+ base ring to do the calculations over
998
+
999
+ OUTPUT: an element of the quasisymmetric functions over the ring ``R``
1000
+
1001
+ EXAMPLES::
1002
+
1003
+ sage: # needs sage.modules
1004
+ sage: R = QQ['q','t'].fraction_field()
1005
+ sage: (q,t) = R.gens()
1006
+ sage: cqf = sum(t**PF.area() * PF.characteristic_quasisymmetric_function()
1007
+ ....: for PF in ParkingFunctions(3)); cqf
1008
+ (q^3+q^2*t+q*t^2+t^3+q*t)*F[1, 1, 1] + (q^2+q*t+t^2+q+t)*F[1, 2]
1009
+ + (q^2+q*t+t^2+q+t)*F[2, 1] + F[3]
1010
+ sage: s = SymmetricFunctions(R).s()
1011
+ sage: s(cqf.to_symmetric_function())
1012
+ (q^3+q^2*t+q*t^2+t^3+q*t)*s[1, 1, 1] + (q^2+q*t+t^2+q+t)*s[2, 1] + s[3]
1013
+ sage: s(cqf.to_symmetric_function()).nabla(power=-1)
1014
+ s[1, 1, 1]
1015
+
1016
+ ::
1017
+
1018
+ sage: p = ParkingFunction([3, 1, 2])
1019
+ sage: p.characteristic_quasisymmetric_function() # needs sage.modules
1020
+ q*F[2, 1]
1021
+ sage: pf = ParkingFunction([1,2,7,2,1,2,3,2,1])
1022
+ sage: pf.characteristic_quasisymmetric_function() # needs sage.modules
1023
+ q^2*F[1, 1, 1, 2, 1, 3]
1024
+ """
1025
+ from sage.combinat.ncsf_qsym.qsym import QuasiSymmetricFunctions
1026
+ if q is None:
1027
+ q = R('q')
1028
+ else:
1029
+ if q not in R:
1030
+ raise ValueError("q=%s must be an element of the base ring %s" % (q, R))
1031
+ F = QuasiSymmetricFunctions(R).Fundamental()
1032
+ return q**self.dinv() * F(self.ides_composition())
1033
+
1034
+ def pretty_print(self, underpath=True):
1035
+ r"""
1036
+ Displays a parking function as a lattice path consisting of a
1037
+ Dyck path and a labelling with the labels displayed along the
1038
+ edges of the Dyck path.
1039
+
1040
+ INPUT:
1041
+
1042
+ - ``underpath`` -- if the length of the parking function is
1043
+ less than or equal to 9 then display the labels under the
1044
+ path if ``underpath`` is ``True`` otherwise display them to the
1045
+ right of the path (default: ``True``)
1046
+
1047
+ EXAMPLES::
1048
+
1049
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
1050
+ sage: PF.pretty_print()
1051
+ ___
1052
+ _|1x
1053
+ |7x .
1054
+ _____|3 . .
1055
+ |5x x . . .
1056
+ _|4x . . . .
1057
+ |6x . . . . .
1058
+ |2 . . . . . .
1059
+
1060
+ sage: PF = ParkingFunction([6, 1, 5, 2, 2, 1, 5])
1061
+ sage: PF.pretty_print(underpath = false)
1062
+ ___
1063
+ _| x 1
1064
+ | x . 7
1065
+ _____| . . 3
1066
+ | x x . . . 5
1067
+ _| x . . . . 4
1068
+ | x . . . . . 6
1069
+ | . . . . . . 2
1070
+
1071
+ ::
1072
+
1073
+ sage: ParkingFunction([3, 1, 1, 4]).pretty_print()
1074
+ _
1075
+ _|4
1076
+ ___|1 .
1077
+ |3x . .
1078
+ |2 . . .
1079
+
1080
+ sage: ParkingFunction([1,1,1]).pretty_print()
1081
+ _____
1082
+ |3x x
1083
+ |2x .
1084
+ |1 . .
1085
+
1086
+ sage: ParkingFunction([4,1,1,1]).pretty_print()
1087
+ _
1088
+ _____|1
1089
+ |4x x .
1090
+ |3x . .
1091
+ |2 . . .
1092
+
1093
+ sage: ParkingFunction([2,1,4,1]).pretty_print()
1094
+ _
1095
+ ___|3
1096
+ _|1x .
1097
+ |4x . .
1098
+ |2 . . .
1099
+
1100
+ sage: ParkingFunction([2,1,4,1]).pretty_print(underpath = false)
1101
+ _
1102
+ ___| 3
1103
+ _| x . 1
1104
+ | x . . 4
1105
+ | . . . 2
1106
+
1107
+ sage: pf = ParkingFunction([1,2,3,7,3,2,1,2,3,2,1])
1108
+ sage: pf.pretty_print()
1109
+ _________
1110
+ _______| x x x x 4
1111
+ | x x x x x x x . 9
1112
+ | x x x x x x . . 5
1113
+ _| x x x x x . . . 3
1114
+ | x x x x x . . . . 10
1115
+ | x x x x . . . . . 8
1116
+ | x x x . . . . . . 6
1117
+ _| x x . . . . . . . 2
1118
+ | x x . . . . . . . . 11
1119
+ | x . . . . . . . . . 7
1120
+ | . . . . . . . . . . 1
1121
+ """
1122
+ L = self.to_labelling_permutation()
1123
+ dw = self.to_dyck_word()
1124
+ if len(L) <= 9:
1125
+ dw.pretty_print(labelling=L, underpath=underpath)
1126
+ else:
1127
+ dw.pretty_print(labelling=L, underpath=False)
1128
+
1129
+
1130
+ PF = ParkingFunction
1131
+
1132
+ # *****************************************************************************
1133
+ # CONSTRUCTIONS
1134
+ # *****************************************************************************
1135
+
1136
+
1137
+ def from_labelling_and_area_sequence(L, D) -> PF:
1138
+ r"""
1139
+ Return the parking function corresponding to the labelling area
1140
+ sequence pair.
1141
+
1142
+ INPUT:
1143
+
1144
+ - ``L`` -- a labelling permutation
1145
+
1146
+ - ``D`` -- an area sequence for a Dyck word
1147
+
1148
+ OUTPUT:
1149
+
1150
+ - the parking function corresponding the labelling permutation ``L``
1151
+ and ``D`` an area sequence of the corresponding Dyck path
1152
+
1153
+ EXAMPLES::
1154
+
1155
+ sage: from sage.combinat.parking_functions import from_labelling_and_area_sequence
1156
+ sage: from_labelling_and_area_sequence([2, 6, 4, 5, 3, 7, 1], [0, 1, 1, 2, 0, 1, 1])
1157
+ [6, 1, 5, 2, 2, 1, 5]
1158
+
1159
+ ::
1160
+
1161
+ sage: from_labelling_and_area_sequence([1, 2, 3], [0, 1, 2])
1162
+ [1, 1, 1]
1163
+ sage: from_labelling_and_area_sequence([1, 2, 3], [0, 0, 0])
1164
+ [1, 2, 3]
1165
+ sage: from_labelling_and_area_sequence([1, 2, 3], [0, 1, 1])
1166
+ [1, 1, 2]
1167
+ sage: from_labelling_and_area_sequence([1, 2, 4, 3], [0, 1, 2, 1])
1168
+ [1, 1, 3, 1]
1169
+
1170
+ TESTS::
1171
+
1172
+ sage: PF = from_labelling_and_area_sequence([1, 2, 4, 3], [0, 1, 2, 1])
1173
+ sage: isinstance(PF, ParkingFunctions().element_class)
1174
+ True
1175
+ """
1176
+ PF = ParkingFunctions_all()
1177
+ return PF.element_class(PF,
1178
+ [L.index(i) + 1 - D[L.index(i)]
1179
+ for i in range(1, len(L) + 1)])
1180
+
1181
+
1182
+ def from_labelled_dyck_word(LDW) -> PF:
1183
+ r"""
1184
+ Return the parking function corresponding to the labelled Dyck word.
1185
+
1186
+ INPUT:
1187
+
1188
+ - ``LDW`` -- labelled Dyck word
1189
+
1190
+ OUTPUT:
1191
+
1192
+ - the parking function corresponding to the labelled Dyck
1193
+ word that is half the size of ``LDW``
1194
+
1195
+ EXAMPLES::
1196
+
1197
+ sage: from sage.combinat.parking_functions import from_labelled_dyck_word
1198
+ sage: LDW = [2, 6, 0, 4, 5, 0, 0, 0, 3, 7, 0, 1, 0, 0]
1199
+ sage: from_labelled_dyck_word(LDW)
1200
+ [6, 1, 5, 2, 2, 1, 5]
1201
+
1202
+ ::
1203
+
1204
+ sage: from_labelled_dyck_word([2, 3, 0, 0, 1, 0, 4, 0])
1205
+ [3, 1, 1, 4]
1206
+ sage: from_labelled_dyck_word([2, 3, 4, 0, 0, 0, 1, 0])
1207
+ [4, 1, 1, 1]
1208
+ sage: from_labelled_dyck_word([2, 4, 0, 1, 0, 0, 3, 0])
1209
+ [2, 1, 4, 1]
1210
+ """
1211
+ L = [ell for ell in LDW if ell != 0]
1212
+ D = DyckWord([Integer(not x.is_zero()) for x in LDW]) # type:ignore
1213
+ return from_labelling_and_area_sequence(L, D.to_area_sequence())
1214
+
1215
+
1216
+ class ParkingFunctions(UniqueRepresentation, Parent):
1217
+ r"""
1218
+ Return the combinatorial class of Parking Functions.
1219
+
1220
+ A *parking function* of size `n` is a sequence `(a_1, \ldots,a_n)`
1221
+ of positive integers such that if `b_1 \leq b_2 \leq \cdots \leq b_n` is
1222
+ the increasing rearrangement of `a_1, \ldots, a_n`, then `b_i \leq i`.
1223
+
1224
+ A *parking function* of size `n` is a pair `(L, D)` of two sequences
1225
+ `L` and `D` where `L` is a permutation and `D` is an area sequence
1226
+ of a Dyck Path of size n such that `D[i] \geq 0`, `D[i+1] \leq D[i]+1`
1227
+ and if `D[i+1] = D[i]+1` then `L[i+1] > L[i]`.
1228
+
1229
+ The number of parking functions of size `n` is equal to the number
1230
+ of rooted forests on `n` vertices and is equal to `(n+1)^{n-1}`.
1231
+
1232
+ EXAMPLES:
1233
+
1234
+ Here are all parking functions of size 3::
1235
+
1236
+ sage: from sage.combinat.parking_functions import ParkingFunctions
1237
+ sage: ParkingFunctions(3).list()
1238
+ [[1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 1, 3], [1, 3, 1],
1239
+ [3, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1], [1, 2, 3], [1, 3, 2],
1240
+ [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
1241
+
1242
+ If no size is specified, then ParkingFunctions returns the
1243
+ combinatorial class of all parking functions. ::
1244
+
1245
+ sage: PF = ParkingFunctions(); PF
1246
+ Parking functions
1247
+ sage: [] in PF
1248
+ True
1249
+ sage: [1] in PF
1250
+ True
1251
+ sage: [2] in PF
1252
+ False
1253
+ sage: [1,3,1] in PF
1254
+ True
1255
+ sage: [1,4,1] in PF
1256
+ False
1257
+
1258
+ If the size `n` is specified, then ParkingFunctions returns
1259
+ the combinatorial class of all parking functions of size `n`.
1260
+
1261
+ ::
1262
+
1263
+ sage: PF = ParkingFunctions(0)
1264
+ sage: PF.list()
1265
+ [[]]
1266
+ sage: PF = ParkingFunctions(1)
1267
+ sage: PF.list()
1268
+ [[1]]
1269
+ sage: PF = ParkingFunctions(3)
1270
+ sage: PF.list()
1271
+ [[1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 1, 3],
1272
+ [1, 3, 1], [3, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1],
1273
+ [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
1274
+
1275
+ ::
1276
+
1277
+ sage: PF3 = ParkingFunctions(3); PF3
1278
+ Parking functions of size 3
1279
+ sage: [] in PF3
1280
+ False
1281
+ sage: [1] in PF3
1282
+ False
1283
+ sage: [1,3,1] in PF3
1284
+ True
1285
+ sage: [1,4,1] in PF3
1286
+ False
1287
+
1288
+ TESTS::
1289
+
1290
+ sage: PF = ParkingFunctions(5)
1291
+ sage: TestSuite(PF).run()
1292
+ sage: len(PF.list()) == PF.cardinality()
1293
+ True
1294
+ """
1295
+ @staticmethod
1296
+ def __classcall_private__(cls, n=None):
1297
+ """
1298
+ Return the correct parent based on input.
1299
+
1300
+ TESTS::
1301
+
1302
+ sage: type(ParkingFunctions(5))
1303
+ <class 'sage.combinat.parking_functions.ParkingFunctions_n_with_category'>
1304
+ sage: type(ParkingFunctions())
1305
+ <class 'sage.combinat.parking_functions.ParkingFunctions_all_with_category'>
1306
+ """
1307
+ if n is None:
1308
+ return ParkingFunctions_all()
1309
+
1310
+ if not isinstance(n, (Integer, int)) or n < 0:
1311
+ raise ValueError("%s is not a nonnegative integer" % n)
1312
+ return ParkingFunctions_n(n)
1313
+
1314
+
1315
+ class ParkingFunctions_all(ParkingFunctions):
1316
+ def __init__(self):
1317
+ """
1318
+ TESTS::
1319
+
1320
+ sage: PF = ParkingFunctions()
1321
+ sage: TestSuite(PF).run()
1322
+ """
1323
+ cat = InfiniteEnumeratedSets() & SetsWithGrading()
1324
+ Parent.__init__(self, category=cat)
1325
+
1326
+ Element = ParkingFunction
1327
+
1328
+ def _repr_(self) -> str:
1329
+ """
1330
+ TESTS::
1331
+
1332
+ sage: repr(ParkingFunctions())
1333
+ 'Parking functions'
1334
+ """
1335
+ return "Parking functions"
1336
+
1337
+ def __contains__(self, x) -> bool:
1338
+ """
1339
+ TESTS::
1340
+
1341
+ sage: [] in ParkingFunctions()
1342
+ True
1343
+ sage: [1] in ParkingFunctions()
1344
+ True
1345
+ sage: [2] in ParkingFunctions()
1346
+ False
1347
+ sage: [1,3,1] in ParkingFunctions()
1348
+ True
1349
+ sage: [1,4,1] in ParkingFunctions()
1350
+ False
1351
+ """
1352
+ if isinstance(x, ParkingFunction):
1353
+ return True
1354
+ return is_a(x)
1355
+
1356
+ def graded_component(self, n):
1357
+ """
1358
+ Return the graded component.
1359
+
1360
+ EXAMPLES::
1361
+
1362
+ sage: PF = ParkingFunctions()
1363
+ sage: PF.graded_component(4) == ParkingFunctions(4)
1364
+ True
1365
+ sage: it = iter(ParkingFunctions()) # indirect doctest
1366
+ sage: [next(it) for i in range(8)]
1367
+ [[], [1], [1, 1], [1, 2], [2, 1], [1, 1, 1], [1, 1, 2], [1, 2, 1]]
1368
+ """
1369
+ return ParkingFunctions_n(n)
1370
+
1371
+ def __iter__(self) -> Iterator:
1372
+ """
1373
+ Return an iterator.
1374
+
1375
+ TESTS::
1376
+
1377
+ sage: it = iter(ParkingFunctions()) # indirect doctest
1378
+ sage: [next(it) for i in range(8)]
1379
+ [[], [1], [1, 1], [1, 2], [2, 1], [1, 1, 1], [1, 1, 2], [1, 2, 1]]
1380
+ """
1381
+ n = 0
1382
+ while True:
1383
+ for pf in ParkingFunctions_n(n):
1384
+ yield self.element_class(self, list(pf))
1385
+ n += 1
1386
+
1387
+ def _coerce_map_from_(self, S):
1388
+ """
1389
+ Coercion from the homogeneous component to the graded set.
1390
+
1391
+ EXAMPLES::
1392
+
1393
+ sage: PF = ParkingFunctions()
1394
+ sage: PF3 = ParkingFunctions(3)
1395
+ sage: x = PF([1,3,2])
1396
+ sage: y = PF3([1,3,2])
1397
+ sage: PF(y).parent()
1398
+ Parking functions
1399
+ sage: x == y
1400
+ True
1401
+ """
1402
+ if isinstance(S, ParkingFunctions_n):
1403
+ return True
1404
+ return False
1405
+
1406
+
1407
+ class ParkingFunctions_n(ParkingFunctions):
1408
+ r"""
1409
+ The combinatorial class of parking functions of size `n`.
1410
+
1411
+ A *parking function* of size `n` is a sequence `(a_1, \ldots,a_n)`
1412
+ of positive integers such that if `b_1 \leq b_2 \leq \cdots \leq b_n` is
1413
+ the increasing rearrangement of `a_1, \ldots, a_n`, then `b_i \leq i`.
1414
+
1415
+ A *parking function* of size `n` is a pair `(L, D)` of two sequences
1416
+ `L` and `D` where `L` is a permutation and `D` is an area sequence
1417
+ of a Dyck Path of size `n` such that `D[i] \geq 0`, `D[i+1] \leq D[i]+1`
1418
+ and if `D[i+1] = D[i]+1` then `L[i+1] > L[i]`.
1419
+
1420
+ The number of parking functions of size `n` is equal to the number
1421
+ of rooted forests on `n` vertices and is equal to `(n+1)^{n-1}`.
1422
+
1423
+ EXAMPLES::
1424
+
1425
+ sage: PF = ParkingFunctions(3)
1426
+ sage: PF.list()
1427
+ [[1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 1, 3],
1428
+ [1, 3, 1], [3, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1],
1429
+ [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
1430
+
1431
+ sage: [ParkingFunctions(i).cardinality() for i in range(6)]
1432
+ [1, 1, 3, 16, 125, 1296]
1433
+
1434
+ .. WARNING::
1435
+
1436
+ The precise order in which the parking function are generated or
1437
+ listed is not fixed, and may change in the future.
1438
+
1439
+ TESTS:
1440
+
1441
+ Check that :issue:`15216` is fixed::
1442
+
1443
+ sage: PF = ParkingFunctions()
1444
+ sage: PF3 = ParkingFunctions(3)
1445
+ sage: [1,1,1] in PF3
1446
+ True
1447
+ sage: PF3([1,1,1]) in PF3
1448
+ True
1449
+ sage: PF3([1,1,1]) in PF
1450
+ True
1451
+ sage: PF([1,1,1]) in PF
1452
+ True
1453
+ sage: PF3(PF3([1,1,1]))
1454
+ [1, 1, 1]
1455
+ """
1456
+
1457
+ def __init__(self, n):
1458
+ """
1459
+ TESTS::
1460
+
1461
+ sage: PF = ParkingFunctions(3)
1462
+ sage: TestSuite(PF).run()
1463
+ """
1464
+ self.n = n
1465
+ Parent.__init__(self, category=FiniteEnumeratedSets())
1466
+
1467
+ Element = ParkingFunction
1468
+
1469
+ def _repr_(self) -> str:
1470
+ """
1471
+ TESTS::
1472
+
1473
+ sage: repr(ParkingFunctions(3))
1474
+ 'Parking functions of size 3'
1475
+ """
1476
+ return "Parking functions of size %s" % self.n
1477
+
1478
+ def __contains__(self, x) -> bool:
1479
+ """
1480
+ TESTS::
1481
+
1482
+ sage: PF3 = ParkingFunctions(3); PF3
1483
+ Parking functions of size 3
1484
+ sage: [] in PF3
1485
+ False
1486
+ sage: [1] in PF3
1487
+ False
1488
+ sage: [1,3,1] in PF3
1489
+ True
1490
+ sage: [1,1,1] in PF3
1491
+ True
1492
+ sage: [1,4,1] in PF3
1493
+ False
1494
+ sage: ParkingFunction([1,2]) in PF3
1495
+ False
1496
+ sage: all(p in PF3 for p in PF3)
1497
+ True
1498
+ """
1499
+ if isinstance(x, ParkingFunction) and len(x) == self.n:
1500
+ return True
1501
+ return is_a(x, self.n)
1502
+
1503
+ def cardinality(self) -> Integer:
1504
+ r"""
1505
+ Return the number of parking functions of size ``n``.
1506
+
1507
+ The cardinality is equal to `(n+1)^{n-1}`.
1508
+
1509
+ EXAMPLES::
1510
+
1511
+ sage: [ParkingFunctions(i).cardinality() for i in range(6)]
1512
+ [1, 1, 3, 16, 125, 1296]
1513
+ """
1514
+ return Integer((self.n + 1)**(self.n - 1))
1515
+
1516
+ def __iter__(self) -> Iterator:
1517
+ """
1518
+ Return an iterator for parking functions of size `n`.
1519
+
1520
+ .. WARNING::
1521
+
1522
+ The precise order in which the parking function are
1523
+ generated is not fixed, and may change in the future.
1524
+
1525
+ EXAMPLES::
1526
+
1527
+ sage: PF = ParkingFunctions(0)
1528
+ sage: [e for e in PF] # indirect doctest
1529
+ [[]]
1530
+ sage: PF = ParkingFunctions(1)
1531
+ sage: [e for e in PF] # indirect doctest
1532
+ [[1]]
1533
+ sage: PF = ParkingFunctions(2)
1534
+ sage: [e for e in PF] # indirect doctest
1535
+ [[1, 1], [1, 2], [2, 1]]
1536
+ sage: PF = ParkingFunctions(3)
1537
+ sage: [e for e in PF] # indirect doctest
1538
+ [[1, 1, 1], [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 1, 3],
1539
+ [1, 3, 1], [3, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1],
1540
+ [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
1541
+
1542
+ TESTS::
1543
+
1544
+ sage: PF = ParkingFunctions(5)
1545
+ sage: [e for e in PF] == PF.list()
1546
+ True
1547
+ sage: PF = ParkingFunctions(6)
1548
+ sage: [e for e in PF] == PF.list()
1549
+ True
1550
+ """
1551
+ def iterator_rec(n):
1552
+ """
1553
+ TESTS::
1554
+
1555
+ sage: PF = ParkingFunctions(2)
1556
+ sage: [e for e in PF] # indirect doctest
1557
+ [[1, 1], [1, 2], [2, 1]]
1558
+ """
1559
+ if n == 0:
1560
+ yield []
1561
+ return
1562
+ if n == 1:
1563
+ yield [1]
1564
+ return
1565
+ for res1 in iterator_rec(n - 1):
1566
+ for i in range(res1[-1], n + 1):
1567
+ yield res1 + [i]
1568
+ return
1569
+ for res in iterator_rec(self.n):
1570
+ for pi in Permutations(res):
1571
+ yield self.element_class(self, list(pi))
1572
+ return
1573
+
1574
+ def random_element(self) -> PF:
1575
+ r"""
1576
+ Return a random parking function of size `n`.
1577
+
1578
+ The algorithm uses a circular parking space with `n+1`
1579
+ spots. Then all `n` cars can park and there remains one empty
1580
+ spot. Spots are then renumbered so that the empty spot is `0`.
1581
+
1582
+ The probability distribution is uniform on the set of
1583
+ `(n+1)^{n-1}` parking functions of size `n`.
1584
+
1585
+ EXAMPLES::
1586
+
1587
+ sage: pf = ParkingFunctions(8)
1588
+ sage: a = pf.random_element(); a # random
1589
+ [5, 7, 2, 4, 2, 5, 1, 3]
1590
+ sage: a in pf
1591
+ True
1592
+ """
1593
+ n = self.n
1594
+ Zm = Zmod(n + 1)
1595
+ fun = [Zm(randint(0, n)) for i in range(n)]
1596
+ free = [Zm(j) for j in range(n + 1)]
1597
+ for car in fun:
1598
+ position = car
1599
+ while position not in free:
1600
+ position += Zm.one()
1601
+ free.remove(position)
1602
+ return self.element_class(self, [(i - free[0]).lift() for i in fun])