passagemath-combinat 10.6.1__cp312-cp312-musllinux_1_2_aarch64.whl → 10.8.1a1__cp312-cp312-musllinux_1_2_aarch64.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 (221) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. {passagemath_combinat-10.6.1.dist-info → passagemath_combinat-10.8.1a1.dist-info}/METADATA +17 -20
  3. {passagemath_combinat-10.6.1.dist-info → passagemath_combinat-10.8.1a1.dist-info}/RECORD +220 -218
  4. {passagemath_combinat-10.6.1.dist-info → passagemath_combinat-10.8.1a1.dist-info}/WHEEL +1 -1
  5. passagemath_combinat-10.8.1a1.dist-info/top_level.txt +3 -0
  6. sage/algebras/affine_nil_temperley_lieb.py +3 -3
  7. sage/algebras/all.py +0 -1
  8. sage/algebras/askey_wilson.py +1 -1
  9. sage/algebras/associated_graded.py +2 -2
  10. sage/algebras/cellular_basis.py +3 -6
  11. sage/algebras/cluster_algebra.py +2 -3
  12. sage/algebras/down_up_algebra.py +6 -6
  13. sage/algebras/free_algebra.py +3 -32
  14. sage/algebras/free_algebra_element.py +21 -25
  15. sage/algebras/free_algebra_quotient_element.py +9 -38
  16. sage/algebras/free_zinbiel_algebra.py +4 -3
  17. sage/algebras/hall_algebra.py +2 -2
  18. sage/algebras/hecke_algebras/ariki_koike_algebra.py +8 -8
  19. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +2 -2
  20. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +11 -14
  21. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1 -1
  22. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +5 -5
  23. sage/algebras/iwahori_hecke_algebra.py +59 -57
  24. sage/algebras/jordan_algebra.py +97 -89
  25. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +6 -6
  26. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +14 -12
  27. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +6 -6
  28. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +4 -4
  29. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +13 -13
  30. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +8 -6
  31. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +7 -5
  32. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +7 -7
  33. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +6 -5
  34. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +12 -11
  35. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +3 -3
  36. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +3 -3
  37. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +11 -11
  38. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +3 -3
  39. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +8 -7
  40. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +9 -8
  41. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +6 -5
  42. sage/algebras/nil_coxeter_algebra.py +4 -4
  43. sage/algebras/q_commuting_polynomials.py +6 -6
  44. sage/algebras/q_system.py +3 -3
  45. sage/algebras/quantum_clifford.py +8 -8
  46. sage/algebras/quantum_groups/fock_space.py +48 -8
  47. sage/algebras/quantum_groups/quantum_group_gap.py +5 -7
  48. sage/algebras/quantum_matrix_coordinate_algebra.py +7 -7
  49. sage/algebras/quantum_oscillator.py +3 -3
  50. sage/algebras/quaternion_algebra_element.py +5 -3
  51. sage/algebras/schur_algebra.py +3 -3
  52. sage/algebras/shuffle_algebra.py +5 -8
  53. sage/algebras/splitting_algebra.py +129 -85
  54. sage/algebras/tensor_algebra.py +7 -7
  55. sage/algebras/yangian.py +16 -15
  56. sage/algebras/yokonuma_hecke_algebra.py +13 -11
  57. sage/combinat/all.py +9 -0
  58. sage/combinat/all__sagemath_combinat.py +1 -0
  59. sage/combinat/alternating_sign_matrix.py +36 -29
  60. sage/combinat/baxter_permutations.py +32 -12
  61. sage/combinat/bijectionist.py +13 -17
  62. sage/combinat/chas/fsym.py +6 -6
  63. sage/combinat/chas/wqsym.py +23 -29
  64. sage/combinat/colored_permutations.py +9 -11
  65. sage/combinat/colored_permutations_representations.py +13 -12
  66. sage/combinat/composition_tableau.py +2 -2
  67. sage/combinat/constellation.py +57 -30
  68. sage/combinat/crystals/affine_factorization.py +5 -4
  69. sage/combinat/crystals/alcove_path.py +2 -2
  70. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +3 -2
  71. sage/combinat/crystals/infinity_crystals.py +18 -18
  72. sage/combinat/crystals/kac_modules.py +1 -1
  73. sage/combinat/crystals/kirillov_reshetikhin.py +2 -2
  74. sage/combinat/crystals/letters.cpython-312-aarch64-linux-musl.so +0 -0
  75. sage/combinat/crystals/littelmann_path.py +1 -1
  76. sage/combinat/crystals/pbw_datum.cpython-312-aarch64-linux-musl.so +0 -0
  77. sage/combinat/crystals/pbw_datum.pyx +3 -2
  78. sage/combinat/crystals/spins.cpython-312-aarch64-linux-musl.so +0 -0
  79. sage/combinat/crystals/tensor_product.py +7 -5
  80. sage/combinat/crystals/tensor_product_element.cpython-312-aarch64-linux-musl.so +0 -0
  81. sage/combinat/debruijn_sequence.cpython-312-aarch64-linux-musl.so +0 -0
  82. sage/combinat/debruijn_sequence.pyx +1 -2
  83. sage/combinat/degree_sequences.cpython-312-aarch64-linux-musl.so +0 -0
  84. sage/combinat/degree_sequences.pyx +241 -188
  85. sage/combinat/derangements.py +28 -22
  86. sage/combinat/diagram_algebras.py +12 -14
  87. sage/combinat/dyck_word.py +15 -14
  88. sage/combinat/e_one_star.py +1 -1
  89. sage/combinat/expnums.cpython-312-aarch64-linux-musl.so +0 -0
  90. sage/combinat/fast_vector_partitions.cpython-312-aarch64-linux-musl.so +0 -0
  91. sage/combinat/fqsym.py +13 -19
  92. sage/combinat/free_dendriform_algebra.py +2 -2
  93. sage/combinat/free_prelie_algebra.py +2 -2
  94. sage/combinat/fully_commutative_elements.py +8 -8
  95. sage/combinat/fully_packed_loop.py +9 -9
  96. sage/combinat/gelfand_tsetlin_patterns.py +4 -5
  97. sage/combinat/gray_codes.py +3 -4
  98. sage/combinat/grossman_larson_algebras.py +2 -2
  99. sage/combinat/growth.py +13 -13
  100. sage/combinat/hall_polynomial.py +1 -1
  101. sage/combinat/hillman_grassl.py +1 -1
  102. sage/combinat/integer_matrices.py +5 -7
  103. sage/combinat/k_tableau.py +8 -7
  104. sage/combinat/kazhdan_lusztig.py +3 -3
  105. sage/combinat/key_polynomial.py +845 -298
  106. sage/combinat/knutson_tao_puzzles.py +11 -13
  107. sage/combinat/matrices/hadamard_matrix.py +1 -1
  108. sage/combinat/matrices/latin.py +75 -92
  109. sage/combinat/misc.py +3 -3
  110. sage/combinat/multiset_partition_into_sets_ordered.py +27 -10
  111. sage/combinat/ncsf_qsym/generic_basis_code.py +5 -5
  112. sage/combinat/ncsf_qsym/ncsf.py +6 -5
  113. sage/combinat/ncsf_qsym/qsym.py +9 -17
  114. sage/combinat/ncsym/ncsym.py +8 -12
  115. sage/combinat/nu_dyck_word.py +1 -1
  116. sage/combinat/parallelogram_polyomino.py +3 -5
  117. sage/combinat/parking_functions.py +6 -5
  118. sage/combinat/partition_algebra.py +22 -57
  119. sage/combinat/partition_kleshchev.py +4 -4
  120. sage/combinat/partition_tuple.py +12 -10
  121. sage/combinat/plane_partition.py +10 -13
  122. sage/combinat/positive_integer_semigroup_test.py +17 -0
  123. sage/combinat/q_bernoulli.cpython-312-aarch64-linux-musl.so +0 -0
  124. sage/combinat/quickref.py +2 -2
  125. sage/combinat/recognizable_series.py +2 -2
  126. sage/combinat/regular_sequence.py +7 -7
  127. sage/combinat/regular_sequence_bounded.py +15 -21
  128. sage/combinat/restricted_growth.py +3 -3
  129. sage/combinat/ribbon.py +3 -3
  130. sage/combinat/rigged_configurations/bijection.py +3 -3
  131. sage/combinat/rigged_configurations/rigged_partition.cpython-312-aarch64-linux-musl.so +0 -0
  132. sage/combinat/rsk.py +2 -0
  133. sage/combinat/schubert_polynomial.py +11 -2
  134. sage/combinat/set_partition.py +3 -7
  135. sage/combinat/set_partition_iterator.cpython-312-aarch64-linux-musl.so +0 -0
  136. sage/combinat/set_partition_iterator.pyx +0 -1
  137. sage/combinat/set_partition_ordered.py +2 -2
  138. sage/combinat/sf/classical.py +1 -1
  139. sage/combinat/sf/dual.py +4 -8
  140. sage/combinat/sf/elementary.py +13 -7
  141. sage/combinat/sf/hall_littlewood.py +10 -8
  142. sage/combinat/sf/homogeneous.py +6 -3
  143. sage/combinat/sf/jack.py +11 -9
  144. sage/combinat/sf/llt.py +4 -5
  145. sage/combinat/sf/macdonald.py +10 -11
  146. sage/combinat/sf/monomial.py +6 -0
  147. sage/combinat/sf/ns_macdonald.py +92 -51
  148. sage/combinat/sf/powersum.py +9 -14
  149. sage/combinat/sf/schur.py +6 -0
  150. sage/combinat/sf/sf.py +21 -19
  151. sage/combinat/sf/sfa.py +13 -64
  152. sage/combinat/shifted_primed_tableau.py +5 -7
  153. sage/combinat/shuffle.py +1 -1
  154. sage/combinat/sine_gordon.py +18 -38
  155. sage/combinat/skew_partition.py +9 -12
  156. sage/combinat/skew_tableau.py +2 -7
  157. sage/combinat/sloane_functions.py +1 -1
  158. sage/combinat/species/all.py +67 -2
  159. sage/combinat/species/characteristic_species.py +3 -0
  160. sage/combinat/species/composition_species.py +3 -0
  161. sage/combinat/species/cycle_species.py +4 -0
  162. sage/combinat/species/empty_species.py +3 -0
  163. sage/combinat/species/functorial_composition_species.py +3 -0
  164. sage/combinat/species/generating_series.py +3 -0
  165. sage/combinat/species/library.py +3 -0
  166. sage/combinat/species/linear_order_species.py +3 -0
  167. sage/combinat/species/partition_species.py +3 -0
  168. sage/combinat/species/permutation_species.py +4 -0
  169. sage/combinat/species/product_species.py +3 -0
  170. sage/combinat/species/recursive_species.py +3 -0
  171. sage/combinat/species/set_species.py +3 -0
  172. sage/combinat/species/species.py +13 -7
  173. sage/combinat/species/structure.py +8 -9
  174. sage/combinat/species/subset_species.py +3 -0
  175. sage/combinat/species/sum_species.py +3 -0
  176. sage/combinat/subword.py +4 -1
  177. sage/combinat/subword_complex.py +7 -7
  178. sage/combinat/subword_complex_c.cpython-312-aarch64-linux-musl.so +0 -0
  179. sage/combinat/superpartition.py +1 -1
  180. sage/combinat/symmetric_group_algebra.py +9 -9
  181. sage/combinat/symmetric_group_representations.py +5 -5
  182. sage/combinat/t_sequences.py +4 -4
  183. sage/combinat/tableau.py +3 -4
  184. sage/combinat/tableau_tuple.py +2 -2
  185. sage/combinat/tiling.py +39 -42
  186. sage/combinat/triangles_FHM.py +38 -15
  187. sage/combinat/tutorial.py +2 -2
  188. sage/combinat/vector_partition.py +43 -31
  189. sage/combinat/words/abstract_word.py +4 -4
  190. sage/combinat/words/alphabet.py +12 -12
  191. sage/combinat/words/finite_word.py +25 -229
  192. sage/combinat/words/infinite_word.py +1 -1
  193. sage/combinat/words/morphic.py +13 -13
  194. sage/combinat/words/morphism.py +3 -12
  195. sage/combinat/words/paths.py +16 -17
  196. sage/combinat/words/word.py +60 -35
  197. sage/combinat/words/word_char.cpython-312-aarch64-linux-musl.so +0 -0
  198. sage/combinat/words/word_char.pyx +46 -7
  199. sage/combinat/words/word_datatypes.cpython-312-aarch64-linux-musl.so +0 -0
  200. sage/combinat/words/word_generators.py +39 -38
  201. sage/databases/findstat.py +72 -31
  202. sage/databases/oeis.py +125 -25
  203. sage/databases/sloane.py +14 -8
  204. sage/games/sudoku_backtrack.cpython-312-aarch64-linux-musl.so +0 -0
  205. sage/groups/indexed_free_group.py +3 -4
  206. sage/libs/symmetrica/symmetrica.cpython-312-aarch64-linux-musl.so +0 -0
  207. sage/libs/symmetrica/symmetrica.pxi +1 -0
  208. sage/monoids/automatic_semigroup.py +1 -3
  209. sage/monoids/free_abelian_monoid.py +7 -33
  210. sage/monoids/free_abelian_monoid_element.cpython-312-aarch64-linux-musl.so +0 -0
  211. sage/monoids/free_monoid.py +8 -40
  212. sage/monoids/free_monoid_element.py +1 -9
  213. sage/monoids/string_monoid.py +5 -2
  214. sage/monoids/string_monoid_element.py +12 -66
  215. sage/rings/all__sagemath_combinat.py +7 -0
  216. sage/sat/solvers/__init__.py +3 -4
  217. sage/sat/solvers/cryptominisat.py +2 -3
  218. sage/sat/solvers/picosat.py +2 -3
  219. sage/sat/solvers/sat_lp.py +2 -2
  220. sage/sat/solvers/satsolver.cpython-312-aarch64-linux-musl.so +0 -0
  221. passagemath_combinat-10.6.1.dist-info/top_level.txt +0 -2
