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,972 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ r"""
3
+ Module of trace monoids (free partially commutative monoids).
4
+
5
+ EXAMPLES:
6
+
7
+ We first create a trace monoid::
8
+
9
+ sage: from sage.monoids.trace_monoid import TraceMonoid
10
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a'))); M
11
+ Trace monoid on 3 generators ([a], [b], [c]) with independence relation {{a, c}}
12
+
13
+ Different elements can be equal because of the partially
14
+ commutative multiplication::
15
+
16
+ sage: c * a * b == a * c * b
17
+ True
18
+
19
+ We check that it is a monoid::
20
+
21
+ sage: M in Monoids()
22
+ True
23
+
24
+ REFERENCES:
25
+
26
+ - :wikipedia:`Trace_monoid`
27
+
28
+ - https://ncatlab.org/nlab/show/trace+monoid
29
+
30
+ AUTHORS:
31
+
32
+ - Pavlo Tokariev (2019-05-31): initial version
33
+ """
34
+ # ****************************************************************************
35
+ # Copyright (C) 2019 Pavlo Tokariev <pavlo.tokariev@gmail.com>
36
+ #
37
+ # This program is free software: you can redistribute it and/or modify
38
+ # it under the terms of the GNU General Public License as published by
39
+ # the Free Software Foundation, either version 2 of the License, or
40
+ # (at your option) any later version.
41
+ # https://www.gnu.org/licenses/
42
+ # ****************************************************************************
43
+
44
+ from itertools import repeat, chain, product
45
+
46
+ from sage.combinat.words.alphabet import Alphabet
47
+ from sage.misc.cachefunc import cached_method
48
+ from sage.misc.lazy_import import lazy_import
49
+ from sage.misc.misc_c import prod
50
+ from sage.monoids.free_monoid import FreeMonoid
51
+ from sage.monoids.monoid import Monoid_class
52
+ from sage.rings.integer_ring import ZZ
53
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
54
+ from sage.rings.power_series_ring import PowerSeriesRing
55
+ from sage.rings.infinity import infinity
56
+ from sage.structure.element import MonoidElement
57
+ from sage.structure.element_wrapper import ElementWrapper
58
+ from sage.structure.unique_representation import UniqueRepresentation
59
+
60
+ lazy_import('sage.graphs.digraph', 'DiGraph')
61
+ lazy_import('sage.graphs.graph', 'Graph')
62
+
63
+
64
+ class TraceMonoidElement(ElementWrapper, MonoidElement):
65
+ r"""
66
+ Element of a trace monoid, also known as a trace.
67
+
68
+ Elements of trace monoid is actually a equivalence classes
69
+ of related free monoid over some equivalence relation
70
+ that in the case is presented as independence relation.
71
+
72
+ .. RUBRIC:: Representative
73
+
74
+ We transform each trace to its lexicographic form for the
75
+ representative in the ambient free monoid. This is also used
76
+ for comparisons.
77
+
78
+ EXAMPLES::
79
+
80
+ sage: from sage.monoids.trace_monoid import TraceMonoid
81
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
82
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
83
+ sage: x = b * a * d * a * c * b
84
+ sage: x^3
85
+ [b*a^2*d*b^2*c*a^2*d*b^2*c*a^2*d*b*c]
86
+ sage: x^0
87
+ 1
88
+ sage: x.lex_normal_form()
89
+ b*a^2*d*b*c
90
+ sage: x.foata_normal_form()
91
+ (b, a*d, a, b*c)
92
+ """
93
+ def _repr_(self) -> str:
94
+ """
95
+ Textual representation of ``self``.
96
+
97
+ TESTS::
98
+
99
+ sage: from sage.monoids.trace_monoid import TraceMonoid
100
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
101
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
102
+ sage: a * b
103
+ [a*b]
104
+ sage: b * a
105
+ [b*a]
106
+ sage: d * a
107
+ [a*d]
108
+ """
109
+ if self == self.parent().one():
110
+ return "1"
111
+ return f"[{self.value}]"
112
+
113
+ def _richcmp_(self, other, op) -> bool:
114
+ r"""
115
+ Compare two traces by their lexicographic normal forms.
116
+
117
+ EXAMPLES::
118
+
119
+ sage: from sage.monoids.trace_monoid import TraceMonoid
120
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
121
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
122
+ sage: a^2 > a
123
+ True
124
+ sage: a*b < b*a
125
+ True
126
+ sage: a * c * b == a * b * c
127
+ True
128
+ """
129
+ return self.value._richcmp_(other.value, op)
130
+
131
+ def lex_normal_form(self):
132
+ r"""
133
+ Return the lexicographic normal form of ``self``.
134
+
135
+ OUTPUT: a free monoid element
136
+
137
+ EXAMPLES::
138
+
139
+ sage: from sage.monoids.trace_monoid import TraceMonoid
140
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
141
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
142
+ sage: (a*b).lex_normal_form()
143
+ a*b
144
+ sage: (b*a).lex_normal_form()
145
+ b*a
146
+ sage: (d*a).lex_normal_form()
147
+ a*d
148
+ """
149
+ return self.value
150
+
151
+ def foata_normal_form(self) -> tuple:
152
+ r"""
153
+ Return the Foata normal form of ``self``.
154
+
155
+ OUTPUT: tuple of free monoid elements
156
+
157
+ EXAMPLES::
158
+
159
+ sage: from sage.monoids.trace_monoid import TraceMonoid
160
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
161
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
162
+ sage: x = b * a * d * a * c * b
163
+ sage: x.foata_normal_form()
164
+ (b, a*d, a, b*c)
165
+ """
166
+ return self.parent()._compute_foata_normal_form(self.value)
167
+
168
+ def _mul_(self, other):
169
+ r"""
170
+ Concatenate one equivalence class with another.
171
+
172
+ EXAMPLES::
173
+
174
+ sage: from sage.monoids.trace_monoid import TraceMonoid
175
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
176
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
177
+ sage: a * b * c == a * c * b
178
+ True
179
+ """
180
+ return self.parent(self.value * other.value)
181
+
182
+ def _flat_elements(self):
183
+ r"""
184
+ Return flatten list of generator numbers representing the trace.
185
+
186
+ OUTPUT: list of generator indexes
187
+
188
+ TESTS::
189
+
190
+ sage: from sage.monoids.trace_monoid import TraceMonoid
191
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
192
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
193
+ sage: x = b * a^3 * d * a * c * b^2
194
+ sage: x._flat_elements()
195
+ [b, a, a, a, a, d, b, b, c]
196
+ """
197
+ return [g for g, times in self.value for _ in range(times)]
198
+
199
+ @cached_method
200
+ def dependence_graph(self):
201
+ r"""
202
+ Return dependence graph of the trace.
203
+
204
+ It is a directed graph where all dependent (non-commutative)
205
+ generators are connected by edges which
206
+ direction depend on the generator position in the trace.
207
+
208
+ OUTPUT: directed graph of generator indexes
209
+
210
+ EXAMPLES::
211
+
212
+ sage: from sage.monoids.trace_monoid import TraceMonoid
213
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
214
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
215
+ sage: x = b * a * d * a * c * b
216
+ sage: x.dependence_graph() # needs sage.graphs
217
+ Digraph on 6 vertices
218
+ """
219
+ elements = self._flat_elements()
220
+ independence = self.parent()._independence
221
+ graph = {}
222
+
223
+ for i, e in enumerate(elements):
224
+ edges = [(v, i) for v in graph
225
+ if (e, elements[v]) not in independence]
226
+ graph[i] = []
227
+ for v1, v2 in edges:
228
+ graph[v1].append(v2)
229
+
230
+ return DiGraph(graph)
231
+
232
+ @cached_method
233
+ def hasse_diagram(self, algorithm='naive'):
234
+ r"""
235
+ Return Hasse diagram of the trace.
236
+
237
+ Hasse diagram is a dependence graph without transitive edges.
238
+
239
+ INPUT:
240
+
241
+ - ``algorithm`` -- string (default: ``'naive'``); defines algorithm
242
+ that will be used to compute Hasse diagram; there are two
243
+ variants: ``'naive'`` and ``'min'``.
244
+
245
+ OUTPUT: directed graph of generator indexes
246
+
247
+ .. SEEALSO::
248
+
249
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.naive_hasse_digram`,
250
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.min_hasse_diagram`.
251
+
252
+ EXAMPLES::
253
+
254
+ sage: from sage.monoids.trace_monoid import TraceMonoid
255
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
256
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
257
+ sage: x = b * a * d * a * c * b
258
+ sage: x.hasse_diagram() # needs sage.graphs
259
+ Digraph on 6 vertices
260
+
261
+ TESTS::
262
+
263
+ sage: from sage.monoids.trace_monoid import TraceMonoid
264
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
265
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
266
+ sage: x = b * a * d * a * c * b
267
+ sage: x.hasse_diagram(algorithm='naive') == x.hasse_diagram(algorithm='min') # needs sage.graphs
268
+ True
269
+ sage: y = b * a^3 * d * a * c * b^2
270
+ sage: y.hasse_diagram(algorithm='naive') == y.hasse_diagram(algorithm='min') # needs sage.graphs
271
+ True
272
+ """
273
+ if algorithm == "naive":
274
+ return self.naive_hasse_diagram()
275
+ elif algorithm == "min":
276
+ return self.min_hasse_diagram()
277
+ raise ValueError("`alg` option must be `naive` "
278
+ f"or `min`, got `{algorithm}`.")
279
+
280
+ def min_hasse_diagram(self):
281
+ r"""
282
+ Return Hasse diagram of the trace.
283
+
284
+ OUTPUT: directed graph of generator indexes
285
+
286
+ .. SEEALSO::
287
+
288
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.hasse_digram`,
289
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.naive_hasse_diagram`.
290
+
291
+ EXAMPLES::
292
+
293
+ sage: from sage.monoids.trace_monoid import TraceMonoid
294
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
295
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
296
+ sage: x = b * a * d * a * c * b
297
+ sage: x.min_hasse_diagram() # needs sage.graphs
298
+ Digraph on 6 vertices
299
+ """
300
+ elements = self._flat_elements()
301
+ elements.reverse()
302
+ independence = self.parent()._independence
303
+ reachable = {}
304
+ mini = set()
305
+ graph = DiGraph({})
306
+
307
+ for i, x in enumerate(elements):
308
+ reachable[i] = set()
309
+ front = mini.copy()
310
+ while front:
311
+ used = set()
312
+ for j in list(front):
313
+ y = elements[j]
314
+ if (x, y) not in independence:
315
+ graph.add_edge(i, j)
316
+ reachable[i].add(j)
317
+ reachable[i].update(reachable[j])
318
+ if j in mini:
319
+ mini.remove(j)
320
+ used.add(j)
321
+ forbidden = set(chain.from_iterable(reachable[v] for v in used))
322
+ front = {dest for _, dest in graph.outgoing_edges(front, labels=False)}
323
+ front = front - forbidden
324
+
325
+ mini.add(i)
326
+
327
+ length = len(elements)
328
+ graph.relabel(length - 1 - i for i in range(length))
329
+ return graph
330
+
331
+ def naive_hasse_diagram(self):
332
+ r"""
333
+ Return Hasse diagram of ``self``.
334
+
335
+ ALGORITHM:
336
+
337
+ In loop check for every two pair of edges if they
338
+ have common vertex, remove their transitive edge.
339
+
340
+ OUTPUT: directed graph of generator indexes
341
+
342
+ .. SEEALSO::
343
+
344
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.hasse_digram`,
345
+ :meth:`~sage.monoids.trace_monoid.TraceMonoidElement.min_hasse_diagram`.
346
+
347
+ EXAMPLES::
348
+
349
+ sage: from sage.monoids.trace_monoid import TraceMonoid
350
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
351
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
352
+ sage: x = b * a * d * a * c * b
353
+ sage: x.naive_hasse_diagram() # needs sage.graphs
354
+ Digraph on 6 vertices
355
+ """
356
+ d = self.dependence_graph()
357
+ h = d.copy()
358
+
359
+ d_edges = d.edges(sort=False)
360
+ for e1 in d_edges:
361
+ for e2 in d_edges:
362
+ if e1[1] == e2[0]:
363
+ h.delete_edge((e1[0], e2[1]))
364
+
365
+ return h
366
+
367
+ def alphabet(self):
368
+ r"""
369
+ Return alphabet of ``self``.
370
+
371
+ OUTPUT: a set of free monoid generators
372
+
373
+ EXAMPLES::
374
+
375
+ sage: from sage.monoids.trace_monoid import TraceMonoid
376
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
377
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
378
+ sage: x = b*a*d*a*c*b
379
+ sage: x.alphabet()
380
+ {b, a, d, c}
381
+ """
382
+ return Alphabet([g for g, _ in self.value])
383
+
384
+ def projection(self, letters):
385
+ r"""
386
+ Return a trace that formed from ``self`` by erasing ``letters``.
387
+
388
+ INPUT:
389
+
390
+ - ``letters`` -- set of generators; defines set of letters that will be
391
+ used to filter the trace
392
+
393
+ OUTPUT: a trace
394
+
395
+ EXAMPLES::
396
+
397
+ sage: from sage.monoids.trace_monoid import TraceMonoid
398
+ sage: F.<a,b,c,d> = FreeMonoid()
399
+ sage: I = ((a,d), (d,a), (b,c), (c,b))
400
+ sage: M.<ac,bc,cc,dc> = TraceMonoid(F, I=I)
401
+ sage: x = M(b*a*d*a*c*b)
402
+ sage: x.projection({a,b})
403
+ [b*a^2*b]
404
+ sage: x.projection({b,d,c})
405
+ [b*d*b*c]
406
+ """
407
+ P = self.parent()
408
+ base = P._free_monoid
409
+ return P(base.prod(x for x in self._flat_elements() if x in letters))
410
+
411
+ def multiplicative_order(self):
412
+ r"""
413
+ Return the multiplicative order of ``self``, which is `\infty`
414
+ for any element not the identity.
415
+
416
+ EXAMPLES::
417
+
418
+ sage: from sage.monoids.trace_monoid import TraceMonoid
419
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
420
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
421
+ sage: a.multiplicative_order()
422
+ +Infinity
423
+ sage: M.one().multiplicative_order()
424
+ 1
425
+ """
426
+ if self.value.is_one():
427
+ return ZZ.one()
428
+ return infinity
429
+
430
+
431
+ class TraceMonoid(UniqueRepresentation, Monoid_class):
432
+ r"""
433
+ Return a free partially commuting monoid (trace monoid) on `n` generators
434
+ over independence relation `I`.
435
+
436
+ We construct a trace monoid by specifying:
437
+
438
+ - a free monoid and independence relation
439
+ - or generator names and independence relation,
440
+ FreeMonoid is constructed automatically then.
441
+
442
+ INPUT:
443
+
444
+ - ``M`` -- a free monoid
445
+
446
+ - ``I`` -- commutation relation between generators
447
+ (or their names if the ``names`` are given)
448
+
449
+ - ``names`` -- names of generators
450
+
451
+ EXAMPLES::
452
+
453
+ sage: from sage.monoids.trace_monoid import TraceMonoid
454
+ sage: F = TraceMonoid(names=('a', 'b', 'c'), I={('a','c'), ('c','a')}); F
455
+ Trace monoid on 3 generators ([a], [b], [c]) with independence relation {{a, c}}
456
+ sage: x = F.gens()
457
+ sage: x[0]*x[1]**5 * (x[0]*x[2])
458
+ [a*b^5*a*c]
459
+
460
+ sage: from sage.monoids.trace_monoid import TraceMonoid
461
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
462
+ sage: latex(M)
463
+ \langle a, b, c \mid ac=ca \rangle
464
+
465
+ TESTS::
466
+
467
+ sage: from sage.monoids.trace_monoid import TraceMonoid
468
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
469
+ sage: M.number_of_words(3) == len(M.words(3)) # needs sage.graphs
470
+ True
471
+ """
472
+ Element = TraceMonoidElement
473
+
474
+ @staticmethod
475
+ def __classcall_private__(cls, M=None, I=frozenset(), names=None):
476
+ """
477
+ Normalize input to ensure a unique representation.
478
+
479
+ TESTS::
480
+
481
+ sage: from sage.monoids.trace_monoid import TraceMonoid
482
+ sage: M1.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
483
+ sage: M2.<a,b,c> = TraceMonoid(I=[('a','c')])
484
+ sage: M3 = TraceMonoid(I=[{'a','c'}], names=('a', 'b', 'c'))
485
+ sage: M1 is M2 and M2 is M3
486
+ True
487
+ """
488
+ if not M:
489
+ if names:
490
+ M = FreeMonoid(names=names)
491
+ else:
492
+ raise ValueError("names must be provided")
493
+ elif not names:
494
+ names = [str(g) for g in M.gens()]
495
+ names = tuple(names)
496
+
497
+ rels = set()
498
+ gen_from_str = {names[i]: gen for i, gen in enumerate(M.gens())}
499
+ for x, y in I:
500
+ try:
501
+ if isinstance(x, str):
502
+ x = gen_from_str[x]
503
+ x = M(x)
504
+ if isinstance(y, str):
505
+ y = gen_from_str[y]
506
+ y = M(y)
507
+ if x == y:
508
+ raise ValueError
509
+ except (TypeError, ValueError):
510
+ raise ValueError("invalid relation defined")
511
+ rels.add((x, y))
512
+ rels.add((y, x))
513
+ I = frozenset(rels)
514
+
515
+ return super().__classcall__(cls, M, I, names)
516
+
517
+ def __init__(self, M, I, names) -> None:
518
+ r"""
519
+ Initialize ``self``.
520
+
521
+ TESTS::
522
+
523
+ sage: from sage.monoids.trace_monoid import TraceMonoid
524
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
525
+ sage: TestSuite(M).run()
526
+ """
527
+ self._free_monoid = M
528
+ self._independence = I
529
+ Monoid_class.__init__(self, names=names)
530
+
531
+ def ngens(self):
532
+ """
533
+ Return the number of generators of ``self``.
534
+
535
+ EXAMPLES::
536
+
537
+ sage: from sage.monoids.trace_monoid import TraceMonoid
538
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
539
+ sage: M.ngens()
540
+ 3
541
+ """
542
+ return self._free_monoid.ngens()
543
+
544
+ def one(self):
545
+ """
546
+ Return the neutral element of ``self``.
547
+
548
+ EXAMPLES::
549
+
550
+ sage: from sage.monoids.trace_monoid import TraceMonoid
551
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
552
+ sage: M.one()
553
+ 1
554
+ """
555
+ return self.element_class(self, self._free_monoid.one())
556
+
557
+ def gen(self, i=0):
558
+ """
559
+ Return the `i`-th generator of the monoid.
560
+
561
+ INPUT:
562
+
563
+ - ``i`` -- integer (default: 0)
564
+
565
+ EXAMPLES::
566
+
567
+ sage: from sage.monoids.trace_monoid import TraceMonoid
568
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
569
+ sage: M.gen(1)
570
+ [b]
571
+ sage: M.gen(4)
572
+ Traceback (most recent call last):
573
+ ...
574
+ IndexError: argument i (= 4) must be between 0 and 2
575
+ """
576
+ return self.element_class(self, self._free_monoid.gen(i))
577
+
578
+ def cardinality(self):
579
+ """
580
+ Return the cardinality of ``self``, which is infinite except for
581
+ the trivial monoid.
582
+
583
+ EXAMPLES::
584
+
585
+ sage: from sage.monoids.trace_monoid import TraceMonoid
586
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
587
+ sage: M.cardinality()
588
+ +Infinity
589
+ """
590
+ return self._free_monoid.cardinality()
591
+
592
+ def _compute_dependence_stack(self, x):
593
+ r"""
594
+ Return generator stacks formed from trace
595
+ subelements with respect to non-commutativity.
596
+
597
+ OUTPUT: used generators and list of stacks as tuple
598
+
599
+ ALGORITHM:
600
+
601
+ Let `x` be a word of monoid; we scan `x` from right to left;
602
+ when processing a letter `a` it is pushed on its stack and a
603
+ marker is pushed on the stack of all the letters `b` ( `b \neq a` )
604
+ which do not commute with `a`.
605
+
606
+ TESTS::
607
+
608
+ sage: from sage.monoids.trace_monoid import TraceMonoid
609
+ sage: F.<a,b,c,d> = FreeMonoid()
610
+ sage: I = (('ac','dc'), ('dc','ac'), ('bc','cc'), ('cc','bc'))
611
+ sage: M.<ac,bc,cc,dc> = TraceMonoid(F, I=I)
612
+ sage: x = b*a*d*a*c*b
613
+ sage: M._compute_dependence_stack(x)
614
+ ({a, b, c, d},
615
+ {a: [False, False, True, True, False],
616
+ b: [True, False, False, False, True],
617
+ c: [True, False, False, False],
618
+ d: [False, False, True, False]})
619
+ """
620
+ independence = self._independence
621
+ generators_set = {e for e, _ in x}
622
+ stacks = dict(sorted((g, []) for g in generators_set))
623
+ for generator, times in reversed(list(x)):
624
+ stacks[generator].extend(repeat(True, times))
625
+ for other_gen in generators_set:
626
+ if other_gen == generator:
627
+ continue
628
+ if (generator, other_gen) not in independence:
629
+ stacks[other_gen].extend(repeat(False, times))
630
+ return generators_set, stacks
631
+
632
+ @cached_method
633
+ def _compute_lex_normal_form(self, x):
634
+ r"""
635
+ Return lexicographic normal form of the free monoid
636
+ element in free monoid terms.
637
+
638
+ OUTPUT: trace monoid element
639
+
640
+ ALGORITHM:
641
+
642
+ Take among the letters being on the top of some stack that
643
+ letter `a` being minimal with respect to the given lexicographic
644
+ ordering. We pop a marker from each stack corresponding to a
645
+ letter `b` ( `b \neq a` ) which does not commute with `a`. We repeat
646
+ this loop until all stacks are empty.
647
+
648
+ EXAMPLES::
649
+
650
+ sage: from sage.monoids.trace_monoid import TraceMonoid
651
+ sage: F.<a,b,c,d> = FreeMonoid()
652
+ sage: I = ((a,d), (d,a), (b,c), (c,b))
653
+ sage: M.<ac,bc,cc,dc> = TraceMonoid(F, I=I)
654
+ sage: M._compute_lex_normal_form(c*a*c*b*a^2)
655
+ c*a*b*c*a^2
656
+ """
657
+ if not x._element_list:
658
+ return x
659
+ generators_set, stacks = self._compute_dependence_stack(x)
660
+ independence = self._independence
661
+
662
+ elements = []
663
+ while any(stacks.values()):
664
+ for generator, g_stack in stacks.items():
665
+ if g_stack and g_stack[-1]:
666
+ g_stack.pop()
667
+ elements.append(generator)
668
+ for other_gen in generators_set:
669
+ if (other_gen != generator
670
+ and (generator, other_gen) not in independence):
671
+ stacks[other_gen].pop()
672
+ break
673
+
674
+ return prod(elements)
675
+
676
+ @cached_method
677
+ def _compute_foata_normal_form(self, x) -> tuple:
678
+ r"""
679
+ Return Foata normal form of the monoid element.
680
+
681
+ OUTPUT: tuple of steps
682
+
683
+ ALGORITHM:
684
+
685
+ Within a loop we form the set using letters being
686
+ on the top of stacks; arranging the letters in the lexicographic
687
+ order yields a step of the Foata normal form;
688
+ This loop is repeated until all stacks are empty.
689
+
690
+ EXAMPLES::
691
+
692
+ sage: from sage.monoids.trace_monoid import TraceMonoid
693
+ sage: F.<a,b,c,d> = FreeMonoid()
694
+ sage: I = ((a,d), (d,a), (b,c), (c,b))
695
+ sage: M.<ac,bc,cc,dc> = TraceMonoid(F, I=I)
696
+ sage: x = b*a*d*a*c*b
697
+ sage: M._compute_foata_normal_form(x)
698
+ (b, a*d, a, b*c)
699
+ sage: y = b*a*a*d*b*a*b*c^2*a
700
+ sage: M._compute_foata_normal_form(y)
701
+ (b, a*d, a, b, a, b*c, c, a)
702
+ """
703
+ if not x._element_list:
704
+ return ()
705
+
706
+ generators_set, stacks = self._compute_dependence_stack(x)
707
+ independence = self._independence
708
+
709
+ steps = []
710
+ while any(stacks.values()):
711
+ step = []
712
+ for generator, g_stack in stacks.items():
713
+ if g_stack and g_stack[-1]:
714
+ g_stack.pop()
715
+ step.append(generator)
716
+
717
+ for g in step:
718
+ for other_gen in generators_set:
719
+ if other_gen != g and (g, other_gen) not in independence:
720
+ stacks[other_gen].pop()
721
+
722
+ steps.append(step)
723
+
724
+ return tuple(prod(step) for step in steps)
725
+
726
+ def _element_constructor_(self, x):
727
+ """
728
+ Return ``x`` coerced into this trace monoid.
729
+
730
+ One can create a free monoid element from the integer 1,
731
+ free monoid elements of the same generators as internal one,
732
+ and coerce everything that can coerce free monoid.
733
+
734
+ EXAMPLES::
735
+
736
+ sage: from sage.monoids.trace_monoid import TraceMonoid
737
+ sage: F.<a,b,c,d> = FreeMonoid()
738
+ sage: I = ((a,d), (d,a), (b,c), (c,b))
739
+ sage: M.<ac,bc,cc,dc> = TraceMonoid(F, I=I)
740
+ sage: x = b*a*d*a*c*b
741
+ sage: M(x)
742
+ [b*a^2*d*b*c]
743
+ """
744
+ x = self._compute_lex_normal_form(self._free_monoid(x))
745
+ return self.element_class(self, x)
746
+
747
+ @cached_method
748
+ def independence(self):
749
+ r"""
750
+ Return independence relation over the monoid.
751
+
752
+ OUTPUT: set of commuting generator pairs
753
+
754
+ EXAMPLES::
755
+
756
+ sage: from sage.monoids.trace_monoid import TraceMonoid
757
+ sage: F.<a,b,c> = FreeMonoid()
758
+ sage: I = frozenset(((a,c), (c,a)))
759
+ sage: M.<ac,bc,cc> = TraceMonoid(F, I=I)
760
+ sage: M.independence() == frozenset([frozenset([a,c])])
761
+ True
762
+ """
763
+ return frozenset(map(frozenset, self._independence))
764
+
765
+ @cached_method
766
+ def dependence(self):
767
+ r"""
768
+ Return dependence relation over the monoid.
769
+
770
+ OUTPUT: set of non-commuting generator pairs
771
+
772
+ EXAMPLES::
773
+
774
+ sage: from sage.monoids.trace_monoid import TraceMonoid
775
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','c'), ('c','a')))
776
+ sage: sorted(M.dependence())
777
+ [(a, a), (a, b), (b, a), (b, b), (b, c), (c, b), (c, c)]
778
+ """
779
+ return frozenset(pair for pair in product(self._free_monoid.gens(), repeat=2)
780
+ if pair not in self._independence)
781
+
782
+ @cached_method
783
+ def dependence_graph(self):
784
+ r"""
785
+ Return graph of dependence relation.
786
+
787
+ OUTPUT: dependence graph with generators as vertices
788
+
789
+ TESTS::
790
+
791
+ sage: from sage.monoids.trace_monoid import TraceMonoid
792
+ sage: F.<a,b,c> = FreeMonoid()
793
+ sage: M.<ai,bi,ci> = TraceMonoid(F, I=((a,c), (c,a)))
794
+ sage: M.dependence_graph() == Graph({a:[a,b], b:[b], c:[c,b]}) # needs sage.graphs
795
+ True
796
+ """
797
+ return Graph({frozenset((e1, e2)) if e1 != e2 else (e1, e2)
798
+ for e1, e2 in self.dependence()}, loops=True,
799
+ format='list_of_edges',
800
+ immutable=True)
801
+
802
+ @cached_method
803
+ def independence_graph(self):
804
+ r"""
805
+ Return the digraph of independence relations.
806
+
807
+ OUTPUT: independence graph with generators as vertices
808
+
809
+ TESTS::
810
+
811
+ sage: from sage.monoids.trace_monoid import TraceMonoid
812
+ sage: F.<a,b,c> = FreeMonoid()
813
+ sage: M.<ai,bi,ci> = TraceMonoid(F, I=((a,c), (c,a)))
814
+ sage: M.independence_graph() == Graph({a:[c], b:[], c:[]}) # needs sage.graphs
815
+ True
816
+ """
817
+ verts = list(self._free_monoid.gens())
818
+ edges = list(map(list, self.independence()))
819
+ return Graph([verts, edges], immutable=True)
820
+
821
+ @cached_method
822
+ def dependence_polynomial(self, t=None):
823
+ r"""
824
+ Return dependence polynomial.
825
+
826
+ The polynomial is defined as follows: `\sum{i}{(-1)^i c_i t^i}`,
827
+ where `c_i` equals to number of full subgraphs
828
+ of size `i` in the independence graph.
829
+
830
+ OUTPUT: a rational function in ``t`` with coefficients in the integer ring
831
+
832
+ EXAMPLES::
833
+
834
+ sage: from sage.monoids.trace_monoid import TraceMonoid
835
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
836
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
837
+ sage: M.dependence_polynomial() # needs sage.graphs
838
+ 1/(2*t^2 - 4*t + 1)
839
+ """
840
+ if t is None:
841
+ R = PolynomialRing(ZZ, 't')
842
+ t = R.gen()
843
+ clique_seq = self.independence_graph().clique_polynomial().coefficients()
844
+ return ~sum((-1)**i * coeff * (t**i)
845
+ for i, coeff in enumerate(clique_seq))
846
+
847
+ @cached_method
848
+ def number_of_words(self, length):
849
+ r"""
850
+ Return number of unique words of defined length.
851
+
852
+ INPUT:
853
+
854
+ - ``length`` -- integer; defines size of words what number should be computed
855
+
856
+ OUTPUT: words number as integer
857
+
858
+ EXAMPLES:
859
+
860
+ Get number of words of size 3 ::
861
+
862
+ sage: from sage.monoids.trace_monoid import TraceMonoid
863
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
864
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
865
+ sage: M.number_of_words(3) # needs sage.graphs
866
+ 48
867
+ """
868
+ psr = PowerSeriesRing(ZZ, default_prec=length + 1)
869
+ return psr(self.dependence_polynomial()).coefficients()[length]
870
+
871
+ @cached_method
872
+ def words(self, length):
873
+ r"""
874
+ Return all lexicographic forms of defined length.
875
+
876
+ INPUT:
877
+
878
+ - ``length`` -- integer; defines size of words
879
+
880
+ OUTPUT: set of traces of size ``length``
881
+
882
+ EXAMPLES:
883
+
884
+ All words of size 2::
885
+
886
+ sage: from sage.monoids.trace_monoid import TraceMonoid
887
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
888
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
889
+ sage: sorted(M.words(2))
890
+ [[a^2], [a*b], [a*c], [a*d], [b*a], [b^2], [b*c],
891
+ [b*d], [c*a], [c^2], [c*d], [d*b], [d*c], [d^2]]
892
+
893
+ Get number of words of size 3::
894
+
895
+ sage: from sage.monoids.trace_monoid import TraceMonoid
896
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
897
+ sage: M.<a,b,c,d> = TraceMonoid(I=I)
898
+ sage: len(M.words(3))
899
+ 48
900
+
901
+ TESTS::
902
+
903
+ sage: from sage.monoids.trace_monoid import TraceMonoid
904
+ sage: M.<a,b,c> = TraceMonoid(I=(('a','b'), ('b','a'), ('b', 'c'), ('c', 'b')))
905
+ sage: for i in range(10): # needs sage.graphs
906
+ ....: assert len(M.words(i)) == M.number_of_words(i)
907
+ """
908
+ if length < 0:
909
+ raise ValueError("bad length of words; expected zero or positive number")
910
+ if length == 0:
911
+ return frozenset([self.one()])
912
+ if length == 1:
913
+ return frozenset(self.gens())
914
+
915
+ return frozenset([word * suffix for word in self.words(length - 1)
916
+ for suffix in self.gens()
917
+ if not ((list(word.value)[-1][0], suffix.value) in self._independence
918
+ and list(word.value)[-1][0] > suffix.value)])
919
+
920
+ def _sorted_independence(self) -> list:
921
+ r"""
922
+ Return independence relation over the monoid.
923
+
924
+ OUTPUT: sorted list of sorted commuting generator pairs
925
+
926
+ EXAMPLES::
927
+
928
+ sage: from sage.monoids.trace_monoid import TraceMonoid
929
+ sage: F.<a,b,c> = FreeMonoid()
930
+ sage: I = frozenset(((a,c), (c,a)))
931
+ sage: M.<ac,bc,cc> = TraceMonoid(F, I=I)
932
+ sage: M._sorted_independence()
933
+ [[a, c]]
934
+ """
935
+ return sorted(sorted(x_y)
936
+ for x_y in self.independence())
937
+
938
+ def _repr_(self) -> str:
939
+ r"""
940
+ Textual representation of trace monoids.
941
+
942
+ TESTS::
943
+
944
+ sage: from sage.monoids.trace_monoid import TraceMonoid
945
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
946
+ sage: M.<a,b,c,d> = TraceMonoid(I=I); M
947
+ Trace monoid on 4 generators ([a], [b], [c], [d])
948
+ with independence relation {{a, d}, {b, c}}
949
+ """
950
+ return ("Trace monoid on {!s} generators {!s} "
951
+ "with independence relation {{{}}}").format(self.ngens(), self.gens(),
952
+ ", ".join(f"{{{x}, {y}}}"
953
+ for (x, y) in self._sorted_independence()))
954
+
955
+ def _latex_(self) -> str:
956
+ r"""
957
+ LaTeX representation of trace monoids.
958
+
959
+ TESTS::
960
+
961
+ sage: from sage.monoids.trace_monoid import TraceMonoid
962
+ sage: I = (('a','d'), ('d','a'), ('b','c'), ('c','b'))
963
+ sage: M.<a,b,c,d> = TraceMonoid(I=I); latex(M)
964
+ \langle a, b, c, d \mid ad=da,bc=cb \rangle
965
+ """
966
+ return "\\langle {} \\mid {} \\rangle".format(
967
+ repr(self._free_monoid.gens())[1:-1],
968
+ ",".join(
969
+ f"{v1!r}{v2!r}={v2!r}{v1!r}"
970
+ for v1, v2 in self._sorted_independence()
971
+ )
972
+ )