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,2932 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Word paths
5
+
6
+ This module implements word paths, which is an application of Combinatorics
7
+ on Words to Discrete Geometry. A word path is the representation of a word
8
+ as a discrete path in a vector space using a one-to-one correspondence
9
+ between the alphabet and a set of vectors called steps. Many problems
10
+ surrounding 2d lattice polygons (such as questions of self-intersection,
11
+ area, inertia moment, etc.) can be solved in linear time (linear in the
12
+ length of the perimeter) using theory from Combinatorics on Words.
13
+
14
+ On the square grid, the encoding of a path using a four-letter alphabet
15
+ (for East, North, West and South directions) is also known as the Freeman
16
+ chain code [1,2] (see [3] for further reading).
17
+
18
+ AUTHORS:
19
+
20
+ - Arnaud Bergeron (2008) : Initial version, path on the square grid
21
+
22
+ - Sébastien Labbé (2009-01-14) : New classes and hierarchy, doc and functions.
23
+
24
+ EXAMPLES:
25
+
26
+ The combinatorial class of all paths defined over three given steps::
27
+
28
+ sage: P = WordPaths('abc', steps=[(1,2), (-3,4), (0,-3)]); P
29
+ Word Paths over 3 steps
30
+
31
+ This defines a one-to-one correspondence between alphabet and steps::
32
+
33
+ sage: d = P.letters_to_steps()
34
+ sage: sorted(d.items())
35
+ [('a', (1, 2)), ('b', (-3, 4)), ('c', (0, -3))]
36
+
37
+ Creation of a path from the combinatorial class P defined above::
38
+
39
+ sage: p = P('abaccba'); p
40
+ Path: abaccba
41
+
42
+ Many functions can be used on p: the coordinates of its trajectory,
43
+ ask whether p is a closed path, plot it and many other::
44
+
45
+ sage: list(p.points())
46
+ [(0, 0), (1, 2), (-2, 6), (-1, 8), (-1, 5), (-1, 2), (-4, 6), (-3, 8)]
47
+ sage: p.is_closed()
48
+ False
49
+ sage: p.plot() # needs sage.plot
50
+ Graphics object consisting of 3 graphics primitives
51
+
52
+ To obtain a list of all the available word path specific functions,
53
+ use ``help(p)``::
54
+
55
+ sage: help(p)
56
+ Help on FiniteWordPath_2d_str in module sage.combinat.words.paths object:
57
+ ...
58
+ Methods inherited from FiniteWordPath_2d:
59
+ ...
60
+ Methods inherited from FiniteWordPath_all:
61
+ ...
62
+
63
+ Since p is a finite word, many functions from the word library are available::
64
+
65
+ sage: p.crochemore_factorization()
66
+ (a, b, a, c, c, ba)
67
+ sage: p.is_palindrome()
68
+ False
69
+ sage: p[:3]
70
+ Path: aba
71
+ sage: len(p)
72
+ 7
73
+
74
+ P also herits many functions from Words::
75
+
76
+ sage: P = WordPaths('rs', steps=[(1,2), (-1,4)]); P
77
+ Word Paths over 2 steps
78
+ sage: P.alphabet()
79
+ {'r', 's'}
80
+ sage: list(P.iterate_by_length(3))
81
+ [Path: rrr,
82
+ Path: rrs,
83
+ Path: rsr,
84
+ Path: rss,
85
+ Path: srr,
86
+ Path: srs,
87
+ Path: ssr,
88
+ Path: sss]
89
+
90
+ When the number of given steps is half the size of alphabet, the
91
+ opposite of vectors are used::
92
+
93
+ sage: P = WordPaths('abcd', [(1,0), (0,1)])
94
+ sage: sorted(P.letters_to_steps().items())
95
+ [('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
96
+
97
+ Some built-in combinatorial classes of paths::
98
+
99
+ sage: P = WordPaths('abAB', steps='square_grid'); P
100
+ Word Paths on the square grid
101
+
102
+ ::
103
+
104
+ sage: D = WordPaths('()', steps='dyck'); D
105
+ Finite Dyck paths
106
+ sage: d = D('()()()(())'); d
107
+ Path: ()()()(())
108
+ sage: d.plot() # needs sage.plot
109
+ Graphics object consisting of 3 graphics primitives
110
+
111
+ ::
112
+
113
+ sage: # needs sage.rings.number_field
114
+ sage: P = WordPaths('abcdef', steps='triangle_grid')
115
+ sage: p = P('babaddefadabcadefaadfafabacdefa')
116
+ sage: p.plot() # needs sage.plot
117
+ Graphics object consisting of 3 graphics primitives
118
+
119
+ Vector steps may be in more than 2 dimensions::
120
+
121
+ sage: d = [(1,0,0), (0,1,0), (0,0,1)]
122
+ sage: P = WordPaths(alphabet='abc', steps=d); P
123
+ Word Paths over 3 steps
124
+ sage: p = P('abcabcabcabcaabacabcababcacbabacacabcaccbcac')
125
+ sage: p.plot() # needs sage.plot
126
+ Graphics3d Object
127
+
128
+ ::
129
+
130
+ sage: d = [(1,3,5,1), (-5,1,-6,0), (0,0,1,9), (4,2,-1,0)]
131
+ sage: P = WordPaths(alphabet='rstu', steps=d); P
132
+ Word Paths over 4 steps
133
+ sage: p = P('rtusuusususuturrsust'); p
134
+ Path: rtusuusususuturrsust
135
+ sage: p.end_point()
136
+ (5, 31, -26, 30)
137
+
138
+ ::
139
+
140
+ sage: CubePaths = WordPaths('abcABC', steps='cube_grid'); CubePaths
141
+ Word Paths on the cube grid
142
+ sage: CubePaths('abcabaabcabAAAAA').plot() # needs sage.plot
143
+ Graphics3d Object
144
+
145
+ The input data may be a str, a list, a tuple,
146
+ a callable or a finite iterator::
147
+
148
+ sage: P = WordPaths([0, 1, 2, 3])
149
+ sage: P([0,1,2,3,2,1,2,3,2])
150
+ Path: 012321232
151
+ sage: P((0,1,2,3,2,1,2,3,2))
152
+ Path: 012321232
153
+ sage: P(lambda n:n%4, length=10)
154
+ Path: 0123012301
155
+ sage: P(iter([0,3,2,1]), length='finite')
156
+ Path: 0321
157
+
158
+ REFERENCES:
159
+
160
+ - [1] Freeman, H.: *On the encoding of arbitrary geometric configurations*.
161
+ IRE Trans. Electronic Computer 10 (1961) 260-268.
162
+ - [2] Freeman, H.: *Boundary encoding and processing*. In Lipkin, B., Rosenfeld,
163
+ A., eds.: Picture Processing and Psychopictorics, Academic Press, New York
164
+ (1970) 241-266.
165
+ - [3] Braquelaire, J.P., Vialard, A.: *Euclidean paths: A new representation of
166
+ boundary of discrete regions*. Graphical Models and Image Processing 61 (1999)
167
+ 16-43.
168
+ - [4] :wikipedia:`Regular_tiling`
169
+ - [5] :wikipedia:`Dyck_word`
170
+ """
171
+ # ****************************************************************************
172
+ # Copyright (C) 2008 Arnaud bergeron <abergeron@gmail.coms>,
173
+ # Copyright (C) 2009 Sebastien Labbe <slabqc@gmail.com>,
174
+ #
175
+ # This program is free software: you can redistribute it and/or modify
176
+ # it under the terms of the GNU General Public License as published by
177
+ # the Free Software Foundation, either version 2 of the License, or
178
+ # (at your option) any later version.
179
+ # https://www.gnu.org/licenses/
180
+ # ****************************************************************************
181
+
182
+ from sage.structure.sage_object import SageObject
183
+ from sage.misc.cachefunc import cached_method
184
+ from sage.misc.lazy_attribute import lazy_attribute
185
+ from sage.combinat.words.words import FiniteWords
186
+ from sage.combinat.words.word import FiniteWord_class
187
+ from sage.combinat.words.alphabet import build_alphabet
188
+ from sage.misc.lazy_import import lazy_import
189
+ from sage.modules.free_module_element import vector
190
+ from sage.rings.integer_ring import ZZ
191
+ from sage.rings.real_mpfr import RR
192
+ from .word_datatypes import (WordDatatype_str,
193
+ WordDatatype_list,
194
+ WordDatatype_tuple)
195
+ # WordDatatype_cpp_basic_string)
196
+
197
+ from .word_infinite_datatypes import (
198
+ WordDatatype_iter_with_caching,
199
+ WordDatatype_iter,
200
+ WordDatatype_callable_with_caching,
201
+ WordDatatype_callable)
202
+ from sage.matrix.constructor import vector_on_axis_rotation_matrix
203
+
204
+ lazy_import("sage.plot.all", ["arrow", "line", "polygon", "point", "Graphics"])
205
+ lazy_import('sage.rings.number_field.number_field', 'QuadraticField')
206
+
207
+
208
+ #######################################################################
209
+ # #
210
+ # WordPaths function #
211
+ # #
212
+ #######################################################################
213
+
214
+ def WordPaths(alphabet, steps=None):
215
+ r"""
216
+ Return the combinatorial class of paths of the given type of steps.
217
+
218
+ INPUT:
219
+
220
+ - ``alphabet`` -- ordered alphabet
221
+
222
+ - ``steps`` -- (default: ``None``) it can be one of the following:
223
+
224
+ - an iterable ordered container of as many vectors as there are
225
+ letters in the alphabet. The vectors are associated to the letters
226
+ according to their order in steps. The vectors can be a tuple or
227
+ anything that can be passed to vector function.
228
+
229
+ - an iterable ordered container of k vectors where k is half the
230
+ size of alphabet. The vectors and their opposites are associated
231
+ to the letters according to their order in steps (given vectors
232
+ first, opposite vectors after).
233
+
234
+ - ``None`` -- in this case, the type of steps are guessed from the
235
+ length of alphabet
236
+
237
+ - ``'square_grid'`` or ``'square'`` -- (default when size of alphabet is 4)
238
+ The order is : East, North, West, South.
239
+
240
+ - ``'triangle_grid'`` or ``'triangle'``
241
+
242
+ - ``'hexagonal_grid'`` or ``'hexagon'`` -- (default when size of alphabet is 6)
243
+
244
+ - ``'cube_grid'`` or ``'cube'``
245
+
246
+ - ``'north_east'``, ``'ne'`` or ``'NE'`` -- (the default when size of alphabet is 2)
247
+
248
+ - ``'dyck'``
249
+
250
+ OUTPUT: the combinatorial class of all paths of the given type
251
+
252
+ EXAMPLES:
253
+
254
+ The steps can be given explicitly::
255
+
256
+ sage: WordPaths('abc', steps=[(1,2), (-1,4), (0,-3)])
257
+ Word Paths over 3 steps
258
+
259
+ Different type of input alphabet::
260
+
261
+ sage: WordPaths(range(3), steps=[(1,2), (-1,4), (0,-3)])
262
+ Word Paths over 3 steps
263
+ sage: WordPaths(['cric','crac','croc'], steps=[(1,2), (1,4), (0,3)])
264
+ Word Paths over 3 steps
265
+
266
+ Directions can be in three dimensions as well::
267
+
268
+ sage: WordPaths('ab', steps=[(1,2,2),(-1,4,2)])
269
+ Word Paths over 2 steps
270
+
271
+ When the number of given steps is half the size of alphabet, the
272
+ opposite of vectors are used::
273
+
274
+ sage: P = WordPaths('abcd', [(1,0), (0,1)])
275
+ sage: P
276
+ Word Paths over 4 steps
277
+ sage: sorted(P.letters_to_steps().items())
278
+ [('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
279
+
280
+ When no steps are given, default classes are returned::
281
+
282
+ sage: WordPaths('ab')
283
+ Word Paths in North and East steps
284
+ sage: WordPaths(range(4))
285
+ Word Paths on the square grid
286
+ sage: WordPaths(range(6)) # needs sage.rings.number_field
287
+ Word Paths on the hexagonal grid
288
+
289
+ There are many type of built-in steps...
290
+
291
+ On a two letters alphabet::
292
+
293
+ sage: WordPaths('ab', steps='north_east')
294
+ Word Paths in North and East steps
295
+ sage: WordPaths('()', steps='dyck')
296
+ Finite Dyck paths
297
+
298
+ On a four letters alphabet::
299
+
300
+ sage: WordPaths('ruld', steps='square_grid')
301
+ Word Paths on the square grid
302
+
303
+ On a six letters alphabet::
304
+
305
+ sage: WordPaths('abcdef', steps='hexagonal_grid') # needs sage.rings.number_field
306
+ Word Paths on the hexagonal grid
307
+ sage: WordPaths('abcdef', steps='triangle_grid') # needs sage.rings.number_field
308
+ Word Paths on the triangle grid
309
+ sage: WordPaths('abcdef', steps='cube_grid')
310
+ Word Paths on the cube grid
311
+
312
+ TESTS::
313
+
314
+ sage: WordPaths(range(5))
315
+ Traceback (most recent call last):
316
+ ...
317
+ TypeError: Unable to make a class WordPaths from {0, 1, 2, 3, 4}
318
+ sage: WordPaths('abAB', steps='square_gridd')
319
+ Traceback (most recent call last):
320
+ ...
321
+ TypeError: Unknown type of steps : square_gridd
322
+ """
323
+ # Construction of the alphabet
324
+ alphabet = build_alphabet(alphabet)
325
+
326
+ # If no steps are given, they are guessed from the alphabet
327
+ if steps is None:
328
+ if alphabet.cardinality() == 2:
329
+ steps = 'north_east'
330
+ elif alphabet.cardinality() == 4:
331
+ steps = 'square_grid'
332
+ elif alphabet.cardinality() == 6:
333
+ steps = 'hexagonal_grid'
334
+ else:
335
+ raise TypeError("Unable to make a class WordPaths from %s" % alphabet)
336
+
337
+ # Return the class of WordPaths according to the given type of paths
338
+ if isinstance(steps, str):
339
+ if steps in ('square_grid', 'square'):
340
+ return WordPaths_square_grid(alphabet=alphabet)
341
+ elif steps in ('triangle_grid', 'triangle'):
342
+ return WordPaths_triangle_grid(alphabet=alphabet)
343
+ elif steps in ('hexagonal_grid', 'hexagon'):
344
+ return WordPaths_hexagonal_grid(alphabet=alphabet)
345
+ elif steps in ('cube_grid', 'cube'):
346
+ return WordPaths_cube_grid(alphabet=alphabet)
347
+ elif steps in ('north_east', 'ne', 'NE'):
348
+ return WordPaths_north_east(alphabet=alphabet)
349
+ elif steps == 'dyck':
350
+ return WordPaths_dyck(alphabet=alphabet)
351
+ else:
352
+ raise TypeError("Unknown type of steps : %s" % steps)
353
+ else:
354
+ return WordPaths_all(alphabet=alphabet, steps=steps)
355
+
356
+
357
+ #######################################################################
358
+ # #
359
+ # Combinatorial classes of word paths #
360
+ # #
361
+ #######################################################################
362
+
363
+ class WordPaths_all(FiniteWords):
364
+ r"""
365
+ The combinatorial class of all paths, i.e of all words over
366
+ an alphabet where each letter is mapped to a step (a vector).
367
+ """
368
+ def __init__(self, alphabet, steps):
369
+ r"""
370
+ INPUT:
371
+
372
+ - ``alphabet`` -- an ordered alphabet
373
+
374
+ - ``steps`` -- an iterable (of same length as alphabet or half the
375
+ length of alphabet) of ordered vectors
376
+
377
+ EXAMPLES::
378
+
379
+ sage: from sage.combinat.words.paths import WordPaths_all
380
+ sage: d = ((1,1), (-1,1), (1,-1), (-1,-1))
381
+ sage: P = WordPaths_all('abAB', d); P
382
+ Word Paths over 4 steps
383
+ sage: P == loads(dumps(P))
384
+ True
385
+
386
+ If size of alphabet is twice the number of steps, then opposite
387
+ vectors are used for the second part of the alphabet::
388
+
389
+ sage: WordPaths('abcd',[(2,1),(2,4)])
390
+ Word Paths over 4 steps
391
+ sage: _.letters_to_steps()
392
+ {'a': (2, 1), 'b': (2, 4), 'c': (-2, -1), 'd': (-2, -4)}
393
+
394
+ TESTS::
395
+
396
+ sage: from sage.combinat.words.paths import WordPaths_all
397
+ sage: d = ((1,1), (-1,1), (1,-1), (-1,-1))
398
+ sage: WordPaths_all('abA', d)
399
+ Traceback (most recent call last):
400
+ ...
401
+ TypeError: size of steps (=4) must equal the size of alphabet (=3) or half the size of alphabet
402
+
403
+ sage: d = ((1,1), 1)
404
+ sage: WordPaths_all('ab', d)
405
+ Traceback (most recent call last):
406
+ ...
407
+ ValueError: cannot make vectors from steps
408
+
409
+ sage: d = ((1,1), (-1,1,0))
410
+ sage: WordPaths_all('ab', d)
411
+ Traceback (most recent call last):
412
+ ...
413
+ ValueError: cannot make summable vectors from steps
414
+ """
415
+ # Construction of the words class
416
+ FiniteWords.__init__(self, alphabet)
417
+ alphabet = self.alphabet()
418
+
419
+ # Checking the size of alphabet and steps
420
+ ls = len(steps)
421
+ la = alphabet.cardinality()
422
+ if la != ls and la != 2 * ls:
423
+ raise TypeError("size of steps (=%s) must equal the size of alphabet (=%s) or half the size of alphabet" % (len(steps), alphabet.cardinality()))
424
+
425
+ # Construction of the steps
426
+ from sage.structure.element import Vector
427
+ if all(isinstance(x, Vector) for x in steps):
428
+ vsteps = steps
429
+ else:
430
+ try:
431
+ vsteps = [vector(s) for s in steps]
432
+ except (TypeError):
433
+ raise ValueError("cannot make vectors from steps")
434
+ try:
435
+ s = sum(vsteps)
436
+ except (TypeError, AttributeError):
437
+ raise ValueError("cannot make summable vectors from steps")
438
+
439
+ # Complete vsteps with the opposite vectors if needed
440
+ if la == 2 * ls:
441
+ vsteps += [-v for v in vsteps]
442
+
443
+ self._steps = dict(zip(alphabet, vsteps))
444
+ self._vector_space = s.parent()
445
+
446
+ def __eq__(self, other):
447
+ r"""
448
+ TESTS::
449
+
450
+ sage: W1 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
451
+ sage: W2 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
452
+ sage: W3 = WordPaths(['a','b'], [vector((0,2)), vector((1,0))])
453
+ sage: W1 == W2
454
+ True
455
+ sage: W1 == W3
456
+ False
457
+ """
458
+ return self is other or (type(self) is type(other) and
459
+ self.alphabet() == other.alphabet() and
460
+ self.vector_space() == other.vector_space() and
461
+ self.letters_to_steps() == other.letters_to_steps())
462
+
463
+ def __ne__(self, other):
464
+ r"""
465
+ TESTS::
466
+
467
+ sage: W1 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
468
+ sage: W2 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
469
+ sage: W3 = WordPaths(['a','b'], [vector((0,2)), vector((1,0))])
470
+ sage: W1 != W2
471
+ False
472
+ sage: W1 != W3
473
+ True
474
+ """
475
+ return not (self == other)
476
+
477
+ @lazy_attribute
478
+ def _element_classes(self):
479
+ r"""
480
+ Return a dictionary that gives the class of the elements of ``self``.
481
+
482
+ The word may be finite (infinite or of unknown length is not supported
483
+ yet).
484
+ Its data may be str, list, tuple, a callable or an iterable.
485
+ For callable and iterable, the data may be cached.
486
+ The dimension of the path may be 1, 2, 3 or more.
487
+
488
+ TESTS::
489
+
490
+ sage: d = WordPaths('ab',steps=[(1,2),(3,4)])._element_classes
491
+ sage: type(d)
492
+ <class 'dict'>
493
+ sage: len(d)
494
+ 7
495
+ sage: d['tuple']
496
+ <class 'sage.combinat.words.paths.FiniteWordPath_2d_tuple'>
497
+
498
+ ::
499
+
500
+ sage: d = WordPaths('ab',steps=[(1,2,3),(3,4,5)])._element_classes
501
+ sage: len(d)
502
+ 7
503
+ sage: d['tuple']
504
+ <class 'sage.combinat.words.paths.FiniteWordPath_3d_tuple'>
505
+
506
+ ::
507
+
508
+ sage: steps = [(1,2,3,4),(3,4,5,6)]
509
+ sage: d = WordPaths('ab',steps=steps)._element_classes
510
+ sage: len(d)
511
+ 7
512
+ sage: d['tuple']
513
+ <class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
514
+
515
+ ::
516
+
517
+ sage: d = WordPaths('ab',steps=[(1,),(3,)])._element_classes
518
+ sage: len(d)
519
+ 7
520
+ sage: d['tuple']
521
+ <class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
522
+ """
523
+ dimension = self._vector_space.dimension()
524
+ if dimension == 2:
525
+ return {
526
+ 'list': FiniteWordPath_2d_list,
527
+ 'str': FiniteWordPath_2d_str,
528
+ 'tuple': FiniteWordPath_2d_tuple,
529
+ 'callable_with_caching': FiniteWordPath_2d_callable_with_caching,
530
+ 'callable': FiniteWordPath_2d_callable,
531
+ 'iter_with_caching': FiniteWordPath_2d_iter_with_caching,
532
+ 'iter': FiniteWordPath_2d_iter,
533
+ }
534
+ elif dimension == 3:
535
+ return {
536
+ 'list': FiniteWordPath_3d_list,
537
+ 'str': FiniteWordPath_3d_str,
538
+ 'tuple': FiniteWordPath_3d_tuple,
539
+ 'callable_with_caching': FiniteWordPath_3d_callable_with_caching,
540
+ 'callable': FiniteWordPath_3d_callable,
541
+ 'iter_with_caching': FiniteWordPath_3d_iter_with_caching,
542
+ 'iter': FiniteWordPath_3d_iter,
543
+ }
544
+ else:
545
+ return {
546
+ 'list': FiniteWordPath_all_list,
547
+ 'str': FiniteWordPath_all_str,
548
+ 'tuple': FiniteWordPath_all_tuple,
549
+ 'callable_with_caching': FiniteWordPath_all_callable_with_caching,
550
+ 'callable': FiniteWordPath_all_callable,
551
+ 'iter_with_caching': FiniteWordPath_all_iter_with_caching,
552
+ 'iter': FiniteWordPath_all_iter,
553
+ }
554
+
555
+ def __repr__(self) -> str:
556
+ r"""
557
+ Return a string representation of ``self``.
558
+
559
+ EXAMPLES::
560
+
561
+ sage: from sage.combinat.words.paths import WordPaths_all
562
+ sage: d = (vector((1,1)), vector((-1,1)), vector((1,-1)), vector((-1,-1)))
563
+ sage: WordPaths_all('abAB',d).__repr__()
564
+ 'Word Paths over 4 steps'
565
+ """
566
+ return "Word Paths over %s steps" % self.alphabet().cardinality()
567
+
568
+ def letters_to_steps(self) -> dict:
569
+ r"""
570
+ Return the dictionary mapping letters to vectors (steps).
571
+
572
+ EXAMPLES::
573
+
574
+ sage: d = WordPaths('ab').letters_to_steps()
575
+ sage: sorted(d.items())
576
+ [('a', (0, 1)), ('b', (1, 0))]
577
+ sage: d = WordPaths('abcd').letters_to_steps()
578
+ sage: sorted(d.items())
579
+ [('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
580
+ sage: d = WordPaths('abcdef').letters_to_steps() # needs sage.rings.number_field
581
+ sage: sorted(d.items()) # needs sage.rings.number_field
582
+ [('a', (1, 0)),
583
+ ('b', (1/2, 1/2*sqrt3)),
584
+ ('c', (-1/2, 1/2*sqrt3)),
585
+ ('d', (-1, 0)),
586
+ ('e', (-1/2, -1/2*sqrt3)),
587
+ ('f', (1/2, -1/2*sqrt3))]
588
+ """
589
+ return self._steps
590
+
591
+ def vector_space(self):
592
+ r"""
593
+ Return the vector space over which the steps of the paths are defined.
594
+
595
+ EXAMPLES::
596
+
597
+ sage: WordPaths('ab',steps='dyck').vector_space()
598
+ Ambient free module of rank 2 over the principal ideal domain Integer Ring
599
+ sage: WordPaths('ab',steps='north_east').vector_space()
600
+ Ambient free module of rank 2 over the principal ideal domain Integer Ring
601
+ sage: WordPaths('abcd',steps='square_grid').vector_space()
602
+ Ambient free module of rank 2 over the principal ideal domain Integer Ring
603
+ sage: WordPaths('abcdef',steps='hexagonal_grid').vector_space() # needs sage.rings.number_field
604
+ Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?
605
+ sage: WordPaths('abcdef',steps='cube_grid').vector_space()
606
+ Ambient free module of rank 3 over the principal ideal domain Integer Ring
607
+ sage: WordPaths('abcdef',steps='triangle_grid').vector_space() # needs sage.rings.number_field
608
+ Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?
609
+ """
610
+ return self._vector_space
611
+
612
+
613
+ class WordPaths_square_grid(WordPaths_all):
614
+ r"""
615
+ The combinatorial class of all paths on the square grid.
616
+ """
617
+ def __init__(self, alphabet):
618
+ r"""
619
+ The combinatorial class of all finite paths on the square grid.
620
+
621
+ INPUT:
622
+
623
+ - ``alphabet`` -- ordered alphabet of length 4; the order for the steps
624
+ is : East, North, West, South
625
+
626
+ EXAMPLES::
627
+
628
+ sage: from sage.combinat.words.paths import WordPaths_square_grid
629
+ sage: P = WordPaths_square_grid('abAB'); P
630
+ Word Paths on the square grid
631
+ sage: P == loads(dumps(P))
632
+ True
633
+ """
634
+ # Construction of the steps
635
+ d = [(1, 0), (0, 1), (-1, 0), (0, -1)]
636
+
637
+ # Construction of the class
638
+ super().__init__(alphabet, steps=d)
639
+
640
+ @lazy_attribute
641
+ def _element_classes(self):
642
+ r"""
643
+ Return a dictionary that gives the class of the elements of ``self``.
644
+
645
+ The word may be finite (infinite or of unknown length is not supported
646
+ yet).
647
+ Its data may be str, list, tuple, a callable or an iterable.
648
+ For callable and iterable, the data may be cached.
649
+
650
+ TESTS::
651
+
652
+ sage: d = WordPaths('abcd')._element_classes
653
+ sage: type(d)
654
+ <class 'dict'>
655
+ sage: len(d)
656
+ 7
657
+ sage: d['tuple']
658
+ <class 'sage.combinat.words.paths.FiniteWordPath_square_grid_tuple'>
659
+ """
660
+ return {
661
+ 'list': FiniteWordPath_square_grid_list,
662
+ 'str': FiniteWordPath_square_grid_str,
663
+ 'tuple': FiniteWordPath_square_grid_tuple,
664
+ 'callable_with_caching': FiniteWordPath_square_grid_callable_with_caching,
665
+ 'callable': FiniteWordPath_square_grid_callable,
666
+ 'iter_with_caching': FiniteWordPath_square_grid_iter_with_caching,
667
+ 'iter': FiniteWordPath_square_grid_iter,
668
+ }
669
+
670
+ def __repr__(self) -> str:
671
+ r"""
672
+ EXAMPLES::
673
+
674
+ sage: from sage.combinat.words.paths import WordPaths_square_grid
675
+ sage: WordPaths_square_grid('abAB').__repr__()
676
+ 'Word Paths on the square grid'
677
+ """
678
+ return "Word Paths on the square grid"
679
+
680
+
681
+ class WordPaths_triangle_grid(WordPaths_all):
682
+ r"""
683
+ The combinatorial class of all paths on the triangle grid.
684
+ """
685
+ def __init__(self, alphabet):
686
+ r"""
687
+ The combinatorial class of all finite paths on the triangle grid.
688
+
689
+ INPUT:
690
+
691
+ - ``alphabet`` -- ordered alphabet of length 6. The order for the steps
692
+ is : Right, Up-Right, Up-Left, Left, Down-Left, Down-Right.
693
+
694
+ EXAMPLES::
695
+
696
+ sage: from sage.combinat.words.paths import WordPaths_triangle_grid
697
+ sage: P = WordPaths_triangle_grid('abcdef'); P # needs sage.rings.number_field
698
+ Word Paths on the triangle grid
699
+ sage: P == loads(dumps(P)) # needs sage.rings.number_field
700
+ True
701
+ """
702
+ K = QuadraticField(3, 'sqrt3')
703
+ sqrt3 = K.gen()
704
+
705
+ # Construction of the steps
706
+ d = (vector(K, (1, 0)),
707
+ vector(K, (ZZ(1) / ZZ(2), sqrt3 / 2)),
708
+ vector(K, (ZZ(-1) / ZZ(2), sqrt3 / 2)),
709
+ vector(K, (-1, 0)),
710
+ vector(K, (ZZ(-1) / ZZ(2), -sqrt3 / 2)),
711
+ vector(K, (ZZ(1) / ZZ(2), -sqrt3 / 2)))
712
+
713
+ # Construction of the class
714
+ super().__init__(alphabet, steps=d)
715
+
716
+ self._infinite_word_class = None
717
+ self._finite_word_class = FiniteWordPath_triangle_grid
718
+
719
+ @lazy_attribute
720
+ def _element_classes(self):
721
+ r"""
722
+ Return a dictionary that gives the class of the elements of ``self``.
723
+
724
+ The word may be finite (infinite or of unknown length is not supported
725
+ yet).
726
+ Its data may be str, list, tuple, a callable or an iterable.
727
+ For callable and iterable, the data may be cached.
728
+
729
+ TESTS::
730
+
731
+ sage: # needs sage.rings.number_field
732
+ sage: d = WordPaths('abcdef', steps='triangle')._element_classes
733
+ sage: len(d)
734
+ 7
735
+ sage: type(d)
736
+ <class 'dict'>
737
+ sage: d['tuple']
738
+ <class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_tuple'>
739
+ """
740
+ return {
741
+ 'list': FiniteWordPath_triangle_grid_list,
742
+ 'str': FiniteWordPath_triangle_grid_str,
743
+ 'tuple': FiniteWordPath_triangle_grid_tuple,
744
+ 'callable_with_caching': FiniteWordPath_triangle_grid_callable_with_caching,
745
+ 'callable': FiniteWordPath_triangle_grid_callable,
746
+ 'iter_with_caching': FiniteWordPath_triangle_grid_iter_with_caching,
747
+ 'iter': FiniteWordPath_triangle_grid_iter,
748
+ }
749
+
750
+ def __repr__(self) -> str:
751
+ r"""
752
+ EXAMPLES::
753
+
754
+ sage: from sage.combinat.words.paths import WordPaths_triangle_grid
755
+ sage: WordPaths_triangle_grid('abcdef').__repr__() # needs sage.rings.number_field
756
+ 'Word Paths on the triangle grid'
757
+ """
758
+ return "Word Paths on the triangle grid"
759
+
760
+
761
+ class WordPaths_hexagonal_grid(WordPaths_triangle_grid):
762
+ r"""
763
+ The combinatorial class of all paths on the hexagonal grid.
764
+ """
765
+ def __init__(self, alphabet):
766
+ r"""
767
+ The combinatorial class of all finite paths on the hexagonal grid.
768
+
769
+ INPUT:
770
+
771
+ - ``alphabet`` -- ordered alphabet of length 6. The order for the steps
772
+ is : Right, Up-Right, Up-Left, Left, Down-Left, Down-Right.
773
+
774
+ EXAMPLES::
775
+
776
+ sage: from sage.combinat.words.paths import WordPaths_hexagonal_grid
777
+ sage: P = WordPaths_hexagonal_grid('abcdef'); P # needs sage.rings.number_field
778
+ Word Paths on the hexagonal grid
779
+ sage: P == loads(dumps(P)) # needs sage.rings.number_field
780
+ True
781
+ """
782
+ # Construction of the class
783
+ super().__init__(alphabet)
784
+
785
+ self._infinite_word_class = None
786
+ self._finite_word_class = FiniteWordPath_hexagonal_grid
787
+
788
+ @lazy_attribute
789
+ def _element_classes(self):
790
+ r"""
791
+ Return a dictionary that gives the class of the elements of ``self``.
792
+
793
+ The word may be finite (infinite or of unknown length is not supported
794
+ yet).
795
+ Its data may be str, list, tuple, a callable or an iterable.
796
+ For callable and iterable, the data may be cached.
797
+
798
+ TESTS::
799
+
800
+ sage: # needs sage.rings.number_field
801
+ sage: d = WordPaths('abcdef', steps='hexagon')._element_classes
802
+ sage: type(d)
803
+ <class 'dict'>
804
+ sage: len(d)
805
+ 7
806
+ sage: d['tuple']
807
+ <class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_tuple'>
808
+ """
809
+ return {
810
+ 'list': FiniteWordPath_hexagonal_grid_list,
811
+ 'str': FiniteWordPath_hexagonal_grid_str,
812
+ 'tuple': FiniteWordPath_hexagonal_grid_tuple,
813
+ 'callable_with_caching': FiniteWordPath_hexagonal_grid_callable_with_caching,
814
+ 'callable': FiniteWordPath_hexagonal_grid_callable,
815
+ 'iter_with_caching': FiniteWordPath_hexagonal_grid_iter_with_caching,
816
+ 'iter': FiniteWordPath_hexagonal_grid_iter,
817
+ }
818
+
819
+ def __repr__(self) -> str:
820
+ r"""
821
+ EXAMPLES::
822
+
823
+ sage: from sage.combinat.words.paths import WordPaths_hexagonal_grid # needs sage.rings.number_field
824
+ sage: WordPaths_hexagonal_grid('abcdef').__repr__() # needs sage.rings.number_field
825
+ 'Word Paths on the hexagonal grid'
826
+ """
827
+ return "Word Paths on the hexagonal grid"
828
+
829
+
830
+ class WordPaths_cube_grid(WordPaths_all):
831
+ r"""
832
+ The combinatorial class of all paths on the cube grid.
833
+ """
834
+ def __init__(self, alphabet):
835
+ r"""
836
+ The combinatorial class of all finite paths on the cube grid.
837
+
838
+ INPUT:
839
+
840
+ - ``alphabet`` -- ordered alphabet of length 6. The order for
841
+ the steps is `e_x, e_y, e_z, -e_x, -e_y, -e_z`, where `e_v`
842
+ denotes the canonical basis.
843
+
844
+ EXAMPLES::
845
+
846
+ sage: from sage.combinat.words.paths import WordPaths_cube_grid
847
+ sage: P = WordPaths_cube_grid('abcABC'); P
848
+ Word Paths on the cube grid
849
+ sage: P == loads(dumps(P))
850
+ True
851
+ """
852
+ # Construction of the class
853
+ d = [(1, 0, 0), (0, 1, 0), (0, 0, 1),
854
+ (-1, 0, 0), (0, -1, 0), (0, 0, -1)]
855
+ super().__init__(alphabet, steps=d)
856
+ self._infinite_word_class = None
857
+ self._finite_word_class = FiniteWordPath_cube_grid
858
+
859
+ @lazy_attribute
860
+ def _element_classes(self):
861
+ r"""
862
+ Return a dictionary that gives the class of the elements of ``self``.
863
+
864
+ The word may be finite (infinite or of unknown length is not supported
865
+ yet).
866
+ Its data may be str, list, tuple, a callable or an iterable.
867
+ For callable and iterable, the data may be cached.
868
+
869
+ TESTS::
870
+
871
+ sage: d = WordPaths('abcdef', steps='cube')._element_classes
872
+ sage: type(d)
873
+ <class 'dict'>
874
+ sage: len(d)
875
+ 7
876
+ sage: d['tuple']
877
+ <class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_tuple'>
878
+ """
879
+ return {'list': FiniteWordPath_cube_grid_list,
880
+ 'str': FiniteWordPath_cube_grid_str,
881
+ 'tuple': FiniteWordPath_cube_grid_tuple,
882
+ 'callable_with_caching': FiniteWordPath_cube_grid_callable_with_caching,
883
+ 'callable': FiniteWordPath_cube_grid_callable,
884
+ 'iter_with_caching': FiniteWordPath_cube_grid_iter_with_caching,
885
+ 'iter': FiniteWordPath_cube_grid_iter,
886
+ }
887
+
888
+ def __repr__(self) -> str:
889
+ r"""
890
+ EXAMPLES::
891
+
892
+ sage: from sage.combinat.words.paths import WordPaths_cube_grid
893
+ sage: WordPaths_cube_grid('abcABC').__repr__()
894
+ 'Word Paths on the cube grid'
895
+ """
896
+ return "Word Paths on the cube grid"
897
+
898
+
899
+ class WordPaths_dyck(WordPaths_all):
900
+ r"""
901
+ The combinatorial class of all Dyck paths.
902
+ """
903
+ def __init__(self, alphabet):
904
+ r"""
905
+ The combinatorial class of all finite Dyck paths.
906
+
907
+ INPUT:
908
+
909
+ - ``alphabet`` -- ordered alphabet of length 2. The order for the steps
910
+ is : (1,1), (1,-1)
911
+
912
+ EXAMPLES::
913
+
914
+ sage: from sage.combinat.words.paths import WordPaths_dyck
915
+ sage: P = WordPaths_dyck('[]'); P
916
+ Finite Dyck paths
917
+ sage: P == loads(dumps(P))
918
+ True
919
+ """
920
+ # Construction of the class
921
+ d = [(1, 1), (1, -1)]
922
+ super().__init__(alphabet, steps=d)
923
+
924
+ self._infinite_word_class = None
925
+ self._finite_word_class = FiniteWordPath_dyck
926
+
927
+ @lazy_attribute
928
+ def _element_classes(self):
929
+ r"""
930
+ Return a dictionary that gives the class of the elements of ``self``.
931
+
932
+ The word may be finite (infinite or of unknown length is not supported
933
+ yet).
934
+ Its data may be str, list, tuple, a callable or an iterable.
935
+ For callable and iterable, the data may be cached.
936
+
937
+ TESTS::
938
+
939
+ sage: d = WordPaths('ab', steps='dyck')._element_classes
940
+ sage: type(d)
941
+ <class 'dict'>
942
+ sage: len(d)
943
+ 7
944
+ sage: d['tuple']
945
+ <class 'sage.combinat.words.paths.FiniteWordPath_dyck_tuple'>
946
+ """
947
+ return {'list': FiniteWordPath_dyck_list,
948
+ 'str': FiniteWordPath_dyck_str,
949
+ 'tuple': FiniteWordPath_dyck_tuple,
950
+ 'callable_with_caching': FiniteWordPath_dyck_callable_with_caching,
951
+ 'callable': FiniteWordPath_dyck_callable,
952
+ 'iter_with_caching': FiniteWordPath_dyck_iter_with_caching,
953
+ 'iter': FiniteWordPath_dyck_iter,
954
+ }
955
+
956
+ def __repr__(self) -> str:
957
+ r"""
958
+ EXAMPLES::
959
+
960
+ sage: from sage.combinat.words.paths import WordPaths_dyck
961
+ sage: WordPaths_dyck('()').__repr__()
962
+ 'Finite Dyck paths'
963
+ """
964
+ return "Finite Dyck paths"
965
+
966
+
967
+ class WordPaths_north_east(WordPaths_all):
968
+ r"""
969
+ The combinatorial class of all paths using North and East directions.
970
+ """
971
+ def __init__(self, alphabet):
972
+ r"""
973
+ The combinatorial class of all finite paths using only north and east
974
+ steps on the square grid.
975
+
976
+ INPUT:
977
+
978
+ - ``alphabet`` -- ordered alphabet of length 2. The order for the steps
979
+ is North, East
980
+
981
+ EXAMPLES::
982
+
983
+ sage: from sage.combinat.words.paths import WordPaths_north_east
984
+ sage: P = WordPaths_north_east('ab'); P
985
+ Word Paths in North and East steps
986
+ sage: P == loads(dumps(P))
987
+ True
988
+ """
989
+ # Construction of the class
990
+ d = [(0, 1), (1, 0)]
991
+ super().__init__(alphabet, steps=d)
992
+ self._infinite_word_class = None
993
+ self._finite_word_class = FiniteWordPath_north_east
994
+
995
+ @lazy_attribute
996
+ def _element_classes(self):
997
+ r"""
998
+ Return a dictionary that gives the class of the elements of ``self``.
999
+
1000
+ The word may be finite (infinite or of unknown length is not supported
1001
+ yet).
1002
+ Its data may be str, list, tuple, a callable or an iterable.
1003
+ For callable and iterable, the data may be cached.
1004
+
1005
+ TESTS::
1006
+
1007
+ sage: d = WordPaths('ab', steps='NE')._element_classes
1008
+ sage: type(d)
1009
+ <class 'dict'>
1010
+ sage: len(d)
1011
+ 7
1012
+ sage: d['tuple']
1013
+ <class 'sage.combinat.words.paths.FiniteWordPath_north_east_tuple'>
1014
+ """
1015
+ return {'list': FiniteWordPath_north_east_list,
1016
+ 'str': FiniteWordPath_north_east_str,
1017
+ 'tuple': FiniteWordPath_north_east_tuple,
1018
+ 'callable_with_caching': FiniteWordPath_north_east_callable_with_caching,
1019
+ 'callable': FiniteWordPath_north_east_callable,
1020
+ 'iter_with_caching': FiniteWordPath_north_east_iter_with_caching,
1021
+ 'iter': FiniteWordPath_north_east_iter,
1022
+ }
1023
+
1024
+ def __repr__(self) -> str:
1025
+ r"""
1026
+ EXAMPLES::
1027
+
1028
+ sage: from sage.combinat.words.paths import WordPaths_north_east
1029
+ sage: WordPaths_north_east('ab').__repr__()
1030
+ 'Word Paths in North and East steps'
1031
+ """
1032
+ return "Word Paths in North and East steps"
1033
+
1034
+
1035
+ #######################################################################
1036
+ # #
1037
+ # Abstract word path classes #
1038
+ # (all, 2d, 3d, ...) #
1039
+ # #
1040
+ #######################################################################
1041
+
1042
+ class FiniteWordPath_all(SageObject):
1043
+ def _repr_(self) -> str:
1044
+ r"""
1045
+ Return a string representation of this path.
1046
+
1047
+ EXAMPLES::
1048
+
1049
+ sage: F = WordPaths('ab',[(1,0,0,0),(0,1,0,0)]); F
1050
+ Word Paths over 2 steps
1051
+ sage: f = F('ababab')
1052
+ sage: f._repr_()
1053
+ 'Path: ababab'
1054
+ """
1055
+ return "Path: %s" % self.string_rep()
1056
+
1057
+ def points(self, include_last=True):
1058
+ r"""
1059
+ Return an iterator yielding a list of points used to draw the path
1060
+ represented by this word.
1061
+
1062
+ INPUT:
1063
+
1064
+ - ``include_last`` -- boolean (default: ``True``); whether to include the
1065
+ last point
1066
+
1067
+ EXAMPLES:
1068
+
1069
+ A simple closed square::
1070
+
1071
+ sage: P = WordPaths('abAB')
1072
+ sage: list(P('abAB').points())
1073
+ [(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]
1074
+
1075
+ A simple closed square without the last point::
1076
+
1077
+ sage: list(P('abAB').points(include_last=False))
1078
+ [(0, 0), (1, 0), (1, 1), (0, 1)]
1079
+
1080
+ ::
1081
+
1082
+ sage: list(P('abaB').points())
1083
+ [(0, 0), (1, 0), (1, 1), (2, 1), (2, 0)]
1084
+ """
1085
+ curpt = self.start_point()
1086
+ yield curpt
1087
+ end = len(self) if include_last else -1
1088
+ for l in self[:end]:
1089
+ curpt += self.parent().letters_to_steps()[l]
1090
+ yield curpt
1091
+
1092
+ def start_point(self):
1093
+ r"""
1094
+ Return the starting point of ``self``.
1095
+
1096
+ OUTPUT: vector
1097
+
1098
+ EXAMPLES::
1099
+
1100
+ sage: # needs sage.rings.number_field
1101
+ sage: WordPaths('abcdef')('abcdef').start_point()
1102
+ (0, 0)
1103
+ sage: WordPaths('abcdef', steps='cube_grid')('abcdef').start_point()
1104
+ (0, 0, 0)
1105
+ sage: P = WordPaths('ab', steps=[(1,0,0,0),(0,1,0,0)])
1106
+ sage: P('abbba').start_point()
1107
+ (0, 0, 0, 0)
1108
+ """
1109
+ return self.parent().vector_space()(0)
1110
+
1111
+ @cached_method
1112
+ def end_point(self):
1113
+ r"""
1114
+ Return the end point of the path.
1115
+
1116
+ EXAMPLES::
1117
+
1118
+ sage: # needs sage.rings.number_field
1119
+ sage: WordPaths('abcdef')('abababab').end_point()
1120
+ (6, 2*sqrt3)
1121
+ sage: WordPaths('abAB')('abababab').end_point()
1122
+ (4, 4)
1123
+ sage: P = WordPaths('abcABC', steps='cube_grid')
1124
+ sage: P('ababababCC').end_point()
1125
+ (4, 4, -2)
1126
+ sage: WordPaths('abcdef')('abcdef').end_point()
1127
+ (0, 0)
1128
+ sage: P = WordPaths('abc', steps=[(1,3,7,9),(-4,1,0,0),(0,32,1,8)])
1129
+ sage: P('abcabababacaacccbbcac').end_point()
1130
+ (-16, 254, 63, 128)
1131
+ """
1132
+ last = None
1133
+ for pt in self.points():
1134
+ last = pt
1135
+ return last
1136
+
1137
+ def directive_vector(self):
1138
+ r"""
1139
+ Return the directive vector of ``self``.
1140
+
1141
+ The directive vector is the vector starting at the start point
1142
+ and ending at the end point of the path ``self``.
1143
+
1144
+ EXAMPLES::
1145
+
1146
+ sage: # needs sage.rings.number_field
1147
+ sage: WordPaths('abcdef')('abababab').directive_vector()
1148
+ (6, 2*sqrt3)
1149
+ sage: WordPaths('abAB')('abababab').directive_vector()
1150
+ (4, 4)
1151
+ sage: P = WordPaths('abcABC', steps='cube_grid')
1152
+ sage: P('ababababCC').directive_vector()
1153
+ (4, 4, -2)
1154
+ sage: WordPaths('abcdef')('abcdef').directive_vector()
1155
+ (0, 0)
1156
+ sage: P = WordPaths('abc', steps=[(1,3,7,9),(-4,1,0,0),(0,32,1,8)])
1157
+ sage: P('abcabababacaacccbbcac').directive_vector()
1158
+ (-16, 254, 63, 128)
1159
+ """
1160
+ return self.end_point() - self.start_point()
1161
+
1162
+ def is_closed(self) -> bool:
1163
+ r"""
1164
+ Return ``True`` if the path is closed.
1165
+
1166
+ A path is closed if the origin and the end of
1167
+ the path are equal.
1168
+
1169
+ EXAMPLES::
1170
+
1171
+ sage: P = WordPaths('abcd', steps=[(1,0),(0,1),(-1,0),(0,-1)])
1172
+ sage: P('abcd').is_closed()
1173
+ True
1174
+ sage: P('abc').is_closed()
1175
+ False
1176
+ sage: P().is_closed()
1177
+ True
1178
+ sage: P('aacacc').is_closed()
1179
+ True
1180
+ """
1181
+ return self.start_point() == self.end_point()
1182
+
1183
+ def is_simple(self) -> bool:
1184
+ r"""
1185
+ Return ``True`` if the path is simple.
1186
+
1187
+ A path is simple if all its points are
1188
+ distinct.
1189
+
1190
+ If the path is closed, the last point is not considered.
1191
+
1192
+ EXAMPLES::
1193
+
1194
+ sage: # needs sage.rings.number_field
1195
+ sage: P = WordPaths('abcdef', steps='triangle_grid'); P
1196
+ Word Paths on the triangle grid
1197
+ sage: P('abc').is_simple()
1198
+ True
1199
+ sage: P('abcde').is_simple()
1200
+ True
1201
+ sage: P('abcdef').is_simple()
1202
+ True
1203
+ sage: P('ad').is_simple()
1204
+ True
1205
+ sage: P('aabdee').is_simple()
1206
+ False
1207
+ """
1208
+ n = 0
1209
+ s = set()
1210
+ include_last = not self.is_closed()
1211
+ for p in self.points(include_last=include_last):
1212
+ # We need the elements to have a common parent,
1213
+ # so we convert the points to immutable vectors.
1214
+ v = vector(p)
1215
+ v.set_immutable()
1216
+ s.add(v)
1217
+ n += 1
1218
+ if len(s) != n:
1219
+ return False
1220
+ return True
1221
+
1222
+ def tikz_trajectory(self) -> str:
1223
+ r"""
1224
+ Return the trajectory of ``self`` as a ``tikz`` string.
1225
+
1226
+ EXAMPLES::
1227
+
1228
+ sage: # needs sage.rings.number_field
1229
+ sage: P = WordPaths('abcdef')
1230
+ sage: p = P('abcde')
1231
+ sage: p.tikz_trajectory()
1232
+ '(0.000, 0.000) -- (1.00, 0.000) -- (1.50, 0.866) -- (1.00, 1.73) -- (0.000, 1.73) -- (-0.500, 0.866)'
1233
+ """
1234
+ from sage.misc.functional import N as n
1235
+ l = (str(tuple(n(x, digits=3) for x in pt)) for pt in self.points())
1236
+ return ' -- '.join(l)
1237
+
1238
+ def projected_point_iterator(self, v=None, ring=None):
1239
+ r"""
1240
+ Return an iterator of the projection of the orbit points of the
1241
+ path into the space orthogonal to the given vector.
1242
+
1243
+ INPUT:
1244
+
1245
+ - ``v`` -- vector (default: ``None``); if ``None``, the directive
1246
+ vector (i.e. the end point minus starting point) of the path is
1247
+ considered
1248
+
1249
+ - ``ring`` -- ring (default: ``None``); where to do the
1250
+ computations. If ``None``, RealField(53) is used.
1251
+
1252
+ OUTPUT: iterator of points
1253
+
1254
+ EXAMPLES:
1255
+
1256
+ Projected points of the Rauzy fractal::
1257
+
1258
+ sage: # needs sage.rings.number_field
1259
+ sage: s = WordMorphism('1->12,2->13,3->1')
1260
+ sage: D = s.fixed_point('1')
1261
+ sage: v = s.pisot_eigenvector_right()
1262
+ sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
1263
+ sage: w = P(D[:200])
1264
+ sage: it = w.projected_point_iterator(v)
1265
+ sage: for i in range(6): next(it)
1266
+ (0.000000000000000, 0.000000000000000)
1267
+ (-0.526233343362516, 0.000000000000000)
1268
+ (0.220830337618112, -0.477656250512816)
1269
+ (-0.305403005744404, -0.477656250512816)
1270
+ (0.100767309386062, 0.400890564600664)
1271
+ (-0.425466033976454, 0.400890564600664)
1272
+
1273
+ Projected points of a 2d path::
1274
+
1275
+ sage: P = WordPaths('ab','ne')
1276
+ sage: p = P('aabbabbab')
1277
+ sage: it = p.projected_point_iterator(ring=RealField(20))
1278
+ sage: for i in range(8): next(it)
1279
+ (0.00000)
1280
+ (0.78087)
1281
+ (1.5617)
1282
+ (0.93704)
1283
+ (0.31235)
1284
+ (1.0932)
1285
+ (0.46852)
1286
+ (-0.15617)
1287
+ """
1288
+ if v is None:
1289
+ v = self.directive_vector()
1290
+ if ring is None:
1291
+ ring = RR
1292
+ R = vector_on_axis_rotation_matrix(v, 0, ring=ring)[1:]
1293
+ for q in self.points():
1294
+ yield R * q
1295
+
1296
+ def plot_projection(self, v=None, letters=None, color=None, ring=None,
1297
+ size=12, kind='right'):
1298
+ r"""
1299
+ Return an image of the projection of the successive points of the
1300
+ path into the space orthogonal to the given vector.
1301
+
1302
+ INPUT:
1303
+
1304
+ - ``self`` -- a word path in a 3 or 4 dimension vector space
1305
+
1306
+ - ``v`` -- vector (default: ``None``); if ``None``, the directive
1307
+ vector (i.e. the end point minus starting point) of the path is
1308
+ considered.
1309
+
1310
+ - ``letters`` -- iterable (default: ``None``); of the letters
1311
+ to be projected. If ``None``, then all the letters are considered.
1312
+
1313
+ - ``color`` -- dictionary (default: ``None``); of the letters
1314
+ mapped to colors. If ``None``, automatic colors are chosen.
1315
+
1316
+ - ``ring`` -- ring (default: ``None``); where to do the
1317
+ computations. If ``None``, RealField(53) is used.
1318
+
1319
+ - ``size`` -- number (default: ``12``); size of the points
1320
+
1321
+ - ``kind`` -- string (default: ``'right'``); either
1322
+ ``'right'`` or ``'left'``. The color of a letter is given to the
1323
+ projected prefix to the right or the left of the letter.
1324
+
1325
+ OUTPUT: 2d or 3d Graphic object
1326
+
1327
+ EXAMPLES:
1328
+
1329
+ The Rauzy fractal::
1330
+
1331
+ sage: # needs sage.rings.number_field
1332
+ sage: s = WordMorphism('1->12,2->13,3->1')
1333
+ sage: D = s.fixed_point('1')
1334
+ sage: v = s.pisot_eigenvector_right()
1335
+ sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
1336
+ sage: w = P(D[:200])
1337
+ sage: w.plot_projection(v) # long time (2s)
1338
+ Graphics object consisting of 200 graphics primitives
1339
+
1340
+ In this case, the abelianized vector doesn't give a good
1341
+ projection::
1342
+
1343
+ sage: w.plot_projection() # long time (2s) # needs sage.rings.number_field
1344
+ Graphics object consisting of 200 graphics primitives
1345
+
1346
+ You can project only the letters you want::
1347
+
1348
+ sage: w.plot_projection(v, letters='12') # long time (2s) # needs sage.rings.number_field
1349
+ Graphics object consisting of 168 graphics primitives
1350
+
1351
+ You can increase or decrease the precision of the computations by
1352
+ changing the ring of the projection matrix::
1353
+
1354
+ sage: w.plot_projection(v, ring=RealField(20)) # long time (2s) # needs sage.rings.number_field
1355
+ Graphics object consisting of 200 graphics primitives
1356
+
1357
+ You can change the size of the points::
1358
+
1359
+ sage: w.plot_projection(v, size=30) # long time (2s) # needs sage.rings.number_field
1360
+ Graphics object consisting of 200 graphics primitives
1361
+
1362
+ You can assign the color of a letter to the projected prefix to the
1363
+ right or the left of the letter::
1364
+
1365
+ sage: w.plot_projection(v, kind='left') # long time (2s) # needs sage.rings.number_field
1366
+ Graphics object consisting of 200 graphics primitives
1367
+
1368
+ To remove the axis, do like this::
1369
+
1370
+ sage: # needs sage.rings.number_field
1371
+ sage: r = w.plot_projection(v) # needs sage.plot
1372
+ sage: r.axes(False) # needs sage.plot
1373
+ sage: r # long time (2s) # needs sage.plot
1374
+ Graphics object consisting of 200 graphics primitives
1375
+
1376
+ You can assign different colors to each letter::
1377
+
1378
+ sage: # needs sage.rings.number_field
1379
+ sage: color = {'1': 'purple', '2': (.2,.3,.4), '3': 'magenta'}
1380
+ sage: w.plot_projection(v, color=color) # long time (2s) # needs sage.plot
1381
+ Graphics object consisting of 200 graphics primitives
1382
+
1383
+ The 3d-Rauzy fractal::
1384
+
1385
+ sage: # needs sage.rings.number_field
1386
+ sage: s = WordMorphism('1->12,2->13,3->14,4->1')
1387
+ sage: D = s.fixed_point('1')
1388
+ sage: v = s.pisot_eigenvector_right()
1389
+ sage: P = WordPaths('1234',[(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)])
1390
+ sage: w = P(D[:200])
1391
+ sage: w.plot_projection(v) # needs sage.plot
1392
+ Graphics3d Object
1393
+
1394
+ The dimension of vector space of the parent must be 3 or 4::
1395
+
1396
+ sage: # needs sage.rings.number_field
1397
+ sage: P = WordPaths('ab', [(1, 0), (0, 1)])
1398
+ sage: p = P('aabbabbab')
1399
+ sage: p.plot_projection() # needs sage.plot
1400
+ Traceback (most recent call last):
1401
+ ...
1402
+ TypeError: The dimension of the vector space (=2) must be 3 or 4
1403
+ """
1404
+ dimension = self.parent().vector_space().dimension()
1405
+ if dimension not in (3, 4):
1406
+ msg = "The dimension of the vector space (=%s) must be 3 or 4" % dimension
1407
+ raise TypeError(msg)
1408
+ if letters is None:
1409
+ letters = self.parent().alphabet()
1410
+ if color is None:
1411
+ from sage.plot.all import hue
1412
+ A = self.parent().alphabet()
1413
+ color = {a: hue(A.rank(a) / float(A.cardinality())) for a in A}
1414
+ it = self.projected_point_iterator(v, ring=ring)
1415
+ if kind == 'right':
1416
+ next(it)
1417
+ elif kind != 'left':
1418
+ raise ValueError('unknown value for kind (=%s)' % kind)
1419
+ tout = [point([c], color=color[a], size=size)
1420
+ for a, c in zip(self, it) if a in letters]
1421
+ return sum(tout)
1422
+
1423
+ def projected_path(self, v=None, ring=None):
1424
+ r"""
1425
+ Return the path projected into the space orthogonal to the given
1426
+ vector.
1427
+
1428
+ INPUT:
1429
+
1430
+ - ``v`` -- vector (default: ``None``); if ``None``, the directive
1431
+ vector (i.e. the end point minus starting point) of the path is
1432
+ considered.
1433
+
1434
+ - ``ring`` -- ring (default: ``None``); where to do the
1435
+ computations. If ``None``, RealField(53) is used.
1436
+
1437
+ OUTPUT: word path
1438
+
1439
+ EXAMPLES:
1440
+
1441
+ The projected path of the tribonacci word::
1442
+
1443
+ sage: # needs sage.rings.number_field
1444
+ sage: s = WordMorphism('1->12,2->13,3->1')
1445
+ sage: D = s.fixed_point('1')
1446
+ sage: v = s.pisot_eigenvector_right()
1447
+ sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
1448
+ sage: w = P(D[:1000])
1449
+ sage: p = w.projected_path(v)
1450
+ sage: p
1451
+ Path: 1213121121312121312112131213121121312121...
1452
+ sage: p[:20].plot() # needs sage.plot
1453
+ Graphics object consisting of 3 graphics primitives
1454
+
1455
+ The ``ring`` argument allows to change the precision of the
1456
+ projected steps::
1457
+
1458
+ sage: # needs sage.rings.number_field
1459
+ sage: p = w.projected_path(v, RealField(10))
1460
+ sage: p
1461
+ Path: 1213121121312121312112131213121121312121...
1462
+ sage: p.parent().letters_to_steps()
1463
+ {'1': (-0.53, 0.00), '2': (0.75, -0.48), '3': (0.41, 0.88)}
1464
+ """
1465
+ if v is None:
1466
+ v = self.directive_vector()
1467
+ if ring is None:
1468
+ ring = RR
1469
+ R = vector_on_axis_rotation_matrix(v, 0, ring=ring)[1:]
1470
+ d = self.parent().letters_to_steps()
1471
+ A = self.parent().alphabet()
1472
+ nvvectors = [R * d[a] for a in A]
1473
+ projected_parent = WordPaths(A, nvvectors)
1474
+ return projected_parent(self)
1475
+
1476
+ def is_tangent(self):
1477
+ r"""
1478
+ The is_tangent() method, which is implemented for words, has
1479
+ an extended meaning for word paths, which is not implemented yet.
1480
+
1481
+ TESTS::
1482
+
1483
+ sage: WordPaths('ab')('abbab').is_tangent()
1484
+ Traceback (most recent call last):
1485
+ ...
1486
+ NotImplementedError
1487
+
1488
+ AUTHOR:
1489
+
1490
+ - Thierry Monteil
1491
+ """
1492
+ raise NotImplementedError
1493
+
1494
+
1495
+ class FiniteWordPath_2d(FiniteWordPath_all):
1496
+ def plot(self, pathoptions={"rgbcolor": 'red', "thickness": 3},
1497
+ fill=True, filloptions={"rgbcolor": 'red', "alpha": 0.2},
1498
+ startpoint=True, startoptions={"rgbcolor": 'red', "pointsize": 100},
1499
+ endarrow=True, arrowoptions={"rgbcolor": 'red', "arrowsize": 20, "width": 3},
1500
+ gridlines=False, gridoptions={}):
1501
+ r"""
1502
+ Return a 2d Graphics illustrating the path.
1503
+
1504
+ INPUT:
1505
+
1506
+ - ``pathoptions`` -- (dict,
1507
+ default:dict(rgbcolor='red',thickness=3)), options for the
1508
+ path drawing
1509
+
1510
+ - ``fill`` -- boolean (default: ``True``); if fill is ``True`` and if
1511
+ the path is closed, the inside is colored
1512
+
1513
+ - ``filloptions`` -- (dict,
1514
+ default:dict(rgbcolor='red',alpha=0.2)), options for the
1515
+ inside filling
1516
+
1517
+ - ``startpoint`` -- boolean (default: ``True``); draw the start point?
1518
+
1519
+ - ``startoptions`` -- (dict,
1520
+ default:dict(rgbcolor='red',pointsize=100)) options for the
1521
+ start point drawing
1522
+
1523
+ - ``endarrow`` -- boolean (default: ``True``); draw an arrow end at the end?
1524
+
1525
+ - ``arrowoptions`` -- (dict,
1526
+ default:dict(rgbcolor='red',arrowsize=20, width=3)) options
1527
+ for the end point arrow
1528
+
1529
+ - ``gridlines`` -- boolean (default: ``False``); show gridlines?
1530
+
1531
+ - ``gridoptions`` -- (dict, default: {}), options for the gridlines
1532
+
1533
+ EXAMPLES:
1534
+
1535
+ A non closed path on the square grid::
1536
+
1537
+ sage: P = WordPaths('abAB')
1538
+ sage: P('abababAABAB').plot() # needs sage.plot
1539
+ Graphics object consisting of 3 graphics primitives
1540
+
1541
+ A closed path on the square grid::
1542
+
1543
+ sage: P('abababAABABB').plot() # needs sage.plot
1544
+ Graphics object consisting of 4 graphics primitives
1545
+
1546
+ A Dyck path::
1547
+
1548
+ sage: P = WordPaths('()', steps='dyck')
1549
+ sage: P('()()()((()))').plot() # needs sage.plot
1550
+ Graphics object consisting of 3 graphics primitives
1551
+
1552
+ A path in the triangle grid::
1553
+
1554
+ sage: # needs sage.rings.number_field
1555
+ sage: P = WordPaths('abcdef', steps='triangle_grid')
1556
+ sage: P('abcdedededefab').plot() # needs sage.plot
1557
+ Graphics object consisting of 3 graphics primitives
1558
+
1559
+ A polygon of length 220 that tiles the plane in two ways::
1560
+
1561
+ sage: P = WordPaths('abAB')
1562
+ sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() # needs sage.plot
1563
+ Graphics object consisting of 4 graphics primitives
1564
+
1565
+ With gridlines::
1566
+
1567
+ sage: P('ababababab').plot(gridlines=True) # needs sage.plot
1568
+
1569
+ TESTS::
1570
+
1571
+ sage: P = WordPaths('abAB')
1572
+ sage: P().plot() # needs sage.plot
1573
+ Graphics object consisting of 3 graphics primitives
1574
+ sage: sum(map(plot,map(P,['a','A','b','B']))) # needs sage.plot
1575
+ Graphics object consisting of 12 graphics primitives
1576
+ """
1577
+ G = Graphics()
1578
+ pts = list(self.points())
1579
+
1580
+ ####################
1581
+ ####################
1582
+ # FIXME Bug: plot needs float for coordinates
1583
+ ####################
1584
+ ####################
1585
+ pts = [[RR(i) for i in x] for x in pts]
1586
+
1587
+ # Inside
1588
+ if fill and self.is_closed():
1589
+ G += polygon(pts, **filloptions)
1590
+
1591
+ # Startpoint
1592
+ if startpoint:
1593
+ G += point(pts[0], **startoptions)
1594
+
1595
+ # The path itself
1596
+ if endarrow and not self.is_empty():
1597
+ G += line(pts[:-1], **pathoptions)
1598
+ G += arrow(pts[-2], pts[-1], **arrowoptions)
1599
+ else:
1600
+ G += line(pts, **pathoptions)
1601
+
1602
+ G.axes(False)
1603
+ G.set_aspect_ratio(1)
1604
+
1605
+ # gridlines
1606
+ # ############## BUG ##############
1607
+ # Gridlines doesn't work fine.
1608
+ # It should be gridlines="integers"
1609
+ # ############## BUG ##############
1610
+ if gridlines:
1611
+ G = G.show(gridlines=True, **gridoptions)
1612
+
1613
+ return G
1614
+
1615
+ def animate(self):
1616
+ r"""
1617
+ Return an animation object illustrating the path growing step by step.
1618
+
1619
+ EXAMPLES::
1620
+
1621
+ sage: P = WordPaths('abAB')
1622
+ sage: p = P('aaababbb')
1623
+ sage: a = p.animate(); print(a) # needs sage.plot
1624
+ Animation with 9 frames
1625
+ sage: show(a) # long time, optional - imagemagick, needs sage.plot
1626
+ sage: show(a, delay=35, iterations=3) # long time, optional - imagemagick, needs sage.plot
1627
+
1628
+ ::
1629
+
1630
+ sage: # needs sage.rings.number_field
1631
+ sage: P = WordPaths('abcdef', steps='triangle')
1632
+ sage: p = P('abcdef')
1633
+ sage: a = p.animate(); print(a) # needs sage.plot
1634
+ Animation with 8 frames
1635
+ sage: show(a) # long time, optional - imagemagick, needs sage.plot
1636
+
1637
+ If the path is closed, the plain polygon is added at the end of the
1638
+ animation::
1639
+
1640
+ sage: P = WordPaths('abAB')
1641
+ sage: p = P('ababAbABABaB')
1642
+ sage: a = p.animate(); print(a) # needs sage.plot
1643
+ Animation with 14 frames
1644
+ sage: show(a) # long time, optional - imagemagick, needs sage.plot
1645
+
1646
+ Another example illustrating a Fibonacci tile::
1647
+
1648
+ sage: w = words.fibonacci_tile(2)
1649
+ sage: a = w.animate(); print(a) # needs sage.plot
1650
+ Animation with 54 frames
1651
+ sage: show(a) # long time, optional - imagemagick, needs sage.plot
1652
+
1653
+ The first 4 Fibonacci tiles in an animation::
1654
+
1655
+ sage: # needs sage.plot
1656
+ sage: a = words.fibonacci_tile(0).animate()
1657
+ sage: b = words.fibonacci_tile(1).animate()
1658
+ sage: c = words.fibonacci_tile(2).animate()
1659
+ sage: d = words.fibonacci_tile(3).animate()
1660
+ sage: print(a*b*c*d)
1661
+ Animation with 296 frames
1662
+ sage: show(a*b*c*d) # long time, optional - imagemagick
1663
+
1664
+ .. NOTE::
1665
+
1666
+ If ImageMagick is not installed, you will get an error
1667
+ message like this::
1668
+
1669
+ convert: not found
1670
+
1671
+ Error: ImageMagick does not appear to be installed. Saving an
1672
+ animation to a GIF file or displaying an animation requires
1673
+ ImageMagick, so please install it and try again.
1674
+
1675
+ See www.imagemagick.org, for example.
1676
+ """
1677
+ from sage.plot.all import line, polygon, animate
1678
+
1679
+ pts = list(self.points())
1680
+
1681
+ ####################
1682
+ ####################
1683
+ # Bug: plot needs float for coordinates
1684
+ ####################
1685
+ ####################
1686
+ pts = [[RR(i) for i in x] for x in pts]
1687
+
1688
+ images = [line(pts[:i]) for i in range(1, len(pts) + 1)]
1689
+
1690
+ if self.is_closed():
1691
+ images.append(polygon(pts))
1692
+
1693
+ # Get the window of the last image
1694
+ last_image = images[-1]
1695
+ kwds = {}
1696
+ kwds['xmin'] = last_image.xmin()
1697
+ kwds['xmax'] = last_image.xmax()
1698
+ kwds['ymin'] = last_image.ymin()
1699
+ kwds['ymax'] = last_image.ymax()
1700
+ kwds['aspect_ratio'] = 1
1701
+ kwds['axes'] = False
1702
+
1703
+ return animate(images, **kwds)
1704
+
1705
+ def plot_directive_vector(self, options={"rgbcolor": 'blue'}):
1706
+ r"""
1707
+ Return an arrow 2d graphics that goes from the start of the path
1708
+ to the end.
1709
+
1710
+ INPUT:
1711
+
1712
+ - ``options`` -- dictionary, default: {'rgbcolor': 'blue'} graphic
1713
+ options for the arrow
1714
+
1715
+ If the start is the same as the end, a single point is returned.
1716
+
1717
+ EXAMPLES::
1718
+
1719
+ sage: P = WordPaths('abcd'); P
1720
+ Word Paths on the square grid
1721
+ sage: p = P('aaaccaccacacacaccccccbbdd'); p
1722
+ Path: aaaccaccacacacaccccccbbdd
1723
+ sage: R = p.plot() + p.plot_directive_vector() # needs sage.plot
1724
+ sage: R.axes(False) # needs sage.plot
1725
+ sage: R.set_aspect_ratio(1) # needs sage.plot
1726
+ sage: R.plot() # needs sage.plot
1727
+ Graphics object consisting of 4 graphics primitives
1728
+
1729
+ TESTS:
1730
+
1731
+ A closed path::
1732
+
1733
+ sage: P('acbd').plot_directive_vector() # needs sage.plot
1734
+ Graphics object consisting of 1 graphics primitive
1735
+ """
1736
+ start = self.start_point()
1737
+ end = self.end_point()
1738
+ if (start == end):
1739
+ G = point(start, pointsize=10, **options)
1740
+ else:
1741
+ G = arrow(start, end, **options)
1742
+ G.axes(False)
1743
+ G.set_aspect_ratio(1)
1744
+ return G
1745
+
1746
+ def area(self):
1747
+ r"""
1748
+ Return the area of a closed path.
1749
+
1750
+ INPUT:
1751
+
1752
+ - ``self`` -- a closed path
1753
+
1754
+ EXAMPLES::
1755
+
1756
+ sage: P = WordPaths('abcd',steps=[(1,1),(-1,1),(-1,-1),(1,-1)])
1757
+ sage: p = P('abcd')
1758
+ sage: p.area() #todo: not implemented
1759
+ 2
1760
+ """
1761
+ if not self.is_closed():
1762
+ raise TypeError("the path must be closed to compute its area")
1763
+ return NotImplemented
1764
+
1765
+ def height(self):
1766
+ r"""
1767
+ Return the height of ``self``.
1768
+
1769
+ The height of a `2d`-path is merely the difference
1770
+ between the highest and the lowest `y`-coordinate of each
1771
+ points traced by it.
1772
+
1773
+ OUTPUT: nonnegative real number
1774
+
1775
+ EXAMPLES::
1776
+
1777
+ sage: Freeman = WordPaths('abAB')
1778
+ sage: Freeman('aababaabbbAA').height()
1779
+ 5
1780
+
1781
+ The function is well-defined if ``self`` is not simple or close::
1782
+
1783
+ sage: Freeman('aabAAB').height()
1784
+ 1
1785
+ sage: Freeman('abbABa').height()
1786
+ 2
1787
+
1788
+ This works for any `2d`-paths::
1789
+
1790
+ sage: Paths = WordPaths('ab', steps=[(1,0),(1,1)])
1791
+ sage: p = Paths('abbaa')
1792
+ sage: p.height()
1793
+ 2
1794
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1795
+ sage: p = DyckPaths('abaabb')
1796
+ sage: p.height()
1797
+ 2
1798
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1799
+ sage: w.height() # needs sage.rings.number_field
1800
+ 2.59807621135332
1801
+ """
1802
+ return self.ymax() - self.ymin()
1803
+
1804
+ def height_vector(self):
1805
+ r"""
1806
+ Return the height at each point.
1807
+
1808
+ EXAMPLES::
1809
+
1810
+ sage: Paths = WordPaths('ab', steps=[(1,0),(0,1)])
1811
+ sage: p = Paths('abbba')
1812
+ sage: p.height_vector()
1813
+ [0, 0, 1, 2, 3, 3]
1814
+ """
1815
+ h_vec = []
1816
+ y_min = None
1817
+ y_max = None
1818
+ for _, y in self.points():
1819
+ if y_min is None:
1820
+ y_min = y
1821
+ y_max = y
1822
+ else:
1823
+ y_max = max(y, y_max)
1824
+ y_min = min(y, y_min)
1825
+ h_vec.append(y_max - y_min)
1826
+ return h_vec
1827
+
1828
+ def width(self):
1829
+ r"""
1830
+ Return the width of ``self``.
1831
+
1832
+ The height of a `2d`-path is merely the difference
1833
+ between the rightmost and the leftmost `x`-coordinate of each
1834
+ points traced by it.
1835
+
1836
+ OUTPUT: nonnegative real number
1837
+
1838
+ EXAMPLES::
1839
+
1840
+ sage: Freeman = WordPaths('abAB')
1841
+ sage: Freeman('aababaabbbAA').width()
1842
+ 5
1843
+
1844
+ The function is well-defined if ``self`` is not simple or close::
1845
+
1846
+ sage: Freeman('aabAAB').width()
1847
+ 2
1848
+ sage: Freeman('abbABa').width()
1849
+ 1
1850
+
1851
+ This works for any `2d`-paths::
1852
+
1853
+ sage: Paths = WordPaths('ab', steps=[(1,0),(1,1)])
1854
+ sage: p = Paths('abbaa')
1855
+ sage: p.width()
1856
+ 5
1857
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1858
+ sage: p = DyckPaths('abaabb')
1859
+ sage: p.width()
1860
+ 6
1861
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1862
+ sage: w.width() # needs sage.rings.number_field
1863
+ 4.50000000000000
1864
+ """
1865
+ return self.xmax() - self.xmin()
1866
+
1867
+ def width_vector(self):
1868
+ r"""
1869
+ Return the width at each point.
1870
+
1871
+ EXAMPLES::
1872
+
1873
+ sage: Paths = WordPaths('ab', steps=[(1,0),(0,1)])
1874
+ sage: p = Paths('abbba')
1875
+ sage: p.width_vector()
1876
+ [0, 1, 1, 1, 1, 2]
1877
+ """
1878
+ w_vec = []
1879
+ x_min = None
1880
+ x_max = None
1881
+ for x, _ in self.points():
1882
+ if x_min is None:
1883
+ x_min = x
1884
+ x_max = x
1885
+ else:
1886
+ x_max = max(x, x_max)
1887
+ x_min = min(x, x_min)
1888
+ w_vec.append(x_max - x_min)
1889
+ return w_vec
1890
+
1891
+ def xmin(self):
1892
+ r"""
1893
+ Return the minimum of the x-coordinates of the path.
1894
+
1895
+ EXAMPLES::
1896
+
1897
+ sage: P = WordPaths('0123')
1898
+ sage: p = P('0101013332')
1899
+ sage: p.xmin()
1900
+ 0
1901
+
1902
+ This works for any `2d`-paths::
1903
+
1904
+ sage: Paths = WordPaths('ab', steps=[(1,0),(-1,1)])
1905
+ sage: p = Paths('abbba')
1906
+ sage: p.xmin()
1907
+ -2
1908
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1909
+ sage: p = DyckPaths('abaabb')
1910
+ sage: p.xmin()
1911
+ 0
1912
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1913
+ sage: w.xmin() # needs sage.rings.number_field
1914
+ 0.000000000000000
1915
+ """
1916
+ return min(x for (x, _) in self.points())
1917
+
1918
+ def ymin(self):
1919
+ r"""
1920
+ Return the minimum of the y-coordinates of the path.
1921
+
1922
+ EXAMPLES::
1923
+
1924
+ sage: P = WordPaths('0123')
1925
+ sage: p = P('0101013332')
1926
+ sage: p.ymin()
1927
+ 0
1928
+
1929
+ This works for any `2d`-paths::
1930
+
1931
+ sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
1932
+ sage: p = Paths('ababa')
1933
+ sage: p.ymin()
1934
+ -1
1935
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1936
+ sage: p = DyckPaths('abaabb')
1937
+ sage: p.ymin()
1938
+ 0
1939
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1940
+ sage: w.ymin() # needs sage.rings.number_field
1941
+ 0.000000000000000
1942
+ """
1943
+ return min(y for (_, y) in self.points())
1944
+
1945
+ def xmax(self):
1946
+ r"""
1947
+ Return the maximum of the x-coordinates of the path.
1948
+
1949
+ EXAMPLES::
1950
+
1951
+ sage: P = WordPaths('0123')
1952
+ sage: p = P('0101013332')
1953
+ sage: p.xmax()
1954
+ 3
1955
+
1956
+ This works for any `2d`-paths::
1957
+
1958
+ sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
1959
+ sage: p = Paths('ababa')
1960
+ sage: p.xmax()
1961
+ 1
1962
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1963
+ sage: p = DyckPaths('abaabb')
1964
+ sage: p.xmax()
1965
+ 6
1966
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1967
+ sage: w.xmax() # needs sage.rings.number_field
1968
+ 4.50000000000000
1969
+ """
1970
+ return max(x for (x, _) in self.points())
1971
+
1972
+ def ymax(self):
1973
+ r"""
1974
+ Return the maximum of the y-coordinates of the path.
1975
+
1976
+ EXAMPLES::
1977
+
1978
+ sage: P = WordPaths('0123')
1979
+ sage: p = P('0101013332')
1980
+ sage: p.ymax()
1981
+ 3
1982
+
1983
+ This works for any `2d`-paths::
1984
+
1985
+ sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
1986
+ sage: p = Paths('ababa')
1987
+ sage: p.ymax()
1988
+ 0
1989
+ sage: DyckPaths = WordPaths('ab', steps='dyck')
1990
+ sage: p = DyckPaths('abaabb')
1991
+ sage: p.ymax()
1992
+ 2
1993
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
1994
+ sage: w.ymax() # needs sage.rings.number_field
1995
+ 2.59807621135332
1996
+ """
1997
+ return max(y for (_, y) in self.points())
1998
+
1999
+
2000
+ class FiniteWordPath_3d(FiniteWordPath_all):
2001
+ def plot(self, pathoptions={"rgbcolor": 'red', "arrow_head": True, "thickness": 3},
2002
+ startpoint=True, startoptions={"rgbcolor": 'red', "size": 10}):
2003
+ r"""
2004
+ INPUT:
2005
+
2006
+ - ``pathoptions`` -- (dict, default:dict(rgbcolor='red',arrow_head=True,
2007
+ thickness=3)), options for the path drawing
2008
+
2009
+ - ``startpoint`` -- boolean (default: ``True``); draw the start point?
2010
+
2011
+ - ``startoptions`` -- (dict, default:dict(rgbcolor='red',size=10))
2012
+ options for the start point drawing
2013
+
2014
+ EXAMPLES::
2015
+
2016
+ sage: d = ( vector((1,3,2)), vector((2,-4,5)) )
2017
+ sage: P = WordPaths(alphabet='ab', steps=d); P
2018
+ Word Paths over 2 steps
2019
+ sage: p = P('ababab'); p
2020
+ Path: ababab
2021
+ sage: p.plot() # needs sage.plot
2022
+ Graphics3d Object
2023
+
2024
+ sage: P = WordPaths('abcABC', steps='cube_grid')
2025
+ sage: p = P('abcabcAABBC')
2026
+ sage: p.plot() # needs sage.plot
2027
+ Graphics3d Object
2028
+ """
2029
+ # The following line seems not to work for 3d
2030
+ # G = Graphics()
2031
+ # so we draw to start a small almost invisible point instead:
2032
+ G = point([self.start_point()], size=1)
2033
+ pts = list(self.points())
2034
+ if startpoint:
2035
+ G += point([pts[0]], **startoptions)
2036
+ G += line(pts, **pathoptions)
2037
+ return G
2038
+
2039
+
2040
+ #######################################################################
2041
+ # #
2042
+ # Abstract word path classes #
2043
+ # (square grid, hexagonal grid, etc.) #
2044
+ # #
2045
+ #######################################################################
2046
+
2047
+ class FiniteWordPath_square_grid(FiniteWordPath_2d):
2048
+ def is_closed(self) -> bool:
2049
+ r"""
2050
+ Return whether ``self`` represents a closed path.
2051
+
2052
+ EXAMPLES::
2053
+
2054
+ sage: P = WordPaths('abAB', steps='square_grid')
2055
+ sage: P('aA').is_closed()
2056
+ True
2057
+ sage: P('abAB').is_closed()
2058
+ True
2059
+ sage: P('ababAABB').is_closed()
2060
+ True
2061
+ sage: P('aaabbbAABB').is_closed()
2062
+ False
2063
+ sage: P('ab').is_closed()
2064
+ False
2065
+ """
2066
+ tab = self.abelian_vector()
2067
+ return tab[0] == tab[2] and tab[1] == tab[3]
2068
+
2069
+ def area(self):
2070
+ r"""
2071
+ Return the area of a closed path.
2072
+
2073
+ INPUT:
2074
+
2075
+ - ``self`` -- a closed path
2076
+
2077
+ EXAMPLES::
2078
+
2079
+ sage: P = WordPaths('abAB', steps='square_grid')
2080
+ sage: P('abAB').area()
2081
+ 1
2082
+ sage: P('aabbAABB').area()
2083
+ 4
2084
+ sage: P('aabbABAB').area()
2085
+ 3
2086
+
2087
+ The area of the Fibonacci tiles::
2088
+
2089
+ sage: [words.fibonacci_tile(i).area() for i in range(6)]
2090
+ [1, 5, 29, 169, 985, 5741]
2091
+ sage: [words.dual_fibonacci_tile(i).area() for i in range(6)]
2092
+ [1, 5, 29, 169, 985, 5741]
2093
+ sage: oeis(_)[0] # optional -- internet
2094
+ A001653: Numbers k such that 2*k^2 - 1 is a square.
2095
+ sage: _.first_terms() # optional -- internet
2096
+ (1,
2097
+ 5,
2098
+ 29,
2099
+ 169,
2100
+ 985,
2101
+ 5741,
2102
+ 33461,
2103
+ 195025,
2104
+ 1136689,
2105
+ 6625109,
2106
+ 38613965,
2107
+ 225058681,
2108
+ 1311738121,
2109
+ 7645370045,
2110
+ 44560482149,
2111
+ 259717522849,
2112
+ 1513744654945,
2113
+ 8822750406821,
2114
+ 51422757785981,
2115
+ 299713796309065,
2116
+ 1746860020068409,
2117
+ 10181446324101389,
2118
+ 59341817924539925)
2119
+
2120
+ TESTS::
2121
+
2122
+ sage: P = WordPaths('abAB', steps='square_grid')
2123
+ sage: P('a').area()
2124
+ Traceback (most recent call last):
2125
+ ...
2126
+ TypeError: the path must be closed to compute its area
2127
+ """
2128
+ if not self.is_closed():
2129
+ raise TypeError("the path must be closed to compute its area")
2130
+ return abs(self._area_vh())
2131
+
2132
+ def _area_vh(self, x=0, y=0):
2133
+ r"""
2134
+ Return the area of ``self``, with starting point (x,y).
2135
+
2136
+ This is using VH algorithm.
2137
+
2138
+ INPUT:
2139
+
2140
+ - x, y -- starting point (default: (0, 0))
2141
+
2142
+ EXAMPLES::
2143
+
2144
+ sage: P = WordPaths('abAB', steps='square_grid')
2145
+ sage: P('abAB')._area_vh()
2146
+ -1
2147
+ sage: P('aabbAABB')._area_vh()
2148
+ -4
2149
+ sage: P('aabbABAB')._area_vh()
2150
+ -3
2151
+
2152
+ REFERENCES:
2153
+
2154
+ Annie Lacasse Memoire.
2155
+ """
2156
+ area = 0
2157
+ a, b, A, B = self.parent().alphabet()
2158
+
2159
+ for move in self:
2160
+ if move == b:
2161
+ area -= x
2162
+ y += 1
2163
+ elif move == B:
2164
+ area += x
2165
+ y -= 1
2166
+ elif move == a:
2167
+ area += y
2168
+ x += 1
2169
+ elif move == A:
2170
+ area -= y
2171
+ x -= 1
2172
+ return area // 2
2173
+
2174
+ def is_simple(self) -> bool:
2175
+ r"""
2176
+ Return whether the path is simple.
2177
+
2178
+ A path is simple if all its points are
2179
+ distinct.
2180
+
2181
+ If the path is closed, the last point is not considered.
2182
+
2183
+ .. NOTE::
2184
+
2185
+ The linear algorithm described in the thesis of Xavier Provençal
2186
+ should be implemented here.
2187
+
2188
+ EXAMPLES::
2189
+
2190
+ sage: P = WordPaths('abAB', steps='square_grid')
2191
+ sage: P('abab').is_simple()
2192
+ True
2193
+ sage: P('abAB').is_simple()
2194
+ True
2195
+ sage: P('abA').is_simple()
2196
+ True
2197
+ sage: P('aabABB').is_simple()
2198
+ False
2199
+ sage: P().is_simple()
2200
+ True
2201
+ sage: P('A').is_simple()
2202
+ True
2203
+ sage: P('aA').is_simple()
2204
+ True
2205
+ sage: P('aaA').is_simple()
2206
+ False
2207
+
2208
+ REFERENCES:
2209
+
2210
+ - Provençal, X., *Combinatoires des mots, géometrie discrète et
2211
+ pavages*, Thèse de doctorat en Mathématiques, Montréal, UQAM,
2212
+ septembre 2008, 115 pages.
2213
+ """
2214
+ return super().is_simple()
2215
+
2216
+ def tikz_trajectory(self) -> str:
2217
+ r"""
2218
+ Return the trajectory of ``self`` as a ``tikz`` string.
2219
+
2220
+ EXAMPLES::
2221
+
2222
+ sage: f = words.fibonacci_tile(1)
2223
+ sage: f.tikz_trajectory()
2224
+ '(0, 0) -- (0, -1) -- (-1, -1) -- (-1, -2) -- (0, -2) -- (0, -3) -- (1, -3) -- (1, -2) -- (2, -2) -- (2, -1) -- (1, -1) -- (1, 0) -- (0, 0)'
2225
+ """
2226
+ return ' -- '.join(map(str, self.points()))
2227
+
2228
+
2229
+ class FiniteWordPath_triangle_grid(FiniteWordPath_2d):
2230
+ # Triangle grid paths are implemented with quadratic fields,
2231
+ # and the ordering of such elements is currently problematic:
2232
+ #
2233
+ # sage: Q.<sqrt3> = QuadraticField(3)
2234
+ # sage: sqrt3 > 0
2235
+ # True
2236
+ # sage: 0 < sqrt3
2237
+ # False
2238
+ # sage: max(2*sqrt3, sqrt3/10)
2239
+ # 1/10*sqrt3
2240
+ #
2241
+ # Therefore, the functions xmin(), xmax(), ymin() and ymax() are
2242
+ # redefined here with conversion to RR in order to avoid this problem
2243
+ def xmin(self):
2244
+ r"""
2245
+ Return the minimum of the x-coordinates of the path.
2246
+
2247
+ EXAMPLES::
2248
+
2249
+ sage: # needs sage.rings.number_field
2250
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
2251
+ sage: w.xmin()
2252
+ 0.000000000000000
2253
+ sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
2254
+ sage: w.xmin()
2255
+ -3.00000000000000
2256
+ """
2257
+ return min(RR(x) for (x, _) in self.points())
2258
+
2259
+ def ymin(self):
2260
+ r"""
2261
+ Return the minimum of the y-coordinates of the path.
2262
+
2263
+ EXAMPLES::
2264
+
2265
+ sage: # needs sage.rings.number_field
2266
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
2267
+ sage: w.ymin()
2268
+ 0.000000000000000
2269
+ sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
2270
+ sage: w.ymin()
2271
+ -0.866025403784439
2272
+ """
2273
+ return min(RR(y) for (_, y) in self.points())
2274
+
2275
+ def xmax(self):
2276
+ r"""
2277
+ Return the maximum of the x-coordinates of the path.
2278
+
2279
+ EXAMPLES::
2280
+
2281
+ sage: # needs sage.rings.number_field
2282
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
2283
+ sage: w.xmax()
2284
+ 4.50000000000000
2285
+ sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
2286
+ sage: w.xmax()
2287
+ 4.00000000000000
2288
+ """
2289
+ return max(RR(x) for (x, _) in self.points())
2290
+
2291
+ def ymax(self):
2292
+ r"""
2293
+ Return the maximum of the y-coordinates of the path.
2294
+
2295
+ EXAMPLES::
2296
+
2297
+ sage: # needs sage.rings.number_field
2298
+ sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
2299
+ sage: w.ymax()
2300
+ 2.59807621135332
2301
+ sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
2302
+ sage: w.ymax()
2303
+ 8.66025403784439
2304
+ """
2305
+ return max(RR(y) for (_, y) in self.points())
2306
+
2307
+
2308
+ # TODO: faire une verification du mot pour etre sur hexagonal grid
2309
+ class FiniteWordPath_hexagonal_grid(FiniteWordPath_triangle_grid):
2310
+ def __init__(self, parent, *args, **kwds):
2311
+ r"""
2312
+ INPUT:
2313
+
2314
+ - ``parent`` -- a parent object inheriting from Words_all
2315
+ that has the alphabet attribute defined
2316
+
2317
+ - ``*args``, ``**kwds`` -- arguments accepted by AbstractWord
2318
+
2319
+ EXAMPLES::
2320
+
2321
+ sage: # needs sage.rings.number_field
2322
+ sage: F = WordPaths('abcdef', steps='hexagon'); F
2323
+ Word Paths on the hexagonal grid
2324
+ sage: f = F('aaabbbccddef'); f
2325
+ Path: aaabbbccddef
2326
+
2327
+ ::
2328
+
2329
+ sage: f == loads(dumps(f)) # needs sage.rings.number_field
2330
+ True
2331
+ """
2332
+ super().__init__(parent, *args, **kwds)
2333
+
2334
+
2335
+ class FiniteWordPath_cube_grid(FiniteWordPath_3d):
2336
+ pass
2337
+
2338
+
2339
+ class FiniteWordPath_north_east(FiniteWordPath_2d):
2340
+ pass
2341
+
2342
+
2343
+ class FiniteWordPath_dyck(FiniteWordPath_2d):
2344
+ pass
2345
+
2346
+
2347
+ #######################################################################
2348
+ # #
2349
+ # Concrete word path classes #
2350
+ # #
2351
+ # It would be nice if those were created inline... #
2352
+ # We must ask if Nicolas Thiery was able to convince Sage #
2353
+ # people about this. #
2354
+ # #
2355
+ #######################################################################
2356
+
2357
+ # #### Finite paths ####
2358
+
2359
+ class FiniteWordPath_all_list(WordDatatype_list, FiniteWordPath_all, FiniteWord_class):
2360
+ r"""
2361
+ TESTS::
2362
+
2363
+ sage: P = WordPaths(['a','b'],[(1,2,0,0),(3,4,0,0)])
2364
+ sage: p = P(['a','b','a']);p
2365
+ Path: aba
2366
+ sage: type(p)
2367
+ <class 'sage.combinat.words.paths.FiniteWordPath_all_list'>
2368
+ sage: p == loads(dumps(p))
2369
+ True
2370
+ """
2371
+ pass
2372
+
2373
+
2374
+ class FiniteWordPath_all_str(WordDatatype_str, FiniteWordPath_all, FiniteWord_class):
2375
+ r"""
2376
+ TESTS::
2377
+
2378
+ sage: P = WordPaths('ab',[(1,2,0,0),(3,4,0,0)])
2379
+ sage: p = P('aabbb'); p
2380
+ Path: aabbb
2381
+ sage: type(p)
2382
+ <class 'sage.combinat.words.paths.FiniteWordPath_all_str'>
2383
+ sage: p == loads(dumps(p))
2384
+ True
2385
+ """
2386
+ pass
2387
+
2388
+
2389
+ class FiniteWordPath_all_tuple(WordDatatype_tuple, FiniteWordPath_all, FiniteWord_class):
2390
+ r"""
2391
+ TESTS::
2392
+
2393
+ sage: P = WordPaths('ab',[(1,2,0,0),(3,4,0,0)])
2394
+ sage: p = P( ('a','b','b') ); p
2395
+ Path: abb
2396
+ sage: type(p)
2397
+ <class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
2398
+ sage: p == loads(dumps(p))
2399
+ True
2400
+ """
2401
+ pass
2402
+
2403
+
2404
+ class FiniteWordPath_all_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_all, FiniteWord_class):
2405
+ pass
2406
+
2407
+
2408
+ class FiniteWordPath_all_iter(WordDatatype_iter, FiniteWordPath_all, FiniteWord_class):
2409
+ pass
2410
+
2411
+
2412
+ class FiniteWordPath_all_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_all, FiniteWord_class):
2413
+ pass
2414
+
2415
+
2416
+ class FiniteWordPath_all_callable(WordDatatype_callable, FiniteWordPath_all, FiniteWord_class):
2417
+ pass
2418
+
2419
+
2420
+ # #### Finite paths on 2d ####
2421
+
2422
+ class FiniteWordPath_2d_list(WordDatatype_list, FiniteWordPath_2d, FiniteWord_class):
2423
+ r"""
2424
+ TESTS::
2425
+
2426
+ sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
2427
+ sage: p = P(['a','b','a']);p
2428
+ Path: aba
2429
+ sage: type(p)
2430
+ <class 'sage.combinat.words.paths.FiniteWordPath_2d_list'>
2431
+ sage: p == loads(dumps(p))
2432
+ True
2433
+ """
2434
+ pass
2435
+
2436
+
2437
+ class FiniteWordPath_2d_str(WordDatatype_str, FiniteWordPath_2d, FiniteWord_class):
2438
+ r"""
2439
+ TESTS::
2440
+
2441
+ sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
2442
+ sage: p = P('aba'); p
2443
+ Path: aba
2444
+ sage: type(p)
2445
+ <class 'sage.combinat.words.paths.FiniteWordPath_2d_str'>
2446
+ sage: p == loads(dumps(p))
2447
+ True
2448
+ """
2449
+ pass
2450
+
2451
+
2452
+ class FiniteWordPath_2d_tuple(WordDatatype_tuple, FiniteWordPath_2d, FiniteWord_class):
2453
+ r"""
2454
+ TESTS::
2455
+
2456
+ sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
2457
+ sage: p = P(('a','b','a'));p
2458
+ Path: aba
2459
+ sage: type(p)
2460
+ <class 'sage.combinat.words.paths.FiniteWordPath_2d_tuple'>
2461
+ sage: p == loads(dumps(p))
2462
+ True
2463
+ """
2464
+ pass
2465
+
2466
+
2467
+ class FiniteWordPath_2d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_2d, FiniteWord_class):
2468
+ pass
2469
+
2470
+
2471
+ class FiniteWordPath_2d_iter(WordDatatype_iter, FiniteWordPath_2d, FiniteWord_class):
2472
+ pass
2473
+
2474
+
2475
+ class FiniteWordPath_2d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_2d, FiniteWord_class):
2476
+ pass
2477
+
2478
+
2479
+ class FiniteWordPath_2d_callable(WordDatatype_callable, FiniteWordPath_2d, FiniteWord_class):
2480
+ pass
2481
+
2482
+
2483
+ # #### Finite paths on 3d ####
2484
+
2485
+ class FiniteWordPath_3d_list(WordDatatype_list, FiniteWordPath_3d, FiniteWord_class):
2486
+ r"""
2487
+ TESTS::
2488
+
2489
+ sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
2490
+ sage: p = P(['a','b','a']);p
2491
+ Path: aba
2492
+ sage: type(p)
2493
+ <class 'sage.combinat.words.paths.FiniteWordPath_3d_list'>
2494
+ sage: p == loads(dumps(p))
2495
+ True
2496
+ """
2497
+ pass
2498
+
2499
+
2500
+ class FiniteWordPath_3d_str(WordDatatype_str, FiniteWordPath_3d, FiniteWord_class):
2501
+ r"""
2502
+ TESTS::
2503
+
2504
+ sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
2505
+ sage: p = P('aba'); p
2506
+ Path: aba
2507
+ sage: type(p)
2508
+ <class 'sage.combinat.words.paths.FiniteWordPath_3d_str'>
2509
+ sage: p == loads(dumps(p))
2510
+ True
2511
+ """
2512
+ pass
2513
+
2514
+
2515
+ class FiniteWordPath_3d_tuple(WordDatatype_tuple, FiniteWordPath_3d, FiniteWord_class):
2516
+ r"""
2517
+ TESTS::
2518
+
2519
+ sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
2520
+ sage: p = P(('a','b','a'));p
2521
+ Path: aba
2522
+ sage: type(p)
2523
+ <class 'sage.combinat.words.paths.FiniteWordPath_3d_tuple'>
2524
+ sage: p == loads(dumps(p))
2525
+ True
2526
+ """
2527
+ pass
2528
+
2529
+
2530
+ class FiniteWordPath_3d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_3d, FiniteWord_class):
2531
+ pass
2532
+
2533
+
2534
+ class FiniteWordPath_3d_iter(WordDatatype_iter, FiniteWordPath_3d, FiniteWord_class):
2535
+ pass
2536
+
2537
+
2538
+ class FiniteWordPath_3d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_3d, FiniteWord_class):
2539
+ pass
2540
+
2541
+
2542
+ class FiniteWordPath_3d_callable(WordDatatype_callable, FiniteWordPath_3d, FiniteWord_class):
2543
+ pass
2544
+
2545
+
2546
+ # #### Finite paths on square grid ####
2547
+
2548
+ class FiniteWordPath_square_grid_list(WordDatatype_list, FiniteWordPath_square_grid, FiniteWord_class):
2549
+ r"""
2550
+ TESTS::
2551
+
2552
+ sage: P = WordPaths('abcd', steps='square')
2553
+ sage: p = P(['a','b','b']); p
2554
+ Path: abb
2555
+ sage: type(p)
2556
+ <class 'sage.combinat.words.paths.FiniteWordPath_square_grid_list'>
2557
+ sage: p == loads(dumps(p))
2558
+ True
2559
+ """
2560
+ pass
2561
+
2562
+
2563
+ class FiniteWordPath_square_grid_str(WordDatatype_str, FiniteWordPath_square_grid, FiniteWord_class):
2564
+ r"""
2565
+ TESTS::
2566
+
2567
+ sage: P = WordPaths('abcd', steps='square')
2568
+ sage: p = P('abccc'); p
2569
+ Path: abccc
2570
+ sage: type(p)
2571
+ <class 'sage.combinat.words.paths.FiniteWordPath_square_grid_str'>
2572
+ sage: p == loads(dumps(p))
2573
+ True
2574
+ """
2575
+ pass
2576
+
2577
+
2578
+ class FiniteWordPath_square_grid_tuple(WordDatatype_tuple, FiniteWordPath_square_grid, FiniteWord_class):
2579
+ r"""
2580
+ TESTS::
2581
+
2582
+ sage: P = WordPaths('abcd', steps='square')
2583
+ sage: p = P(('a','b','b')); p
2584
+ Path: abb
2585
+ sage: type(p)
2586
+ <class 'sage.combinat.words.paths.FiniteWordPath_square_grid_tuple'>
2587
+ sage: p == loads(dumps(p))
2588
+ True
2589
+ """
2590
+ pass
2591
+
2592
+
2593
+ class FiniteWordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, FiniteWord_class):
2594
+ pass
2595
+
2596
+
2597
+ class FiniteWordPath_square_grid_iter(WordDatatype_iter, FiniteWordPath_square_grid, FiniteWord_class):
2598
+ pass
2599
+
2600
+
2601
+ class FiniteWordPath_square_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_square_grid, FiniteWord_class):
2602
+ pass
2603
+
2604
+
2605
+ class FiniteWordPath_square_grid_callable(WordDatatype_callable, FiniteWordPath_square_grid, FiniteWord_class):
2606
+ pass
2607
+
2608
+
2609
+ # #### Unknown length paths on square grid (experimental) ####
2610
+
2611
+ # class WordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, Word_class):
2612
+ # pass
2613
+
2614
+ # #### Finite paths on triangle grid ####
2615
+
2616
+ class FiniteWordPath_triangle_grid_list(WordDatatype_list, FiniteWordPath_triangle_grid, FiniteWord_class):
2617
+ r"""
2618
+ TESTS::
2619
+
2620
+ sage: # needs sage.rings.number_field
2621
+ sage: P = WordPaths('abcdef', steps='triangle')
2622
+ sage: p = P(['a','b','b']); p
2623
+ Path: abb
2624
+ sage: type(p)
2625
+ <class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_list'>
2626
+ sage: p == loads(dumps(p))
2627
+ True
2628
+ """
2629
+ pass
2630
+
2631
+
2632
+ class FiniteWordPath_triangle_grid_str(WordDatatype_str, FiniteWordPath_triangle_grid, FiniteWord_class):
2633
+ r"""
2634
+ TESTS::
2635
+
2636
+ sage: # needs sage.rings.number_field
2637
+ sage: P = WordPaths('abcdef', steps='triangle')
2638
+ sage: p = P('abb'); p
2639
+ Path: abb
2640
+ sage: type(p)
2641
+ <class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_str'>
2642
+ sage: p == loads(dumps(p))
2643
+ True
2644
+ """
2645
+ pass
2646
+
2647
+
2648
+ class FiniteWordPath_triangle_grid_tuple(WordDatatype_tuple, FiniteWordPath_triangle_grid, FiniteWord_class):
2649
+ r"""
2650
+ TESTS::
2651
+
2652
+ sage: # needs sage.rings.number_field
2653
+ sage: P = WordPaths('abcdef', steps='triangle')
2654
+ sage: p = P(('a','b','b')); p
2655
+ Path: abb
2656
+ sage: type(p)
2657
+ <class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_tuple'>
2658
+ sage: p == loads(dumps(p))
2659
+ True
2660
+ """
2661
+ pass
2662
+
2663
+
2664
+ class FiniteWordPath_triangle_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class):
2665
+ pass
2666
+
2667
+
2668
+ class FiniteWordPath_triangle_grid_iter(WordDatatype_iter, FiniteWordPath_triangle_grid, FiniteWord_class):
2669
+ pass
2670
+
2671
+
2672
+ class FiniteWordPath_triangle_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class):
2673
+ pass
2674
+
2675
+
2676
+ class FiniteWordPath_triangle_grid_callable(WordDatatype_callable, FiniteWordPath_triangle_grid, FiniteWord_class):
2677
+ pass
2678
+
2679
+
2680
+ # #### Finite paths on hexagonal grid ####
2681
+
2682
+ class FiniteWordPath_hexagonal_grid_list(WordDatatype_list, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2683
+ r"""
2684
+ TESTS::
2685
+
2686
+ sage: # needs sage.rings.number_field
2687
+ sage: P = WordPaths('abcdef', steps='hexagon')
2688
+ sage: p = P(['a','b','b']); p
2689
+ Path: abb
2690
+ sage: type(p)
2691
+ <class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_list'>
2692
+ sage: p == loads(dumps(p))
2693
+ True
2694
+ """
2695
+ pass
2696
+
2697
+
2698
+ class FiniteWordPath_hexagonal_grid_str(WordDatatype_str, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2699
+ r"""
2700
+ TESTS::
2701
+
2702
+ sage: # needs sage.rings.number_field
2703
+ sage: P = WordPaths('abcdef', steps='hexagon')
2704
+ sage: p = P('abb'); p
2705
+ Path: abb
2706
+ sage: type(p)
2707
+ <class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_str'>
2708
+ sage: p == loads(dumps(p))
2709
+ True
2710
+ """
2711
+ pass
2712
+
2713
+
2714
+ class FiniteWordPath_hexagonal_grid_tuple(WordDatatype_tuple, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2715
+ r"""
2716
+ TESTS::
2717
+
2718
+ sage: # needs sage.rings.number_field
2719
+ sage: P = WordPaths('abcdef', steps='hexagon')
2720
+ sage: p = P(('a','b','b')); p
2721
+ Path: abb
2722
+ sage: type(p)
2723
+ <class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_tuple'>
2724
+ sage: p == loads(dumps(p))
2725
+ True
2726
+ """
2727
+ pass
2728
+
2729
+
2730
+ class FiniteWordPath_hexagonal_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2731
+ pass
2732
+
2733
+
2734
+ class FiniteWordPath_hexagonal_grid_iter(WordDatatype_iter, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2735
+ pass
2736
+
2737
+
2738
+ class FiniteWordPath_hexagonal_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2739
+ pass
2740
+
2741
+
2742
+ class FiniteWordPath_hexagonal_grid_callable(WordDatatype_callable, FiniteWordPath_hexagonal_grid, FiniteWord_class):
2743
+ pass
2744
+
2745
+
2746
+ # #### Finite paths on cube grid ####
2747
+
2748
+ class FiniteWordPath_cube_grid_list(WordDatatype_list, FiniteWordPath_cube_grid, FiniteWord_class):
2749
+ r"""
2750
+ TESTS::
2751
+
2752
+ sage: P = WordPaths('abcdef', steps='cube')
2753
+ sage: p = P(['a','b','b']); p
2754
+ Path: abb
2755
+ sage: type(p)
2756
+ <class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_list'>
2757
+ sage: p == loads(dumps(p))
2758
+ True
2759
+ """
2760
+ pass
2761
+
2762
+
2763
+ class FiniteWordPath_cube_grid_str(WordDatatype_str, FiniteWordPath_cube_grid, FiniteWord_class):
2764
+ r"""
2765
+ TESTS::
2766
+
2767
+ sage: P = WordPaths('abcdef', steps='cube')
2768
+ sage: p = P('abb'); p
2769
+ Path: abb
2770
+ sage: type(p)
2771
+ <class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_str'>
2772
+ sage: p == loads(dumps(p))
2773
+ True
2774
+ """
2775
+ pass
2776
+
2777
+
2778
+ class FiniteWordPath_cube_grid_tuple(WordDatatype_tuple, FiniteWordPath_cube_grid, FiniteWord_class):
2779
+ r"""
2780
+ TESTS::
2781
+
2782
+ sage: P = WordPaths('abcdef', steps='cube')
2783
+ sage: p = P(('a','b','b')); p
2784
+ Path: abb
2785
+ sage: type(p)
2786
+ <class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_tuple'>
2787
+ sage: p == loads(dumps(p))
2788
+ True
2789
+ """
2790
+ pass
2791
+
2792
+
2793
+ class FiniteWordPath_cube_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_cube_grid, FiniteWord_class):
2794
+ pass
2795
+
2796
+
2797
+ class FiniteWordPath_cube_grid_iter(WordDatatype_iter, FiniteWordPath_cube_grid, FiniteWord_class):
2798
+ pass
2799
+
2800
+
2801
+ class FiniteWordPath_cube_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_cube_grid, FiniteWord_class):
2802
+ pass
2803
+
2804
+
2805
+ class FiniteWordPath_cube_grid_callable(WordDatatype_callable, FiniteWordPath_cube_grid, FiniteWord_class):
2806
+ pass
2807
+
2808
+
2809
+ # #### Finite paths on north_east ####
2810
+
2811
+ class FiniteWordPath_north_east_list(WordDatatype_list, FiniteWordPath_north_east, FiniteWord_class):
2812
+ r"""
2813
+ TESTS::
2814
+
2815
+ sage: P = WordPaths('ab', steps='ne')
2816
+ sage: p = P(['a','b','b']); p
2817
+ Path: abb
2818
+ sage: type(p)
2819
+ <class 'sage.combinat.words.paths.FiniteWordPath_north_east_list'>
2820
+ sage: p == loads(dumps(p))
2821
+ True
2822
+ """
2823
+ pass
2824
+
2825
+
2826
+ class FiniteWordPath_north_east_str(WordDatatype_str, FiniteWordPath_north_east, FiniteWord_class):
2827
+ r"""
2828
+ TESTS::
2829
+
2830
+ sage: P = WordPaths('ab', steps='ne')
2831
+ sage: p = P('abb'); p
2832
+ Path: abb
2833
+ sage: type(p)
2834
+ <class 'sage.combinat.words.paths.FiniteWordPath_north_east_str'>
2835
+ sage: p == loads(dumps(p))
2836
+ True
2837
+ """
2838
+ pass
2839
+
2840
+
2841
+ class FiniteWordPath_north_east_tuple(WordDatatype_tuple, FiniteWordPath_north_east, FiniteWord_class):
2842
+ r"""
2843
+ TESTS::
2844
+
2845
+ sage: P = WordPaths('ab', steps='ne')
2846
+ sage: p = P(('a','b','b')); p
2847
+ Path: abb
2848
+ sage: type(p)
2849
+ <class 'sage.combinat.words.paths.FiniteWordPath_north_east_tuple'>
2850
+ sage: p == loads(dumps(p))
2851
+ True
2852
+ """
2853
+ pass
2854
+
2855
+
2856
+ class FiniteWordPath_north_east_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_north_east, FiniteWord_class):
2857
+ pass
2858
+
2859
+
2860
+ class FiniteWordPath_north_east_iter(WordDatatype_iter, FiniteWordPath_north_east, FiniteWord_class):
2861
+ pass
2862
+
2863
+
2864
+ class FiniteWordPath_north_east_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_north_east, FiniteWord_class):
2865
+ pass
2866
+
2867
+
2868
+ class FiniteWordPath_north_east_callable(WordDatatype_callable, FiniteWordPath_north_east, FiniteWord_class):
2869
+ pass
2870
+
2871
+
2872
+ # #### Finite paths on dyck ####
2873
+
2874
+ class FiniteWordPath_dyck_list(WordDatatype_list, FiniteWordPath_dyck, FiniteWord_class):
2875
+ r"""
2876
+ TESTS::
2877
+
2878
+ sage: P = WordPaths('ab', steps='dyck')
2879
+ sage: p = P(['a','b','b']); p
2880
+ Path: abb
2881
+ sage: type(p)
2882
+ <class 'sage.combinat.words.paths.FiniteWordPath_dyck_list'>
2883
+ sage: p == loads(dumps(p))
2884
+ True
2885
+ """
2886
+ pass
2887
+
2888
+
2889
+ class FiniteWordPath_dyck_str(WordDatatype_str, FiniteWordPath_dyck, FiniteWord_class):
2890
+ r"""
2891
+ TESTS::
2892
+
2893
+ sage: P = WordPaths('ab', steps='dyck')
2894
+ sage: p = P('abb'); p
2895
+ Path: abb
2896
+ sage: type(p)
2897
+ <class 'sage.combinat.words.paths.FiniteWordPath_dyck_str'>
2898
+ sage: p == loads(dumps(p))
2899
+ True
2900
+ """
2901
+ pass
2902
+
2903
+
2904
+ class FiniteWordPath_dyck_tuple(WordDatatype_tuple, FiniteWordPath_dyck, FiniteWord_class):
2905
+ r"""
2906
+ TESTS::
2907
+
2908
+ sage: P = WordPaths('ab', steps='dyck')
2909
+ sage: p = P(('a','b','b')); p
2910
+ Path: abb
2911
+ sage: type(p)
2912
+ <class 'sage.combinat.words.paths.FiniteWordPath_dyck_tuple'>
2913
+ sage: p == loads(dumps(p))
2914
+ True
2915
+ """
2916
+ pass
2917
+
2918
+
2919
+ class FiniteWordPath_dyck_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_dyck, FiniteWord_class):
2920
+ pass
2921
+
2922
+
2923
+ class FiniteWordPath_dyck_iter(WordDatatype_iter, FiniteWordPath_dyck, FiniteWord_class):
2924
+ pass
2925
+
2926
+
2927
+ class FiniteWordPath_dyck_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_dyck, FiniteWord_class):
2928
+ pass
2929
+
2930
+
2931
+ class FiniteWordPath_dyck_callable(WordDatatype_callable, FiniteWordPath_dyck, FiniteWord_class):
2932
+ pass