@@ -9,7 +9,7 @@ AUTHORS:
9
9
  - Sébastien Labbé
10
10
  - Franco Saliola
11
11
  """
12
- #*****************************************************************************
12
+ # ***************************************************************************
13
13
  # Copyright (C) 2008 Arnaud Bergeron <abergeron@gmail.com>,
14
14
  # Amy Glen <amy.glen@gmail.com>,
15
15
  # Sébastien Labbé <slabqc@gmail.com>,
@@ -19,21 +19,21 @@ AUTHORS:
19
19
  # it under the terms of the GNU General Public License as published by
20
20
  # the Free Software Foundation, either version 2 of the License, or
21
21
  # (at your option) any later version.
22
- # http://www.gnu.org/licenses/
23
- #*****************************************************************************
22
+ # https://www.gnu.org/licenses/
23
+ # ***************************************************************************
24
24
  from sage.misc.lazy_import import lazy_import
25
25
  from sage.combinat.words.word_char import WordDatatype_char
26
26
  from sage.combinat.words.abstract_word import Word_class
27
27
  from sage.combinat.words.finite_word import FiniteWord_class
28
28
  from sage.combinat.words.infinite_word import InfiniteWord_class
29
29
  from .word_datatypes import (WordDatatype_str,
30
- WordDatatype_list,
31
- WordDatatype_tuple)
30
+ WordDatatype_list,
31
+ WordDatatype_tuple)
32
32
  from .word_infinite_datatypes import (
33
- WordDatatype_iter_with_caching,
34
- WordDatatype_iter,
35
- WordDatatype_callable_with_caching,
36
- WordDatatype_callable)
33
+ WordDatatype_iter_with_caching,
34
+ WordDatatype_iter,
35
+ WordDatatype_callable_with_caching,
36
+ WordDatatype_callable)
37
37
  from .morphic import WordDatatype_morphic
38
38
 
39
39
  lazy_import('sage.monoids.free_monoid_element', 'FreeMonoidElement')
@@ -42,7 +42,8 @@ lazy_import('sage.monoids.free_monoid_element', 'FreeMonoidElement')
42
42
  # Word_class to Word and imbedding Word as its __call__ method.
43
43
 
44
44
 
45
- def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK_data=None):
45
+ def Word(data=None, alphabet=None, length=None, datatype=None,
46
+ caching=True, RSK_data=None):
46
47
  r"""
