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,1722 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ r"""
3
+ Abstract word (finite or infinite)
4
+
5
+ This module gathers functions that works for both finite and infinite
6
+ words.
7
+
8
+ AUTHORS:
9
+
10
+ - Sébastien Labbé
11
+ - Franco Saliola
12
+
13
+ EXAMPLES::
14
+
15
+ sage: a = 0.618
16
+ sage: g = words.CodingOfRotationWord(alpha=a, beta=1-a, x=a)
17
+ sage: f = words.FibonacciWord()
18
+ sage: p = f.longest_common_prefix(g, length='finite')
19
+ sage: p
20
+ word: 0100101001001010010100100101001001010010...
21
+ sage: p.length()
22
+ 231
23
+ """
24
+ # ****************************************************************************
25
+ # Copyright (C) 2008-2010 Sebastien Labbe <slabqc@gmail.com>,
26
+ # 2008-2010 Franco Saliola <saliola@gmail.com>
27
+ #
28
+ # This program is free software: you can redistribute it and/or modify
29
+ # it under the terms of the GNU General Public License as published by
30
+ # the Free Software Foundation, either version 2 of the License, or
31
+ # (at your option) any later version.
32
+ # https://www.gnu.org/licenses/
33
+ # ****************************************************************************
34
+ from itertools import islice, groupby
35
+
36
+ from sage.structure.sage_object import SageObject
37
+ from sage.combinat.words.word_options import word_options
38
+ from sage.rings.finite_rings.integer_mod_ring import Integers
39
+ from sage.rings.infinity import Infinity
40
+ from sage.rings.integer_ring import ZZ
41
+ from sage.structure.richcmp import richcmp_method, rich_to_bool, richcmp_item
42
+
43
+
44
+ @richcmp_method
45
+ class Word_class(SageObject):
46
+ def parent(self):
47
+ r"""
48
+ Return the parent of ``self``.
49
+
50
+ TESTS::
51
+
52
+ sage: Word(iter([1,2,3]), length='unknown').parent()
53
+ Finite words over Set of Python objects of class 'object'
54
+ sage: Word(range(12)).parent()
55
+ Finite words over Set of Python objects of class 'object'
56
+ sage: Word(range(4), alphabet=list(range(6))).parent()
57
+ Finite words over {0, 1, 2, 3, 4, 5}
58
+ sage: Word(iter('abac'), alphabet='abc').parent()
59
+ Finite words over {'a', 'b', 'c'}
60
+ """
61
+ return self._parent
62
+
63
+ def _repr_(self):
64
+ r"""
65
+ Return a string representation of ``self``.
66
+
67
+ TESTS::
68
+
69
+ sage: Word(iter([1,2,3]), length='unknown')._repr_()
70
+ 'word: 123'
71
+ sage: Word(range(100), length='unknown')._repr_()
72
+ 'word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...'
73
+ sage: Word(lambda x:x%3)._repr_()
74
+ 'word: 0120120120120120120120120120120120120120...'
75
+ """
76
+ if word_options['old_repr']:
77
+ return "Word over %s" % (str(self.parent().alphabet())[17:])
78
+ return word_options['identifier'] + self.string_rep()
79
+
80
+ def string_rep(self):
81
+ r"""
82
+ Return the (truncated) raw sequence of letters as a string.
83
+
84
+ EXAMPLES::
85
+
86
+ sage: Word('abbabaab').string_rep()
87
+ 'abbabaab'
88
+ sage: Word([0, 1, 0, 0, 1]).string_rep()
89
+ '01001'
90
+ sage: Word([0,1,10,101]).string_rep()
91
+ '0,1,10,101'
92
+ sage: WordOptions(letter_separator='-')
93
+ sage: Word([0,1,10,101]).string_rep()
94
+ '0-1-10-101'
95
+ sage: WordOptions(letter_separator=',')
96
+
97
+ TESTS:
98
+
99
+ Insertion in a str::
100
+
101
+ sage: from itertools import count
102
+ sage: w = Word((i % 5 for i in count()), length='unknown')
103
+ sage: "w = %s in this string." % w
104
+ 'w = 0123401234012340123401234012340123401234... in this string.'
105
+
106
+ Using LatexExpr::
107
+
108
+ sage: from sage.misc.latex import LatexExpr
109
+ sage: LatexExpr(w)
110
+ 0123401234012340123401234012340123401234...
111
+
112
+ With the print statement::
113
+
114
+ sage: print(w)
115
+ 0123401234012340123401234012340123401234...
116
+
117
+ Truncation is done for possibly infinite words::
118
+
119
+ sage: print(w)
120
+ 0123401234012340123401234012340123401234...
121
+ """
122
+ l = word_options['truncate_length']
123
+ letters = list(islice(self, int(l + 1)))
124
+ if len(letters) == l + 1:
125
+ letters.pop()
126
+ suffix = "..."
127
+ else:
128
+ suffix = ""
129
+ if word_options['display'] == 'string':
130
+ ls = word_options['letter_separator']
131
+ letters = [str(a) for a in letters]
132
+ if all(len(a) == 1 for a in letters):
133
+ return ''.join(letters) + suffix
134
+ elif suffix == "...":
135
+ return ls.join(letters) + ls + suffix
136
+ else:
137
+ return ls.join(letters)
138
+ elif word_options['display'] == 'list':
139
+ if suffix == "...":
140
+ return "[%s, %s]" % (str(letters)[1:-1], suffix)
141
+ else:
142
+ return str(letters)
143
+
144
+ __str__ = string_rep
145
+
146
+ def __iter__(self):
147
+ r"""
148
+ EXAMPLES::
149
+
150
+ sage: from sage.combinat.words.word import Word_class
151
+ sage: w = Word_class()
152
+ sage: w.__iter__()
153
+ Traceback (most recent call last):
154
+ ...
155
+ NotImplementedError: you need to define an iterator in __iter__
156
+ """
157
+ raise NotImplementedError("you need to define an iterator in __iter__")
158
+
159
+ def length(self):
160
+ r"""
161
+ Return the length of ``self``.
162
+
163
+ TESTS::
164
+
165
+ sage: from sage.combinat.words.word import Word_class
166
+ sage: w = Word(iter('abba'*100), length='unknown')
167
+ sage: w.length() is None
168
+ True
169
+ sage: w = Word(iter('abba'), length='finite')
170
+ sage: w.length()
171
+ 4
172
+ sage: w = Word(iter([0,1,1,0,1,0,0,1]*100), length='unknown')
173
+ sage: w.length() is None
174
+ True
175
+ sage: w = Word(iter([0,1,1,0,1,0,0,1]), length='finite')
176
+ sage: w.length()
177
+ 8
178
+ """
179
+ return self._len
180
+
181
+ def is_finite(self):
182
+ r"""
183
+ Return whether this word is known to be finite.
184
+
185
+ .. WARNING::
186
+
187
+ A word defined by an iterator such that its end has
188
+ never been reached will returns False.
189
+
190
+ EXAMPLES::
191
+
192
+ sage: Word([]).is_finite()
193
+ True
194
+ sage: Word('a').is_finite()
195
+ True
196
+ sage: TM = words.ThueMorseWord()
197
+ sage: TM.is_finite()
198
+ False
199
+
200
+ ::
201
+
202
+ sage: w = Word(iter('a'*100))
203
+ sage: w.is_finite()
204
+ False
205
+ """
206
+ return False
207
+
208
+ def __len__(self):
209
+ r"""
210
+ Return the length of ``self`` (as a Python integer).
211
+
212
+ .. NOTE::
213
+
214
+ For infinite words or words of unknown length,
215
+ use `length()` method instead.
216
+
217
+ OUTPUT: positive integer
218
+
219
+ EXAMPLES::
220
+
221
+ sage: len(Word(lambda n:n, length=1000))
222
+ 1000
223
+ sage: len(Word(iter('a'*200), length='finite'))
224
+ 200
225
+
226
+ We make sure :issue:`8574` is fixed::
227
+
228
+ sage: s = WordMorphism('0->000,1->%s'%('1'*100))
229
+ sage: len(s('1'))
230
+ 100
231
+
232
+ For infinite words::
233
+
234
+ sage: len(Word(lambda n:n))
235
+ Traceback (most recent call last):
236
+ ...
237
+ TypeError: Python len method cannot return a non integer value (=+Infinity): use length method instead.
238
+ sage: len(Word(iter('a'*200)))
239
+ Traceback (most recent call last):
240
+ ...
241
+ TypeError: Python len method cannot return a non integer value (=None): use length method instead.
242
+
243
+ For words of unknown length::
244
+
245
+ sage: len(Word(iter('a'*200), length='unknown'))
246
+ Traceback (most recent call last):
247
+ ...
248
+ TypeError: Python len method cannot return a non integer value (=None): use length method instead.
249
+ """
250
+ L = self.length()
251
+ if L is None or L is Infinity:
252
+ msg = "Python len method cannot return a non integer value (=%s): " % L
253
+ msg += "use length method instead."
254
+ raise TypeError(msg)
255
+ return int(L)
256
+
257
+ def __richcmp__(self, other, op):
258
+ r"""
259
+ Compare two words lexicographically according to the ordering
260
+ defined by the parent of ``self``.
261
+
262
+ This corresponds to Python's built-in
263
+ ordering when no parent nor alphabet was used to defined the word.
264
+
265
+ Provides for all normal comparison operators.
266
+
267
+ .. NOTE::
268
+
269
+ This function will not terminate if ``self`` and ``other``
270
+ are equal infinite words!
271
+
272
+ EXAMPLES::
273
+
274
+ sage: W = Word
275
+ sage: from itertools import count
276
+ sage: W(range(1,10)) > W(range(10))
277
+ True
278
+ sage: W(range(10)) < W(range(1,10))
279
+ True
280
+ sage: W(range(10)) == W(range(10))
281
+ True
282
+ sage: W(range(10)) < W(count())
283
+ True
284
+ sage: W(count()) > W(range(10))
285
+ True
286
+
287
+ ::
288
+
289
+ sage: W = Words(['a', 'b', 'c'])
290
+ sage: W('a') > W([])
291
+ True
292
+ sage: W([]) < W('a')
293
+ True
294
+
295
+ sage: Word('abc') == Word(['a','b','c'])
296
+ True
297
+ sage: Words([0,1])([0,1,0,1]) == Words([0,1])([0,1,0,1])
298
+ True
299
+ sage: Words([0,1])([0,1,0,1]) == Words([0,1])([0,1,0,0])
300
+ False
301
+
302
+ It works even when parents are not the same::
303
+
304
+ sage: Words([0,1,2])([0,1,0,1]) == Words([0,1])([0,1,0,1])
305
+ True
306
+ sage: Word('ababa') == Words('abcd')('ababa')
307
+ True
308
+
309
+ Or when one word is finite while the other is infinite::
310
+
311
+ sage: Word(range(20)) == Word(lambda n:n)
312
+ False
313
+ sage: Word(lambda n:n) == Word(range(20))
314
+ False
315
+
316
+ Beware the following does not halt! ::
317
+
318
+ sage: from itertools import count
319
+ sage: Word(lambda n:n) == Word(count()) #not tested
320
+
321
+ Examples for unequality::
322
+
323
+ sage: w = Word(range(10))
324
+ sage: z = Word(range(10))
325
+ sage: w != z
326
+ False
327
+ sage: u = Word(range(12))
328
+ sage: u != w
329
+ True
330
+
331
+ TESTS::
332
+
333
+ sage: Word(count())[:20] == Word(range(20))
334
+ True
335
+ sage: Word(range(20)) == Word(count())[:20]
336
+ True
337
+ sage: Word(range(20)) == Word(lambda n:n)[:20]
338
+ True
339
+ sage: Word(range(20)) == Word(lambda n:n,length=20)
340
+ True
341
+ """
342
+ if not isinstance(other, Word_class):
343
+ return NotImplemented
344
+ self_it, other_it = iter(self), iter(other)
345
+ cmp_key = self._parent.sortkey_letters
346
+ while True:
347
+ try:
348
+ cs = next(self_it)
349
+ except StopIteration:
350
+ try:
351
+ next(other_it)
352
+ except StopIteration:
353
+ # If both self_it and other_it are exhausted then
354
+ # self == other. Return 0.
355
+ return rich_to_bool(op, 0)
356
+ else:
357
+ # If self_it is exhausted, but not other_it, then
358
+ # self is a proper prefix of other: return -1
359
+ return rich_to_bool(op, -1)
360
+ else:
361
+ try:
362
+ co = next(other_it)
363
+ except StopIteration:
364
+ # If self_it is not exhausted but other_it is, then
365
+ # other is a proper prefix of self: return 1.
366
+ return rich_to_bool(op, 1)
367
+ else:
368
+ key_cs = cmp_key(cs)
369
+ key_co = cmp_key(co)
370
+ res = richcmp_item(key_cs, key_co, op)
371
+ if res is not NotImplemented:
372
+ return res
373
+
374
+ def _longest_common_prefix_iterator(self, other):
375
+ r"""
376
+ Return an iterator of the longest common prefix of ``self`` and ``other``.
377
+
378
+ INPUT:
379
+
380
+ - ``other`` -- word
381
+
382
+ OUTPUT: iterator
383
+
384
+ EXAMPLES::
385
+
386
+ sage: f = words.FibonacciWord()
387
+ sage: it = f._longest_common_prefix_iterator(f)
388
+ sage: w = Word(it, length='unknown'); w
389
+ word: 0100101001001010010100100101001001010010...
390
+ sage: w[:6]
391
+ word: 010010
392
+ sage: it = w._longest_common_prefix_iterator(w[:10])
393
+ sage: w = Word(it, length='finite'); w
394
+ word: 0100101001
395
+ """
396
+ for (b, c) in zip(self, other):
397
+ if b == c:
398
+ yield b
399
+ else:
400
+ break
401
+
402
+ def longest_common_prefix(self, other, length='unknown'):
403
+ r"""
404
+ Return the longest common prefix of ``self`` and ``other``.
405
+
406
+ INPUT:
407
+
408
+ - ``other`` -- word
409
+
410
+ - ``length`` -- string (default: ``'unknown'``)
411
+ the length type of the resulting word if known. It may be one of
412
+ the following:
413
+
414
+ - ``'unknown'``
415
+ - ``'finite'``
416
+ - ``'infinite'``
417
+
418
+ EXAMPLES::
419
+
420
+ sage: f = lambda n : add(Integer(n).digits(2)) % 2
421
+ sage: t = Word(f)
422
+ sage: u = t[:10]
423
+ sage: t.longest_common_prefix(u)
424
+ word: 0110100110
425
+
426
+ The longest common prefix of two equal infinite words::
427
+
428
+ sage: t1 = Word(f)
429
+ sage: t2 = Word(f)
430
+ sage: t1.longest_common_prefix(t2)
431
+ word: 0110100110010110100101100110100110010110...
432
+
433
+ Useful to study the approximation of an infinite word::
434
+
435
+ sage: a = 0.618
436
+ sage: g = words.CodingOfRotationWord(alpha=a, beta=1-a, x=a)
437
+ sage: f = words.FibonacciWord()
438
+ sage: p = f.longest_common_prefix(g, length='finite')
439
+ sage: p.length()
440
+ 231
441
+
442
+ TESTS::
443
+
444
+ sage: w = Word('12345')
445
+ sage: y = Word('1236777')
446
+ sage: w.longest_common_prefix(y)
447
+ word: 123
448
+ sage: w.longest_common_prefix(w)
449
+ word: 12345
450
+ sage: y.longest_common_prefix(w)
451
+ word: 123
452
+ sage: y.longest_common_prefix(y)
453
+ word: 1236777
454
+ sage: Word().longest_common_prefix(w)
455
+ word:
456
+ sage: w.longest_common_prefix(Word())
457
+ word:
458
+ sage: w.longest_common_prefix(w[:3])
459
+ word: 123
460
+ sage: Word("11").longest_common_prefix(Word("1"))
461
+ word: 1
462
+ sage: Word("1").longest_common_prefix(Word("11"))
463
+ word: 1
464
+
465
+ With infinite words::
466
+
467
+ sage: t = words.ThueMorseWord('ab')
468
+ sage: u = t[:10]
469
+ sage: u.longest_common_prefix(t)
470
+ word: abbabaabba
471
+ sage: u.longest_common_prefix(u)
472
+ word: abbabaabba
473
+
474
+ Check length::
475
+
476
+ sage: w1 = Word(iter('ab'*200))
477
+ sage: w2 = Word(iter('bcd'*200))
478
+ sage: w1.longest_common_prefix(w2, length=19)
479
+ Traceback (most recent call last):
480
+ ...
481
+ ValueError: invalid argument length (=19)
482
+ """
483
+ it = self._longest_common_prefix_iterator(other)
484
+
485
+ if length == "finite" or \
486
+ (length == "unknown" and (self.is_finite() or other.is_finite())):
487
+ parent = self._parent.factors()
488
+ elif length == "infinite":
489
+ parent = self._parent.shift()
490
+ elif length == "unknown":
491
+ from sage.combinat.words.words import FiniteOrInfiniteWords
492
+ parent = FiniteOrInfiniteWords(self._parent.alphabet())
493
+ else:
494
+ raise ValueError("invalid argument length (={})".format(length))
495
+
496
+ return parent(it)
497
+
498
+ def _longest_periodic_prefix_iterator(self, period=1):
499
+ r"""
500
+ Return an iterator of the longest prefix of ``self`` having the given
501
+ period.
502
+
503
+ INPUT:
504
+
505
+ - ``period`` -- positive integer (default: 1)
506
+
507
+ OUTPUT: iterator
508
+
509
+ EXAMPLES::
510
+
511
+ sage: list(Word([])._longest_periodic_prefix_iterator())
512
+ []
513
+ sage: list(Word([1])._longest_periodic_prefix_iterator())
514
+ [1]
515
+ sage: list(Word([1,2])._longest_periodic_prefix_iterator())
516
+ [1]
517
+ sage: list(Word([1,1,2])._longest_periodic_prefix_iterator())
518
+ [1, 1]
519
+ sage: list(Word([1,1,1,2])._longest_periodic_prefix_iterator())
520
+ [1, 1, 1]
521
+ sage: Word(Word(lambda n:0)._longest_periodic_prefix_iterator())
522
+ word: 0000000000000000000000000000000000000000...
523
+ sage: list(Word([1,2,1,2,1,3])._longest_periodic_prefix_iterator(2))
524
+ [1, 2, 1, 2, 1]
525
+ """
526
+ for i, l in enumerate(self):
527
+ if self[i % period] == l:
528
+ yield l
529
+ else:
530
+ break
531
+
532
+ def longest_periodic_prefix(self, period=1):
533
+ r"""
534
+ Return the longest prefix of ``self`` having the given period.
535
+
536
+ INPUT:
537
+
538
+ - ``period`` -- positive integer (default: 1)
539
+
540
+ OUTPUT: word
541
+
542
+ EXAMPLES::
543
+
544
+ sage: Word([]).longest_periodic_prefix()
545
+ word:
546
+ sage: Word([1]).longest_periodic_prefix()
547
+ word: 1
548
+ sage: Word([1,2]).longest_periodic_prefix()
549
+ word: 1
550
+ sage: Word([1,1,2]).longest_periodic_prefix()
551
+ word: 11
552
+ sage: Word([1,2,1,2,1,3]).longest_periodic_prefix(2)
553
+ word: 12121
554
+ sage: type(_)
555
+ <class 'sage.combinat.words.word.FiniteWord_iter_with_caching'>
556
+ sage: Word(lambda n:0).longest_periodic_prefix()
557
+ word: 0000000000000000000000000000000000000000...
558
+ """
559
+ if self.is_finite():
560
+ parent = self._parent.factors()
561
+ else:
562
+ from sage.combinat.words.words import FiniteOrInfiniteWords
563
+ parent = FiniteOrInfiniteWords(self._parent.alphabet())
564
+ return parent(self._longest_periodic_prefix_iterator(period))
565
+
566
+ def is_empty(self):
567
+ r"""
568
+ Return ``True`` if the length of ``self`` is zero, and ``False`` otherwise.
569
+
570
+ EXAMPLES::
571
+
572
+ sage: it = iter([])
573
+ sage: Word(it).is_empty()
574
+ True
575
+ sage: it = iter([1,2,3])
576
+ sage: Word(it).is_empty()
577
+ False
578
+ sage: from itertools import count
579
+ sage: Word(count()).is_empty()
580
+ False
581
+ """
582
+ try:
583
+ next(iter(self))
584
+ return False
585
+ except StopIteration:
586
+ return True
587
+
588
+ def _to_integer_iterator(self, use_parent_alphabet=False):
589
+ r"""
590
+ Return an iterator over the letters of an integer representation of
591
+ ``self``.
592
+
593
+ INPUT:
594
+
595
+ - ``use_parent_alphabet`` -- boolean (default: ``False``); when ``True``
596
+ and if the ``self`` parent's alphabet is finite, it uses the index of
597
+ the letters in the alphabet. Otherwise, the first letter occurring in
598
+ ``self`` is mapped to zero, and every letter that hasn't yet occurred in
599
+ the word is mapped to the next available integer.
600
+
601
+ EXAMPLES::
602
+
603
+ sage: from itertools import count
604
+ sage: w = Word(count())
605
+ sage: ir = w._to_integer_iterator()
606
+ sage: [next(ir) for _ in range(10)]
607
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
608
+ sage: w = Word(iter("abbacabba"))
609
+ sage: ir = w._to_integer_iterator()
610
+ sage: list(ir)
611
+ [0, 1, 1, 0, 2, 0, 1, 1, 0]
612
+
613
+ ::
614
+
615
+ sage: w = Words('abc')('abbccc')
616
+ sage: list(w._to_integer_iterator(True))
617
+ [0, 1, 1, 2, 2, 2]
618
+ sage: w = Words('acb')('abbccc')
619
+ sage: list(w._to_integer_iterator(True))
620
+ [0, 2, 2, 1, 1, 1]
621
+ sage: w = Words('xabc')('abbccc')
622
+ sage: list(w._to_integer_iterator(True))
623
+ [1, 2, 2, 3, 3, 3]
624
+ """
625
+ from sage.combinat.words.words import FiniteWords, InfiniteWords
626
+ if use_parent_alphabet and\
627
+ isinstance(self.parent(), (FiniteWords, InfiniteWords)):
628
+ A = self.parent().alphabet()
629
+ for letter in self:
630
+ yield A.rank(letter)
631
+
632
+ else:
633
+ mapping = {}
634
+ next_value = 0
635
+ for letter in self:
636
+ if letter not in mapping:
637
+ mapping[letter] = next_value
638
+ next_value += 1
639
+ yield mapping[letter]
640
+
641
+ def to_integer_word(self):
642
+ r"""
643
+ Return a word over the integers whose letters are those output by
644
+ self._to_integer_iterator()
645
+
646
+ EXAMPLES::
647
+
648
+ sage: from itertools import count
649
+ sage: w = Word(count()); w
650
+ word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...
651
+ sage: w.to_integer_word()
652
+ word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...
653
+ sage: w = Word(iter("abbacabba"), length='finite'); w
654
+ word: abbacabba
655
+ sage: w.to_integer_word()
656
+ word: 011020110
657
+ sage: w = Word(iter("abbacabba"), length='unknown'); w
658
+ word: abbacabba
659
+ sage: w.to_integer_word()
660
+ word: 011020110
661
+ """
662
+ length = "unknown" if self._len is None else self._len
663
+ from sage.combinat.words.word import Word
664
+ return Word(self._to_integer_iterator(), length=length)
665
+
666
+ def lex_less(self, other):
667
+ r"""
668
+ Return ``True`` if ``self`` is lexicographically less than ``other``.
669
+
670
+ EXAMPLES::
671
+
672
+ sage: w = Word([1,2,3])
673
+ sage: u = Word([1,3,2])
674
+ sage: v = Word([3,2,1])
675
+ sage: w.lex_less(u)
676
+ True
677
+ sage: v.lex_less(w)
678
+ False
679
+ sage: a = Word("abba")
680
+ sage: b = Word("abbb")
681
+ sage: a.lex_less(b)
682
+ True
683
+ sage: b.lex_less(a)
684
+ False
685
+
686
+ For infinite words::
687
+
688
+ sage: t = words.ThueMorseWord()
689
+ sage: t.lex_less(t[:10])
690
+ False
691
+ sage: t[:10].lex_less(t)
692
+ True
693
+ """
694
+ return self < other
695
+
696
+ def lex_greater(self, other):
697
+ r"""
698
+ Return ``True`` if ``self`` is lexicographically greater than ``other``.
699
+
700
+ EXAMPLES::
701
+
702
+ sage: w = Word([1,2,3])
703
+ sage: u = Word([1,3,2])
704
+ sage: v = Word([3,2,1])
705
+ sage: w.lex_greater(u)
706
+ False
707
+ sage: v.lex_greater(w)
708
+ True
709
+ sage: a = Word("abba")
710
+ sage: b = Word("abbb")
711
+ sage: a.lex_greater(b)
712
+ False
713
+ sage: b.lex_greater(a)
714
+ True
715
+
716
+ For infinite words::
717
+
718
+ sage: t = words.ThueMorseWord()
719
+ sage: t[:10].lex_greater(t)
720
+ False
721
+ sage: t.lex_greater(t[:10])
722
+ True
723
+ """
724
+ return self > other
725
+
726
+ def apply_morphism(self, morphism):
727
+ r"""
728
+ Return the word obtained by applying the morphism to ``self``.
729
+
730
+ INPUT:
731
+
732
+ - ``morphism`` -- can be an instance of WordMorphism, or
733
+ anything that can be used to construct one
734
+
735
+ EXAMPLES::
736
+
737
+ sage: w = Word("ab")
738
+ sage: d = {'a':'ab', 'b':'ba'}
739
+ sage: w.apply_morphism(d)
740
+ word: abba
741
+ sage: w.apply_morphism(WordMorphism(d))
742
+ word: abba
743
+
744
+ ::
745
+
746
+ sage: w = Word('ababa')
747
+ sage: d = dict(a='ab', b='ba')
748
+ sage: d
749
+ {'a': 'ab', 'b': 'ba'}
750
+ sage: w.apply_morphism(d)
751
+ word: abbaabbaab
752
+
753
+ For infinite words::
754
+
755
+ sage: t = words.ThueMorseWord([0,1]); t
756
+ word: 0110100110010110100101100110100110010110...
757
+ sage: t.apply_morphism({0:8,1:9})
758
+ word: 8998988998898998988989988998988998898998...
759
+ """
760
+ from sage.combinat.words.morphism import WordMorphism
761
+ if not isinstance(morphism, WordMorphism):
762
+ morphism = WordMorphism(morphism)
763
+ return morphism(self)
764
+
765
+ def _delta_iterator(self):
766
+ r"""
767
+ Return an iterator of the image of ``self`` under the delta morphism.
768
+ This is the word composed of the length of consecutive runs of the
769
+ same letter in a given word.
770
+
771
+ OUTPUT: generator object
772
+
773
+ EXAMPLES::
774
+
775
+ sage: W = Words('0123456789')
776
+ sage: it=W('22112122')._delta_iterator()
777
+ sage: Word(it)
778
+ word: 22112
779
+ sage: Word(W('555008')._delta_iterator())
780
+ word: 321
781
+ sage: Word(W()._delta_iterator())
782
+ word:
783
+
784
+ For infinite words::
785
+
786
+ sage: t = words.ThueMorseWord()
787
+ sage: it = t._delta_iterator()
788
+ sage: Word(it)
789
+ word: 1211222112112112221122211222112112112221...
790
+ """
791
+ for letter, run in groupby(self):
792
+ yield len(list(run))
793
+
794
+ def delta(self):
795
+ r"""
796
+ Return the image of ``self`` under the delta morphism.
797
+
798
+ This is the word composed of the length of consecutive runs of
799
+ the same letter in a given word.
800
+
801
+ OUTPUT: word over integers
802
+
803
+ EXAMPLES:
804
+
805
+ For finite words::
806
+
807
+ sage: W = Words('0123456789')
808
+ sage: W('22112122').delta()
809
+ word: 22112
810
+ sage: W('555008').delta()
811
+ word: 321
812
+ sage: W().delta()
813
+ word:
814
+ sage: Word('aabbabaa').delta()
815
+ word: 22112
816
+
817
+ For infinite words::
818
+
819
+ sage: t = words.ThueMorseWord()
820
+ sage: t.delta()
821
+ word: 1211222112112112221122211222112112112221...
822
+ """
823
+ from sage.combinat.words.word import Word
824
+ from sage.rings.semirings.non_negative_integer_semiring import NN
825
+ return Word(self._delta_iterator(), alphabet=NN)
826
+
827
+ def _iterated_right_palindromic_closure_iterator(self, f=None):
828
+ r"""
829
+ Return an iterator over the iterated (`f`-)palindromic closure of ``self``.
830
+
831
+ INPUT:
832
+
833
+ - ``f`` -- involution on the alphabet of ``self`` (default: ``None``);
834
+ it must be callable on letters as well as words (e.g. WordMorphism)
835
+
836
+ OUTPUT: iterator; the iterated (`f`-)palindromic closure of ``self``
837
+
838
+ EXAMPLES::
839
+
840
+ sage: w = Word('abc')
841
+ sage: it = w._iterated_right_palindromic_closure_iterator()
842
+ sage: Word(it)
843
+ word: abacaba
844
+
845
+ ::
846
+
847
+ sage: w = Word('aaa')
848
+ sage: it = w._iterated_right_palindromic_closure_iterator()
849
+ sage: Word(it)
850
+ word: aaa
851
+
852
+ ::
853
+
854
+ sage: w = Word('abbab')
855
+ sage: it = w._iterated_right_palindromic_closure_iterator()
856
+ sage: Word(it)
857
+ word: ababaabababaababa
858
+
859
+ An infinite word::
860
+
861
+ sage: t = words.ThueMorseWord('ab')
862
+ sage: it = t._iterated_right_palindromic_closure_iterator()
863
+ sage: Word(it)
864
+ word: ababaabababaababaabababaababaabababaabab...
865
+
866
+ TESTS:
867
+
868
+ The empty word::
869
+
870
+ sage: w = Word()
871
+ sage: it = w._iterated_right_palindromic_closure_iterator()
872
+ sage: next(it)
873
+ Traceback (most recent call last):
874
+ ...
875
+ StopIteration
876
+
877
+ REFERENCES:
878
+
879
+ - [1] A. de Luca, A. De Luca, Pseudopalindrome closure operators
880
+ in free monoids, Theoret. Comput. Sci. 362 (2006) 282--300.
881
+ """
882
+ par = self.parent().factors()
883
+ w = self[:0]
884
+ for letter in self:
885
+ length_before = w.length()
886
+ w = (w*par([letter])).palindromic_closure(f=f)
887
+ length_after = w.length()
888
+ d = length_after - length_before
889
+ yield from w[-d:]
890
+
891
+ def _iterated_right_palindromic_closure_recursive_iterator(self, f=None):
892
+ r"""
893
+ Return an iterator over the iterated (`f`-)palindromic closure of ``self``.
894
+
895
+ INPUT:
896
+
897
+ - ``f`` -- involution (default: ``None``) on the alphabet of ``self``;
898
+ it must be callable on letters as well as words (e.g. WordMorphism)
899
+
900
+ OUTPUT: iterator; the iterated (`f`-)palindromic closure of ``self``
901
+
902
+ ALGORITHM:
903
+
904
+ For the case of palindromes only, it has been shown in [2] that
905
+ the iterated right palindromic closure of a given word `w`,
906
+ denoted by `IRPC(w)`, may be obtained as follows.
907
+ Let `w` be any word and `x` be a letter. Then
908
+
909
+ #. If `x` does not occur in `w`,
910
+ `IRPC(wx) = IRPC(w) \cdot x \cdot IRPC(w)`
911
+ #. Otherwise, write `w = w_1xw_2` such that `x` does not
912
+ occur in `w_2`. Then `IRPC(wx) = IRPC(w) \cdot IRPC(w_1)^{-1}
913
+ \cdot IRPC(w)`
914
+
915
+ This formula is directly generalized to the case of `f`-palindromes.
916
+ See [1] for more details.
917
+
918
+ EXAMPLES::
919
+
920
+ sage: w = Word('abc')
921
+ sage: it = w._iterated_right_palindromic_closure_recursive_iterator()
922
+ sage: Word(it)
923
+ word: abacaba
924
+
925
+ ::
926
+
927
+ sage: w = Word('aaa')
928
+ sage: it = w._iterated_right_palindromic_closure_recursive_iterator()
929
+ sage: Word(it)
930
+ word: aaa
931
+
932
+ ::
933
+
934
+ sage: w = Word('abbab')
935
+ sage: it = w._iterated_right_palindromic_closure_recursive_iterator()
936
+ sage: Word(it)
937
+ word: ababaabababaababa
938
+
939
+ An infinite word::
940
+
941
+ sage: t = words.ThueMorseWord('ab')
942
+ sage: it = t._iterated_right_palindromic_closure_recursive_iterator()
943
+ sage: Word(it)
944
+ word: ababaabababaababaabababaababaabababaabab...
945
+
946
+ TESTS:
947
+
948
+ The empty word::
949
+
950
+ sage: w = Word()
951
+ sage: it = w._iterated_right_palindromic_closure_recursive_iterator()
952
+ sage: next(it)
953
+ Traceback (most recent call last):
954
+ ...
955
+ StopIteration
956
+
957
+ REFERENCES:
958
+
959
+ - [1] A. de Luca, A. De Luca, Pseudopalindrome closure operators
960
+ in free monoids, Theoret. Comput. Sci. 362 (2006) 282--300.
961
+ - [2] J. Justin, Episturmian morphisms and a Galois theorem on
962
+ continued fractions, RAIRO Theoret. Informatics Appl. 39 (2005)
963
+ 207-215.
964
+ """
965
+ parent = self.parent().factors()
966
+ ipcw = self[:0]
967
+ lengths = []
968
+ for i, letter in enumerate(self):
969
+ lengths.append(ipcw.length())
970
+ w = self[:i]
971
+ pos = w.rfind(parent([letter]))
972
+ if pos == -1:
973
+ to_append = parent([letter]).palindromic_closure(f=f) + ipcw
974
+ else:
975
+ to_append = ipcw[lengths[pos]:]
976
+ ipcw += to_append
977
+ yield from to_append
978
+
979
+ def iterated_right_palindromic_closure(self, f=None, algorithm='recursive'):
980
+ r"""
981
+ Return the iterated (`f`-)palindromic closure of ``self``.
982
+
983
+ INPUT:
984
+
985
+ - ``f`` -- involution (default: ``None``) on the alphabet of ``self``;
986
+ it must be callable on letters as well as words (e.g. WordMorphism)
987
+
988
+ - ``algorithm`` -- string (default: ``'recursive'``); specifying which
989
+ algorithm to be used when computing the iterated palindromic closure.
990
+ It must be one of the two following values:
991
+
992
+ - ``'definition'`` -- computed using the definition
993
+ - ``'recursive'`` -- computation based on an efficient formula
994
+ that recursively computes the iterated right palindromic closure
995
+ without having to recompute the longest `f`-palindromic suffix
996
+ at each iteration [2].
997
+
998
+ OUTPUT: word; the iterated (`f`-)palindromic closure of ``self``
999
+
1000
+ EXAMPLES::
1001
+
1002
+ sage: Word('123').iterated_right_palindromic_closure()
1003
+ word: 1213121
1004
+
1005
+ ::
1006
+
1007
+ sage: w = Word('abc')
1008
+ sage: w.iterated_right_palindromic_closure()
1009
+ word: abacaba
1010
+
1011
+ ::
1012
+
1013
+ sage: w = Word('aaa')
1014
+ sage: w.iterated_right_palindromic_closure()
1015
+ word: aaa
1016
+
1017
+ ::
1018
+
1019
+ sage: w = Word('abbab')
1020
+ sage: w.iterated_right_palindromic_closure()
1021
+ word: ababaabababaababa
1022
+
1023
+ A right `f`-palindromic closure::
1024
+
1025
+ sage: f = WordMorphism('a->b,b->a')
1026
+ sage: w = Word('abbab')
1027
+ sage: w.iterated_right_palindromic_closure(f=f)
1028
+ word: abbaabbaababbaabbaabbaababbaabbaab
1029
+
1030
+ An infinite word::
1031
+
1032
+ sage: t = words.ThueMorseWord('ab')
1033
+ sage: t.iterated_right_palindromic_closure()
1034
+ word: ababaabababaababaabababaababaabababaabab...
1035
+
1036
+ There are two implementations computing the iterated right
1037
+ `f`-palindromic closure, the latter being much more efficient::
1038
+
1039
+ sage: w = Word('abaab')
1040
+ sage: u = w.iterated_right_palindromic_closure(algorithm='definition')
1041
+ sage: v = w.iterated_right_palindromic_closure(algorithm='recursive')
1042
+ sage: u
1043
+ word: abaabaababaabaaba
1044
+ sage: u == v
1045
+ True
1046
+ sage: w = words.RandomWord(8)
1047
+ sage: u = w.iterated_right_palindromic_closure(algorithm='definition')
1048
+ sage: v = w.iterated_right_palindromic_closure(algorithm='recursive')
1049
+ sage: u == v
1050
+ True
1051
+
1052
+ TESTS:
1053
+
1054
+ The empty word::
1055
+
1056
+ sage: w = Word()
1057
+ sage: w.iterated_right_palindromic_closure()
1058
+ word:
1059
+
1060
+ The length-`1` word::
1061
+
1062
+ sage: Word('1').iterated_right_palindromic_closure()
1063
+ word: 1
1064
+
1065
+ If the word is finite, so is the result::
1066
+
1067
+ sage: w = Word([0,1]*7)
1068
+ sage: c = w.iterated_right_palindromic_closure()
1069
+ sage: type(c)
1070
+ <class 'sage.combinat.words.word.FiniteWord_iter_with_caching'>
1071
+
1072
+ REFERENCES:
1073
+
1074
+ - [1] A. de Luca, A. De Luca, Pseudopalindrome closure operators
1075
+ in free monoids, Theoret. Comput. Sci. 362 (2006) 282--300.
1076
+ - [2] J. Justin, Episturmian morphisms and a Galois theorem on
1077
+ continued fractions, RAIRO Theoret. Informatics Appl. 39 (2005)
1078
+ 207-215.
1079
+ """
1080
+ if algorithm == 'definition':
1081
+ it = self._iterated_right_palindromic_closure_iterator(f=f)
1082
+ elif algorithm == 'recursive':
1083
+ it = self._iterated_right_palindromic_closure_recursive_iterator(f=f)
1084
+ else:
1085
+ raise ValueError("algorithm (=%s) must be either 'definition' or 'recursive'")
1086
+
1087
+ if self.is_finite():
1088
+ return self._parent(it)
1089
+ else:
1090
+ from sage.combinat.words.words import Words
1091
+ parent = Words(self._parent.alphabet())
1092
+ return parent(it)
1093
+
1094
+ def prefixes_iterator(self, max_length=None):
1095
+ r"""
1096
+ Return an iterator over the prefixes of ``self``.
1097
+
1098
+ INPUT:
1099
+
1100
+ - ``max_length`` -- nonnegative integer or ``None`` (default); the
1101
+ maximum length of the prefixes
1102
+
1103
+ OUTPUT: iterator
1104
+
1105
+ EXAMPLES::
1106
+
1107
+ sage: w = Word('abaaba')
1108
+ sage: for p in w.prefixes_iterator(): p
1109
+ word:
1110
+ word: a
1111
+ word: ab
1112
+ word: aba
1113
+ word: abaa
1114
+ word: abaab
1115
+ word: abaaba
1116
+ sage: for p in w.prefixes_iterator(max_length=3): p
1117
+ word:
1118
+ word: a
1119
+ word: ab
1120
+ word: aba
1121
+
1122
+ You can iterate over the prefixes of an infinite word::
1123
+
1124
+ sage: f = words.FibonacciWord()
1125
+ sage: for p in f.prefixes_iterator(max_length=8): p
1126
+ word:
1127
+ word: 0
1128
+ word: 01
1129
+ word: 010
1130
+ word: 0100
1131
+ word: 01001
1132
+ word: 010010
1133
+ word: 0100101
1134
+ word: 01001010
1135
+
1136
+ TESTS::
1137
+
1138
+ sage: list(f.prefixes_iterator(max_length=0))
1139
+ [word: ]
1140
+ """
1141
+ to_consider = self if max_length is None else self[:max_length]
1142
+ yield self[:0]
1143
+ for (i, a) in enumerate(to_consider):
1144
+ yield self[:i + 1]
1145
+
1146
+ def palindrome_prefixes_iterator(self, max_length=None):
1147
+ r"""
1148
+ Return an iterator over the palindrome prefixes of ``self``.
1149
+
1150
+ INPUT:
1151
+
1152
+ - ``max_length`` -- nonnegative integer or ``None`` (default); the
1153
+ maximum length of the prefixes
1154
+
1155
+ OUTPUT: iterator
1156
+
1157
+ EXAMPLES::
1158
+
1159
+ sage: w = Word('abaaba')
1160
+ sage: for pp in w.palindrome_prefixes_iterator(): pp
1161
+ word:
1162
+ word: a
1163
+ word: aba
1164
+ word: abaaba
1165
+ sage: for pp in w.palindrome_prefixes_iterator(max_length=4): pp
1166
+ word:
1167
+ word: a
1168
+ word: aba
1169
+
1170
+ You can iterate over the palindrome prefixes of an infinite word::
1171
+
1172
+ sage: f = words.FibonacciWord()
1173
+ sage: for pp in f.palindrome_prefixes_iterator(max_length=20): pp
1174
+ word:
1175
+ word: 0
1176
+ word: 010
1177
+ word: 010010
1178
+ word: 01001010010
1179
+ word: 0100101001001010010
1180
+ """
1181
+ for p in self.prefixes_iterator(max_length):
1182
+ if p.is_palindrome():
1183
+ yield p
1184
+
1185
+ def _partial_sums_iterator(self, start, mod=None):
1186
+ r"""
1187
+ Iterator over the partial sums of the prefixes of ``self``.
1188
+
1189
+ INPUT:
1190
+
1191
+ - ``self`` -- a word over the integers
1192
+ - ``start`` -- integer; the first letter of the resulting word
1193
+ - ``mod`` -- (default: ``None``) it can be one of the following:
1194
+ - None or 0 : result is over the integers
1195
+ - integer : result is over the integers modulo ``mod``.
1196
+
1197
+ EXAMPLES::
1198
+
1199
+ sage: w = Word(range(8))
1200
+ sage: list(w._partial_sums_iterator(0, mod=10))
1201
+ [0, 0, 1, 3, 6, 0, 5, 1, 8]
1202
+
1203
+ ::
1204
+
1205
+ sage: w = Word([1,1,1,1,1,1,1,1,1,1,1,1])
1206
+ sage: list(w._partial_sums_iterator(0, mod=10))
1207
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2]
1208
+
1209
+ ::
1210
+
1211
+ sage: w = Word([1,1,1,1,1,1,1,1,1,1,1,1])
1212
+ sage: list(w._partial_sums_iterator(0))
1213
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
1214
+ """
1215
+ if mod in (None, 0):
1216
+ sum = start
1217
+
1218
+ elif mod in ZZ:
1219
+ Zn = Integers(mod)
1220
+ sum = Zn(start)
1221
+
1222
+ else:
1223
+ raise TypeError('mod(=%s) must be None or an integer' % mod)
1224
+
1225
+ yield sum
1226
+ for letter in self:
1227
+ sum += letter
1228
+ yield sum
1229
+
1230
+ def partial_sums(self, start, mod=None):
1231
+ r"""
1232
+ Return the word defined by the partial sums of its prefixes.
1233
+
1234
+ INPUT:
1235
+
1236
+ - ``self`` -- a word over the integers
1237
+ - ``start`` -- integer; the first letter of the resulting word
1238
+ - ``mod`` -- (default: ``None``) it can be one of the following:
1239
+ - None or 0 : result is over the integers
1240
+ - integer : result is over the integers modulo ``mod``.
1241
+
1242
+ EXAMPLES::
1243
+
1244
+ sage: w = Word(range(10))
1245
+ sage: w.partial_sums(0)
1246
+ word: 0,0,1,3,6,10,15,21,28,36,45
1247
+ sage: w.partial_sums(1)
1248
+ word: 1,1,2,4,7,11,16,22,29,37,46
1249
+
1250
+ ::
1251
+
1252
+ sage: w = Word([1,2,3,1,2,3,2,2,2,2])
1253
+ sage: w.partial_sums(0, mod=None)
1254
+ word: 0,1,3,6,7,9,12,14,16,18,20
1255
+ sage: w.partial_sums(0, mod=0)
1256
+ word: 0,1,3,6,7,9,12,14,16,18,20
1257
+ sage: w.partial_sums(0, mod=8)
1258
+ word: 01367146024
1259
+ sage: w.partial_sums(0, mod=4)
1260
+ word: 01323102020
1261
+ sage: w.partial_sums(0, mod=2)
1262
+ word: 01101100000
1263
+ sage: w.partial_sums(0, mod=1)
1264
+ word: 00000000000
1265
+
1266
+ TESTS:
1267
+
1268
+ If the word is infinite, so is the result::
1269
+
1270
+ sage: w = Word(lambda n:1)
1271
+ sage: u = w.partial_sums(0)
1272
+ sage: type(u)
1273
+ <class 'sage.combinat.words.word.InfiniteWord_iter_with_caching'>
1274
+ """
1275
+ it = self._partial_sums_iterator(start=start, mod=mod)
1276
+
1277
+ if mod in (None, 0):
1278
+ alphabet = None
1279
+ elif mod in ZZ:
1280
+ alphabet = Integers(mod)
1281
+
1282
+ if self.is_finite():
1283
+ length = "finite"
1284
+ elif self.length() == Infinity:
1285
+ length = "infinite"
1286
+ else:
1287
+ length = "unknown"
1288
+ from sage.combinat.words.word import Word
1289
+ return Word(it, alphabet=alphabet, length=length)
1290
+
1291
+ def _finite_differences_iterator(self, mod=None):
1292
+ r"""
1293
+ Iterator over the differences of consecutive letters of ``self``.
1294
+
1295
+ INPUT:
1296
+
1297
+ - ``self`` -- a word over the integers
1298
+ - ``mod`` -- (default: ``None``) it can be one of the following:
1299
+ - None or 0 : result is over the integers
1300
+ - integer : result is over the integers modulo ``mod``.
1301
+
1302
+ EXAMPLES::
1303
+
1304
+ sage: w = Word(x^2 for x in range(10))
1305
+ sage: list(w._finite_differences_iterator())
1306
+ [1, 3, 5, 7, 9, 11, 13, 15, 17]
1307
+
1308
+ ::
1309
+
1310
+ sage: w = Word([1,6,8,4,2,6,8,2,3])
1311
+ sage: list(w._finite_differences_iterator())
1312
+ [5, 2, -4, -2, 4, 2, -6, 1]
1313
+ sage: list(w._finite_differences_iterator(4))
1314
+ [1, 2, 0, 2, 0, 2, 2, 1]
1315
+ sage: list(w._finite_differences_iterator(5))
1316
+ [0, 2, 1, 3, 4, 2, 4, 1]
1317
+
1318
+ TESTS::
1319
+
1320
+ sage: w = Word([2,3,6])
1321
+ sage: list(w._finite_differences_iterator())
1322
+ [1, 3]
1323
+ sage: w = Word([2,6])
1324
+ sage: list(w._finite_differences_iterator())
1325
+ [4]
1326
+ sage: w = Word([2])
1327
+ sage: list(w._finite_differences_iterator())
1328
+ []
1329
+ sage: w = Word()
1330
+ sage: list(w._finite_differences_iterator())
1331
+ []
1332
+
1333
+ ::
1334
+
1335
+ sage: list(w._finite_differences_iterator('a'))
1336
+ Traceback (most recent call last):
1337
+ ...
1338
+ TypeError: mod(=a) must be None or an integer
1339
+ """
1340
+ if mod in (None, 0):
1341
+ i = iter(self)
1342
+ j = iter(self)
1343
+
1344
+ try:
1345
+ next(j)
1346
+ while True:
1347
+ yield next(j) - next(i)
1348
+ except StopIteration:
1349
+ return
1350
+
1351
+ elif mod in ZZ:
1352
+ Zn = Integers(mod)
1353
+ i = iter(self)
1354
+ j = iter(self)
1355
+
1356
+ try:
1357
+ next(j)
1358
+ while True:
1359
+ yield Zn(next(j) - next(i))
1360
+ except StopIteration:
1361
+ return
1362
+
1363
+ else:
1364
+ raise TypeError('mod(=%s) must be None or an integer' % mod)
1365
+
1366
+ def finite_differences(self, mod=None):
1367
+ r"""
1368
+ Return the word obtained by the differences of consecutive letters
1369
+ of ``self``.
1370
+
1371
+ INPUT:
1372
+
1373
+ - ``self`` -- a word over the integers
1374
+ - ``mod`` -- (default: ``None``) it can be one of the following:
1375
+ - None or 0 : result is over the integers
1376
+ - integer : result is over the integers modulo ``mod``.
1377
+
1378
+ EXAMPLES::
1379
+
1380
+ sage: w = Word([x^2 for x in range(10)])
1381
+ sage: w.finite_differences()
1382
+ word: 1,3,5,7,9,11,13,15,17
1383
+ sage: w.finite_differences(mod=4)
1384
+ word: 131313131
1385
+ sage: w.finite_differences(mod=0)
1386
+ word: 1,3,5,7,9,11,13,15,17
1387
+
1388
+ TESTS::
1389
+
1390
+ sage: w = Word([2,3,6])
1391
+ sage: w.finite_differences()
1392
+ word: 13
1393
+ sage: w = Word([2,6])
1394
+ sage: w.finite_differences()
1395
+ word: 4
1396
+ sage: w = Word([2])
1397
+ sage: w.finite_differences()
1398
+ word:
1399
+ sage: w = Word()
1400
+ sage: w.finite_differences()
1401
+ word:
1402
+
1403
+ If the word is infinite, so is the result::
1404
+
1405
+ sage: w = Word(lambda n:n)
1406
+ sage: u = w.finite_differences()
1407
+ sage: u
1408
+ word: 1111111111111111111111111111111111111111...
1409
+ sage: type(u)
1410
+ <class 'sage.combinat.words.word.InfiniteWord_iter_with_caching'>
1411
+ """
1412
+ it = self._finite_differences_iterator(mod=mod)
1413
+
1414
+ if mod in (None, 0):
1415
+ alphabet = None
1416
+ elif mod in ZZ:
1417
+ alphabet = Integers(mod)
1418
+
1419
+ if self.is_finite():
1420
+ length = "finite"
1421
+ elif self.length() == Infinity:
1422
+ length = "infinite"
1423
+ else:
1424
+ length = "unknown"
1425
+ from sage.combinat.words.word import Word
1426
+ return Word(it, alphabet=alphabet, length=length)
1427
+
1428
+ def sum_digits(self, base=2, mod=None):
1429
+ r"""
1430
+ Return the sequence of the sum modulo ``mod`` of the digits written
1431
+ in base ``base`` of ``self``.
1432
+
1433
+ INPUT:
1434
+
1435
+ - ``self`` -- word over natural numbers
1436
+
1437
+ - ``base`` -- integer (default: 2) greater or equal to 2
1438
+
1439
+ - ``mod`` -- modulo (default: ``None``); can take the following
1440
+ values:
1441
+ - ``integer`` -- the modulo
1442
+ - ``None`` -- the value ``base`` is considered for the modulo
1443
+
1444
+ EXAMPLES:
1445
+
1446
+ The Thue-Morse word::
1447
+
1448
+ sage: from itertools import count
1449
+ sage: Word(count()).sum_digits()
1450
+ word: 0110100110010110100101100110100110010110...
1451
+
1452
+ Sum of digits modulo 2 of the prime numbers written in base 2::
1453
+
1454
+ sage: Word(primes(1000)).sum_digits() # needs sage.libs.pari
1455
+ word: 1001110100111010111011001011101110011011...
1456
+
1457
+ Sum of digits modulo 3 of the prime numbers written in base 3::
1458
+
1459
+ sage: Word(primes(1000)).sum_digits(base=3) # needs sage.libs.pari
1460
+ word: 2100002020002221222121022221022122111022...
1461
+ sage: Word(primes(1000)).sum_digits(base=3, mod=3) # needs sage.libs.pari
1462
+ word: 2100002020002221222121022221022122111022...
1463
+
1464
+ Sum of digits modulo 2 of the prime numbers written in base 3::
1465
+
1466
+ sage: Word(primes(1000)).sum_digits(base=3, mod=2) # needs sage.libs.pari
1467
+ word: 0111111111111111111111111111111111111111...
1468
+
1469
+ Sum of digits modulo 7 of the prime numbers written in base 10::
1470
+
1471
+ sage: Word(primes(1000)).sum_digits(base=10, mod=7) # needs sage.libs.pari
1472
+ word: 2350241354435041006132432241353546006304...
1473
+
1474
+ Negative entries::
1475
+
1476
+ sage: w = Word([-1,0,1,2,3,4,5])
1477
+ sage: w.sum_digits()
1478
+ Traceback (most recent call last):
1479
+ ...
1480
+ NotImplementedError: nth digit of Thue-Morse word is not implemented for negative value of n
1481
+
1482
+ TESTS:
1483
+
1484
+ The Thue-Morse word::
1485
+
1486
+ sage: from itertools import count
1487
+ sage: w = Word(count()).sum_digits()
1488
+ sage: t = words.ThueMorseWord()
1489
+ sage: w[:100] == t[:100]
1490
+ True
1491
+
1492
+ ::
1493
+
1494
+ sage: type(Word(range(10)).sum_digits())
1495
+ <class 'sage.combinat.words.word.FiniteWord_iter_with_caching'>
1496
+ """
1497
+ from functools import partial
1498
+ from sage.combinat.words.word_generators import words
1499
+
1500
+ # The alphabet
1501
+ if mod is None and base >= 2:
1502
+ alphabet = list(range(base))
1503
+ elif mod in ZZ and mod >= 2:
1504
+ alphabet = list(range(mod))
1505
+ else:
1506
+ raise ValueError("base (=%s) and mod (=%s) must be integers greater or equal to 2" % (base, mod))
1507
+
1508
+ # The iterator
1509
+ f = partial(words._ThueMorseWord_nth_digit, alphabet=alphabet, base=base)
1510
+ it = (f(a) for a in self)
1511
+
1512
+ # The length
1513
+ if self.is_finite():
1514
+ length = "finite"
1515
+ elif self.length() == Infinity:
1516
+ length = None
1517
+ else:
1518
+ length = "unknown"
1519
+
1520
+ from sage.combinat.words.word import Word
1521
+ return Word(it, alphabet=alphabet, length=length, datatype='iter')
1522
+
1523
+ def first_occurrence(self, other, start=0):
1524
+ r"""
1525
+ Return the position of the first occurrence of ``other`` in ``self``.
1526
+
1527
+ If ``other`` is not a factor of ``self``, it returns ``None``
1528
+ or loops forever when ``self`` is an infinite word.
1529
+
1530
+ INPUT:
1531
+
1532
+ - ``other`` -- a finite word
1533
+ - ``start`` -- integer (default: `0`) where the search starts
1534
+
1535
+ OUTPUT: integer or ``None``
1536
+
1537
+ EXAMPLES::
1538
+
1539
+ sage: w = Word('01234567890123456789')
1540
+ sage: w.first_occurrence(Word('3456'))
1541
+ 3
1542
+ sage: w.first_occurrence(Word('3456'), start=7)
1543
+ 13
1544
+
1545
+ When the factor is not present, ``None`` is returned::
1546
+
1547
+ sage: w.first_occurrence(Word('3456'), start=17) is None
1548
+ True
1549
+ sage: w.first_occurrence(Word('3333')) is None
1550
+ True
1551
+
1552
+ Also works for searching a finite word in an infinite word::
1553
+
1554
+ sage: w = Word('0123456789')^oo
1555
+ sage: w.first_occurrence(Word('3456'))
1556
+ 3
1557
+ sage: w.first_occurrence(Word('3456'), start=1000)
1558
+ 1003
1559
+
1560
+ But it will loop for ever if the factor is not found::
1561
+
1562
+ sage: w.first_occurrence(Word('3333')) # not tested -- infinite loop
1563
+
1564
+ The empty word occurs in a word::
1565
+
1566
+ sage: Word('123').first_occurrence(Word(''), 0)
1567
+ 0
1568
+ sage: Word('').first_occurrence(Word(''), 0)
1569
+ 0
1570
+ """
1571
+ lf = other.length()
1572
+ lm = self.length()
1573
+ if lf == 0:
1574
+ return start
1575
+ elif lm == 0:
1576
+ return None
1577
+ occ = other.last_position_dict()
1578
+ suff = other.good_suffix_table()
1579
+ s = start
1580
+ while s <= lm - lf:
1581
+ for j in range(lf-1, -1, -1):
1582
+ a = self[s+j]
1583
+ if other[j] != a:
1584
+ s += max(suff[j + 1], j - occ.get(a, -1))
1585
+ break
1586
+ else:
1587
+ return s
1588
+ return None
1589
+
1590
+ def factor_occurrences_iterator(self, fact):
1591
+ r"""
1592
+ Return an iterator over all occurrences (including overlapping ones)
1593
+ of fact in ``self`` in their order of appearance.
1594
+
1595
+ INPUT:
1596
+
1597
+ - ``fact`` -- a non empty finite word
1598
+
1599
+ OUTPUT: iterator
1600
+
1601
+ EXAMPLES::
1602
+
1603
+ sage: TM = words.ThueMorseWord()
1604
+ sage: fact = Word([0,1,1,0,1])
1605
+ sage: it = TM.factor_occurrences_iterator(fact)
1606
+ sage: next(it)
1607
+ 0
1608
+ sage: next(it)
1609
+ 12
1610
+ sage: next(it)
1611
+ 24
1612
+
1613
+ ::
1614
+
1615
+ sage: u = Word('121')
1616
+ sage: w = Word('121213211213')
1617
+ sage: list(w.factor_occurrences_iterator(u))
1618
+ [0, 2, 8]
1619
+ """
1620
+ if fact.is_empty():
1621
+ raise NotImplementedError("The factor must be non empty")
1622
+ if not fact.is_finite():
1623
+ raise ValueError("The factor must be finite")
1624
+ p = self.first_occurrence(fact, start=0)
1625
+ while p is not None:
1626
+ yield p
1627
+ p = self.first_occurrence(fact, start=p+1)
1628
+
1629
+ def return_words_iterator(self, fact):
1630
+ r"""
1631
+ Return an iterator over all the return words of fact in self
1632
+ (without unicity).
1633
+
1634
+ INPUT:
1635
+
1636
+ - ``fact`` -- a non empty finite word
1637
+
1638
+ OUTPUT: iterator
1639
+
1640
+ EXAMPLES::
1641
+
1642
+ sage: w = Word('baccabccbacbca')
1643
+ sage: b = Word('b')
1644
+ sage: list(w.return_words_iterator(b))
1645
+ [word: bacca, word: bcc, word: bac]
1646
+
1647
+ ::
1648
+
1649
+ sage: TM = words.ThueMorseWord()
1650
+ sage: fact = Word([0,1,1,0,1])
1651
+ sage: it = TM.return_words_iterator(fact)
1652
+ sage: next(it)
1653
+ word: 011010011001
1654
+ sage: next(it)
1655
+ word: 011010010110
1656
+ sage: next(it)
1657
+ word: 0110100110010110
1658
+ sage: next(it)
1659
+ word: 01101001
1660
+ sage: next(it)
1661
+ word: 011010011001
1662
+ sage: next(it)
1663
+ word: 011010010110
1664
+ """
1665
+ it = self.factor_occurrences_iterator(fact)
1666
+ try:
1667
+ i = next(it)
1668
+ while True:
1669
+ j = next(it)
1670
+ yield self[i:j]
1671
+ i = j
1672
+ except StopIteration:
1673
+ return
1674
+
1675
+ def complete_return_words_iterator(self, fact):
1676
+ r"""
1677
+ Return an iterator over all the complete return words of fact in
1678
+ ``self`` (without unicity).
1679
+
1680
+ A complete return words `u` of a factor `v` is a factor starting
1681
+ by the given factor `v` and ending just after the next occurrence
1682
+ of this factor `v`. See for instance [1].
1683
+
1684
+ INPUT:
1685
+
1686
+ - ``fact`` -- a non empty finite word
1687
+
1688
+ OUTPUT: iterator
1689
+
1690
+ EXAMPLES::
1691
+
1692
+ sage: TM = words.ThueMorseWord()
1693
+ sage: fact = Word([0,1,1,0,1])
1694
+ sage: it = TM.complete_return_words_iterator(fact)
1695
+ sage: next(it)
1696
+ word: 01101001100101101
1697
+ sage: next(it)
1698
+ word: 01101001011001101
1699
+ sage: next(it)
1700
+ word: 011010011001011001101
1701
+ sage: next(it)
1702
+ word: 0110100101101
1703
+ sage: next(it)
1704
+ word: 01101001100101101
1705
+ sage: next(it)
1706
+ word: 01101001011001101
1707
+
1708
+ REFERENCES:
1709
+
1710
+ - [1] J. Justin, L. Vuillon, Return words in Sturmian and
1711
+ episturmian words, Theor. Inform. Appl. 34 (2000) 343--356.
1712
+ """
1713
+ it = self.factor_occurrences_iterator(fact)
1714
+ L = fact.length()
1715
+ try:
1716
+ i = next(it)
1717
+ while True:
1718
+ j = next(it)
1719
+ yield self[i:j+L]
1720
+ i = j
1721
+ except StopIteration:
1722
+ return