47
48
  Construct a word.
48
49
 
@@ -192,18 +193,18 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK
192
193
  return data.to_word(alphabet)
193
194
 
194
195
  if RSK_data is not None:
195
- #if a list of a semistandard and a standard tableau or a pair of lists
196
+ # if a list of a semistandard and a standard tableau or a pair of lists
196
197
  from sage.combinat.tableau import Tableau
197
198
  if isinstance(RSK_data, (tuple, list)) and len(RSK_data) == 2 and \
198
- all(isinstance(x, Tableau) for x in RSK_data):
199
+ all(isinstance(x, Tableau) for x in RSK_data):
199
200
  from sage.combinat.rsk import RSK_inverse
200
201
  return RSK_inverse(*RSK_data, output='word')
201
202
  elif isinstance(RSK_data, (tuple, list)) and len(RSK_data) == 2 and \
202
- all(isinstance(x, (list, tuple)) for x in RSK_data):
203
+ all(isinstance(x, (list, tuple)) for x in RSK_data):
203
204
  from sage.combinat.rsk import RSK_inverse
204
- P,Q = map(Tableau, RSK_data)
205
+ P, Q = map(Tableau, RSK_data)
205
206
  return RSK_inverse(P, Q, 'word')
206
- raise ValueError("Invalid input. Must be a pair of tableaux")
207
+ raise ValueError("input must be a pair of tableaux")
207
208
 
208
209
  # Create the parent object
209
210
  from .words import Words
@@ -217,7 +218,7 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK
217
218
  # #
218
219
  #######################################################################
219
220
 
220
- ##### Finite Words #####
221
+ # #### Finite Words ####
221
222
 
222
223
 
223
224
  class FiniteWord_char(WordDatatype_char, FiniteWord_class):
@@ -486,7 +487,7 @@ class FiniteWord_callable(WordDatatype_callable, FiniteWord_class):
486
487
  pass
487
488
 
488
489
 
489
- ##### Infinite Words #####
490
+ # #### Infinite Words ####
490
491
 
491
492
  class InfiniteWord_iter_with_caching(WordDatatype_iter_with_caching, InfiniteWord_class):
492
493
  r"""
@@ -519,10 +520,16 @@ class InfiniteWord_iter_with_caching(WordDatatype_iter_with_caching, InfiniteWor
519
520
 
520
521
  Pickle is not supported for infinite word defined by an iterator::
521
522
 
522
- sage: dumps(w)
523
- Traceback (most recent call last):
524
- ...
525
- TypeError: can...t...pickle...generator...object...
523
+ sage: try:
524
+ ....: dumps(w)
525
+ ....: except TypeError as e:
526
+ ....: if "pickle" in str(e) and "generator" in str(e):
527
+ ....: print("TypeError raised in dumps() as expected")
528
+ ....: except Exception as e:
529
+ ....: print("Unexpected exception raised:", e)
530
+ ....: else:
531
+ ....: print("No exception raised, unexpected")
532
+ TypeError raised in dumps() as expected
526
533
  """
527
534
  pass
528
535
 
@@ -558,10 +565,16 @@ class InfiniteWord_iter(WordDatatype_iter, InfiniteWord_class):
558
565
 
559
566
  Pickle is not supported for infinite word defined by an iterator::
560
567
 
561
- sage: dumps(w)
562
- Traceback (most recent call last):
563
- ...
564
- TypeError: can...t...pickle...generator...object...
568
+ sage: try:
569
+ ....: dumps(w)
570
+ ....: except TypeError as e:
571
+ ....: if "pickle" in str(e) and "generator" in str(e):
572
+ ....: print("TypeError raised in dumps() as expected")
573
+ ....: except Exception as e:
574
+ ....: print("Unexpected exception raised:", e)
575
+ ....: else:
576
+ ....: print("No exception raised, unexpected")
577
+ TypeError raised in dumps() as expected
565
578
  """
566
579
  pass
567
580
 
@@ -629,7 +642,7 @@ class InfiniteWord_callable(WordDatatype_callable, InfiniteWord_class):
629
642
  pass
630
643
 
631
644
 
632
- ##### Words of unknown length #####
645
+ # #### Words of unknown length ####
633
646
 
634
647
  class Word_iter_with_caching(WordDatatype_iter_with_caching, Word_class):
635
648
  r"""
@@ -660,10 +673,16 @@ class Word_iter_with_caching(WordDatatype_iter_with_caching, Word_class):
660
673
 
661
674
  Pickle is not supported for word of unknown length defined by an iterator::
662
675
 
663
- sage: dumps(w)
664
- Traceback (most recent call last):
665
- ...
666
- TypeError: can...t...pickle...generator...object...
676
+ sage: try:
677
+ ....: dumps(w)
678
+ ....: except TypeError as e:
679
+ ....: if "pickle" in str(e) and "generator" in str(e):
680
+ ....: print("TypeError raised in dumps() as expected")
681
+ ....: except Exception as e:
682
+ ....: print("Unexpected exception raised:", e)
683
+ ....: else:
684
+ ....: print("No exception raised, unexpected")
685
+ TypeError raised in dumps() as expected
667
686
  """
668
687
  pass
669
688
 
@@ -697,15 +716,21 @@ class Word_iter(WordDatatype_iter, Word_class):
697
716
 
698
717
  Pickle is not supported for word of unknown length defined by an iterator::
699
718
 
700
- sage: dumps(w)
701
- Traceback (most recent call last):
702
- ...
703
- TypeError: can...t...pickle...generator...object...
719
+ sage: try:
720
+ ....: dumps(w)
721
+ ....: except TypeError as e:
722
+ ....: if "pickle" in str(e) and "generator" in str(e):
723
+ ....: print("TypeError raised in dumps() as expected")
724
+ ....: except Exception as e:
725
+ ....: print("Unexpected exception raised:", e)
726
+ ....: else:
727
+ ....: print("No exception raised, unexpected")
728
+ TypeError raised in dumps() as expected
704
729
  """
705
730
  pass
706
731
 
707
732
 
708
- ##### Morphic Words #####
733
+ # #### Morphic Words ####
709
734
 
710
735
  class FiniteWord_morphic(WordDatatype_morphic, FiniteWord_class):
711
736
  r"""
@@ -444,22 +444,39 @@ cdef class WordDatatype_char(WordDatatype):
444
444
  TESTS:
445
445
 
446
446
  sage: W = Words(IntegerRange(0,255))
447
- sage: W([0,1]) * W([2,0])
447
+ sage: W([0, 1]) * W([2, 0])
448
448
  word: 0120
449
449
 
450
- The result is automatically converted to a WordDatatype_char. Currently we can
451
- even do::
450
+ The result of a concatenation is always a WordDatatype_char. Currently there is no
451
+ check on the resulting parent and concatenation might lead to invalid words::
452
452
 
453
- sage: w = W([0,1,2,3])
454
- sage: w * [4,0,4,0]
455
- word: 01234040
453
+ sage: W = Words([0, 1, 2, 3])
454
+ sage: w = W([0, 1, 2, 3, 2, 1, 0])
455
+ sage: w * [4, 0, 4, 0]
456
+ word: 01232104040
457
+ sage: (w * [4, 0, 4, 0]).parent()
458
+ Finite words over {0, 1, 2, 3}
459
+
460
+ TESTS:
461
+
462
+ Tests for :issue:`40690` and :issue:`41289`::
463
+
464
+ sage: W = Words([0,1])
465
+
466
+ sage: W([0]) + [0]
467
+ word: 00
468
+ sage: [0] + W([0])
469
+ word: 00
470
+
471
+ sage: W([0]) + W([1])**oo
472
+ word: 0111111111111111111111111111111111111111...
456
473
  """
457
474
  cdef WordDatatype_char w
458
475
 
459
476
  if isinstance(other, WordDatatype_char):
460
477
  return (<WordDatatype_char> self)._concatenate(other)
461
478
 
462
- elif PySequence_Check(other):
479
+ elif isinstance(other, (tuple, list)):
463
480
  # we convert other to a WordDatatype_char and perform the concatenation
464
481
  w = (<WordDatatype_char> self)._new_c(NULL, 0, None)
465
482
  w._set_data(other)
@@ -469,6 +486,28 @@ cdef class WordDatatype_char(WordDatatype):
469
486
  from sage.combinat.words.finite_word import FiniteWord_class
470
487
  return FiniteWord_class.concatenate(self, other)
471
488
 
489
+ def __rmul__(self, other):
490
+ r"""
491
+ Return the concatenation ``other * self``.
492
+
493
+ TESTS:
494
+
495
+ sage: W = Words(IntegerRange(0,255))
496
+ sage: [1] * W([0])
497
+ word: 10
498
+ """
499
+ cdef WordDatatype_char w
500
+
501
+ if isinstance(other, (tuple, list)):
502
+ # we convert other to a WordDatatype_char and perform the concatenation
503
+ w = (<WordDatatype_char> self)._new_c(NULL, 0, None)
504
+ w._set_data(other)
505
+ return (<WordDatatype_char> w)._concatenate(self)
506
+
507
+ else:
508
+ from sage.combinat.words.finite_word import FiniteWord_class
509
+ return FiniteWord_class.concatenate(other, self)
510
+
472
511
  def __add__(self, other):
473
512
  r"""
474
513
  Concatenation (alias for ``*``).
@@ -224,7 +224,7 @@ class LowerChristoffelWord(FiniteWord_list):
224
224
  v = u * (cf[i]-1) + v
225
225
  w = u + v
226
226
  else:
227
- raise ValueError('Unknown algorithm (=%s)' % algorithm)
227
+ raise ValueError(f'unknown algorithm (={algorithm})')
228
228
  super().__init__(FiniteWords(alphabet), w)
229
229
  self.__p = p
230
230
  self.__q = q
@@ -250,11 +250,11 @@ class LowerChristoffelWord(FiniteWord_list):
250
250
  True
251
251
  """
252
252
  from sage.matrix.constructor import matrix
253
- eta = {0:matrix(2,[2,1,1,1]), 1:matrix(2,[5,2,2,1])}
254
- M = matrix(2,[1,0,0,1])
253
+ eta = {0: matrix(2, [2, 1, 1, 1]), 1: matrix(2, [5, 2, 2, 1])}
254
+ M = matrix(2, [1, 0, 0, 1])
255
255
  for a in self:
256
256
  M *= eta[a]
257
- return M.trace()/3
257
+ return M.trace() / 3
258
258
 
259
259
  def standard_factorization(self):
260
260
  r"""
@@ -299,8 +299,8 @@ class LowerChristoffelWord(FiniteWord_list):
299
299
  w11 = w1.number_of_letter_occurrences(1)
300
300
  w20 = w2.number_of_letter_occurrences(0)
301
301
  w21 = w2.number_of_letter_occurrences(1)
302
- return Factorization([LowerChristoffelWord(w11,w10),
303
- LowerChristoffelWord(w21,w20)])
302
+ return Factorization([LowerChristoffelWord(w11, w10),
303
+ LowerChristoffelWord(w21, w20)])
304
304
 
305
305
  def __reduce__(self):
306
306
  r"""
@@ -568,27 +568,28 @@ class WordGenerator:
568
568
  alphabet = W.alphabet()
569
569
  if alphabet.cardinality() != 2:
570
570
  raise TypeError("alphabet does not contain two distinct elements")
571
- a,b = alphabet
571
+ a, b = alphabet
572
572
 
573
573
  if construction_method == "recursive":
574
574
  w = W(self._FibonacciWord_RecursiveConstructionIterator(alphabet),
575
575
  datatype='iter')
576
576
  return w
577
577
 
578
- elif construction_method in ("fixed point", "fixed_point"):
579
- d = {b:[a],a:[a,b]}
578
+ if construction_method in ("fixed point", "fixed_point"):
579
+ d = {b: [a], a: [a, b]}
580
580
  w = self.FixedPointOfMorphism(d, a)
581
581
  return w
582
582
 
583
- elif construction_method == "function":
583
+ if construction_method == "function":
584
584
  from sage.functions.other import floor
585
585
  from sage.misc.functional import sqrt
586
- phi = (1 + sqrt(5))/2 # the golden ratio
587
- f = lambda n:a if floor((n+2)*phi) - floor((n+1)*phi) == 2 else b
586
+ phi = (1 + sqrt(5))/2 # the golden ratio
587
+
588
+ def f(n):
589
+ return a if floor((n+2)*phi) - floor((n+1)*phi) == 2 else b
588
590
  return W(f)
589
591
 
590
- else:
591
- raise NotImplementedError
592
+ raise NotImplementedError
592
593
 
593
594
  def _FibonacciWord_RecursiveConstructionIterator(self, alphabet=(0, 1)):
594
595
  r"""
@@ -606,7 +607,7 @@ class WordGenerator:
606
607
  [0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1]
607
608
  """
608
609
  Fib0 = [0]
609
- Fib1 = [0,1]
610
+ Fib1 = [0, 1]
610
611
  n = 0
611
612
  while True:
612
613
  it = iter(Fib1[n:])
@@ -691,9 +692,9 @@ class WordGenerator:
691
692
  if len(set(alphabet)) != 2:
692
693
  raise TypeError("alphabet does not contain two distinct elements")
693
694
  from functools import partial
694
- f = partial(self._CodingOfRotationWord_function,alpha=alpha,beta=beta,x=x,alphabet=alphabet)
695
- w = InfiniteWords(alphabet)(f, datatype='callable')
696
- return w
695
+ f = partial(self._CodingOfRotationWord_function,
696
+ alpha=alpha, beta=beta, x=x, alphabet=alphabet)
697
+ return InfiniteWords(alphabet)(f, datatype='callable')
697
698
 
698
699
  def _CodingOfRotationWord_function(self, n, alpha, beta, x=0, alphabet=(0, 1)):
699
700
  r"""
@@ -897,7 +898,7 @@ class WordGenerator:
897
898
  else:
898
899
  raise TypeError("slope (=%s) must be a real number" % slope +
899
900
  "or an iterable")
900
- w = parent(self._CharacteristicSturmianWord_LetterIterator(cf,alphabet),
901
+ w = parent(self._CharacteristicSturmianWord_LetterIterator(cf, alphabet),
901
902
  datatype='iter')
902
903
  return w
903
904
 
@@ -1383,8 +1384,8 @@ class WordGenerator:
1383
1384
  if alphabet is None:
1384
1385
  alphabet = list(range(m))
1385
1386
  if len(set(alphabet)) != m:
1386
- raise TypeError("alphabet does not contain %s distinct elements" % m)
1387
- return FiniteWords(alphabet)([alphabet[randint(0,m-1)] for i in range(n)])
1387
+ raise TypeError(f"alphabet does not contain {m} distinct elements")
1388
+ return FiniteWords(alphabet)([alphabet[randint(0, m - 1)] for i in range(n)])
1388
1389
 
1389
1390
  LowerChristoffelWord = LowerChristoffelWord
1390
1391
 
@@ -1482,8 +1483,8 @@ class WordGenerator:
1482
1483
  [BmBGL09]_
1483
1484
  """
1484
1485
  from sage.combinat.words.morphism import WordMorphism
1485
- W = FiniteWords([0,1,2,3])
1486
- bar = WordMorphism({0:0,1:3,3:1,2:2},codomain=W)
1486
+ W = FiniteWords([0, 1, 2, 3])
1487
+ bar = WordMorphism({0: 0, 1: 3, 3: 1, 2: 2}, codomain=W)
1487
1488
  if n == 0:
1488
1489
  a = [] if q_0 is None else [q_0]
1489
1490
  return W(a)
@@ -1491,12 +1492,12 @@ class WordGenerator:
1491
1492
  b = [] if q_1 is None else [q_1]
1492
1493
  return W(b)
1493
1494
  elif n % 3 == 2:
1494
- u = self._fibonacci_tile(n-1,q_0,q_1)
1495
- v = self._fibonacci_tile(n-2,q_0,q_1)
1495
+ u = self._fibonacci_tile(n - 1, q_0, q_1)
1496
+ v = self._fibonacci_tile(n - 2, q_0, q_1)
1496
1497
  return u * v
1497
1498
  else:
1498
- u = self._fibonacci_tile(n-1,q_0,q_1)
1499
- v = bar(self._fibonacci_tile(n-2,q_0,q_1))
1499
+ u = self._fibonacci_tile(n - 1, q_0, q_1)
1500
+ v = bar(self._fibonacci_tile(n - 2, q_0, q_1))
1500
1501
  return u * v
1501
1502
 
1502
1503
  def fibonacci_tile(self, n):
@@ -1513,8 +1514,8 @@ class WordGenerator:
1513
1514
  w = self._fibonacci_tile(3*n+1)
1514
1515
  w = w**4
1515
1516
  from sage.combinat.words.paths import WordPaths
1516
- P = WordPaths([0,1,2,3])
1517
- l = list(w.partial_sums(start=3,mod=4))
1517
+ P = WordPaths([0, 1, 2, 3])
1518
+ l = list(w.partial_sums(start=3, mod=4))
1518
1519
  return P(l)[:-1]
1519
1520
 
1520
1521
  def dual_fibonacci_tile(self, n):
@@ -1529,11 +1530,11 @@ class WordGenerator:
1529
1530
  Path: 3212303230103230321232101232123032123210...
1530
1531
  Path: 3212303230103230321232101232123032123210...
1531
1532
  """
1532
- w = self._fibonacci_tile(3*n+1,3,3)
1533
+ w = self._fibonacci_tile(3*n+1, 3, 3)
1533
1534
  w = w**4
1534
1535
  from sage.combinat.words.paths import WordPaths
1535
- P = WordPaths([0,1,2,3])
1536
- l = list(w.partial_sums(start=3,mod=4))
1536
+ P = WordPaths([0, 1, 2, 3])
1537
+ l = list(w.partial_sums(start=3, mod=4))
1537
1538
  return P(l)[:-1]
1538
1539
 
1539
1540
  def _s_adic_iterator(self, sequence, letters):
@@ -1622,17 +1623,17 @@ class WordGenerator:
1622
1623
  - Sébastien Labbé (2009-12-18): initial version
1623
1624
  """
1624
1625
  from itertools import tee
1625
- sequence_it,sequence = tee(sequence)
1626
+ sequence_it, sequence = tee(sequence)
1626
1627
  m = next(sequence_it)
1627
1628
  codomain = m.codomain()
1628
1629
  p = codomain.identity_morphism()
1629
- letters_it,letters = tee(letters)
1630
+ letters_it, letters = tee(letters)
1630
1631
  precedent_letter = m(next(letters_it))[0]
1631
1632
 
1632
1633
  yield precedent_letter
1633
- for (i,(m,a)) in enumerate(zip(sequence, letters)):
1634
+ for (i, (m, a)) in enumerate(zip(sequence, letters)):
1634
1635
  if not precedent_letter == m(a)[0]:
1635
- raise ValueError("the hypothesis of the algorithm used is not satisfied; the image of the %s-th letter (=%s) under the %s-th morphism (=%s) should start with the %s-th letter (=%s)" % (i+1,a,i+1,m,i,precedent_letter))
1636
+ raise ValueError("the hypothesis of the algorithm used is not satisfied; the image of the %s-th letter (=%s) under the %s-th morphism (=%s) should start with the %s-th letter (=%s)" % (i+1, a, i+1, m, i, precedent_letter))
1636
1637
  w = p(m(a)[1:])
1637
1638
  yield from w
1638
1639
  p = p * m
@@ -1881,7 +1882,7 @@ class WordGenerator:
1881
1882
  raise TypeError("morphisms (=%s) must be None, callable or provide a __getitem__ method" % morphisms)
1882
1883
 
1883
1884
  from sage.combinat.words.word import FiniteWord_class
1884
- if isinstance(sequence,(tuple,list,str,FiniteWord_class)) \
1885
+ if isinstance(sequence, (tuple, list, str, FiniteWord_class)) \
1885
1886
  and hasattr(letters, "__len__") and len(letters) == 1:
1886
1887
  from sage.misc.misc_c import prod
1887
1888
  return prod(seq)(letters)
@@ -1895,7 +1896,7 @@ class WordGenerator:
1895
1896
  kwds['data'] = self._s_adic_iterator(seq, letters)
1896
1897
  kwds['datatype'] = 'iter'
1897
1898
  kwds['caching'] = True
1898
- #kwds['check'] = False
1899
+ # kwds['check'] = False
1899
1900
  return W.shift()(**kwds)
1900
1901
 
1901
1902
  def PalindromicDefectWord(self, k=1, alphabet='ab'):