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.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
- passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +44 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,1067 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
Datatypes for finite words
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# Copyright (C) 2009 Franco Saliola <saliola@gmail.com>
|
|
7
|
+
# Vincent Delecroix <20100.delecroix@gmail.com>
|
|
8
|
+
#
|
|
9
|
+
# This program is free software: you can redistribute it and/or modify
|
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
|
11
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
12
|
+
# (at your option) any later version.
|
|
13
|
+
# https://www.gnu.org/licenses/
|
|
14
|
+
# ****************************************************************************
|
|
15
|
+
|
|
16
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
17
|
+
from itertools import islice
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
cdef class WordDatatype():
|
|
21
|
+
r"""
|
|
22
|
+
The generic WordDatatype class.
|
|
23
|
+
|
|
24
|
+
Any word datatype must contain two attributes (at least):
|
|
25
|
+
|
|
26
|
+
- ``_parent``
|
|
27
|
+
- ``_hash``
|
|
28
|
+
|
|
29
|
+
They are automatically defined here and it's not necessary (and forbidden)
|
|
30
|
+
to define them anywhere else.
|
|
31
|
+
|
|
32
|
+
TESTS::
|
|
33
|
+
|
|
34
|
+
sage: w = Word([0,1,1,0,0,1])
|
|
35
|
+
sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype)
|
|
36
|
+
True
|
|
37
|
+
"""
|
|
38
|
+
def __reduce__(self):
|
|
39
|
+
r"""
|
|
40
|
+
Default pickle support.
|
|
41
|
+
|
|
42
|
+
TESTS::
|
|
43
|
+
|
|
44
|
+
sage: w = Word([0,1,1,0,0,1])
|
|
45
|
+
sage: w.__reduce__()
|
|
46
|
+
(Finite words over Set of Python objects of class 'object', ([0, 1, 1, 0, 0, 1],))
|
|
47
|
+
"""
|
|
48
|
+
return self._parent, (list(self),)
|
|
49
|
+
|
|
50
|
+
def __hash__(self):
|
|
51
|
+
r"""
|
|
52
|
+
Return the hash for this word.
|
|
53
|
+
|
|
54
|
+
TESTS::
|
|
55
|
+
|
|
56
|
+
sage: h = hash(Word('abc')) # indirect test
|
|
57
|
+
sage: Word('abc').__hash__() == Word('abc').__hash__()
|
|
58
|
+
True
|
|
59
|
+
|
|
60
|
+
sage: tm = words.ThueMorseWord()
|
|
61
|
+
sage: hash(tm)
|
|
62
|
+
-973965563
|
|
63
|
+
"""
|
|
64
|
+
cdef int res
|
|
65
|
+
if self._hash is None:
|
|
66
|
+
res = 5381
|
|
67
|
+
for s in islice(self, 1024):
|
|
68
|
+
res = ((res << 5) + res) + hash(s)
|
|
69
|
+
self._hash = res
|
|
70
|
+
return self._hash
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
cdef class WordDatatype_list(WordDatatype):
|
|
74
|
+
r"""
|
|
75
|
+
Datatype class for words defined by lists.
|
|
76
|
+
"""
|
|
77
|
+
cdef public list _data
|
|
78
|
+
|
|
79
|
+
def __init__(self, parent=None, data=None):
|
|
80
|
+
r"""
|
|
81
|
+
Construct a word with a given parent.
|
|
82
|
+
|
|
83
|
+
.. NOTE::
|
|
84
|
+
|
|
85
|
+
It is slower than WordDatatype_str and WordDatatype_tuple.
|
|
86
|
+
|
|
87
|
+
INPUT:
|
|
88
|
+
|
|
89
|
+
- ``parent`` -- an instance of :class:`Words_all`
|
|
90
|
+
- ``data`` -- an iterable
|
|
91
|
+
|
|
92
|
+
EXAMPLES::
|
|
93
|
+
|
|
94
|
+
sage: w = Word([0,1,1,0])
|
|
95
|
+
sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype_list)
|
|
96
|
+
True
|
|
97
|
+
"""
|
|
98
|
+
self._parent = parent
|
|
99
|
+
if isinstance(data, list):
|
|
100
|
+
self._data = data
|
|
101
|
+
else:
|
|
102
|
+
self._data = list(data)
|
|
103
|
+
self._hash = None
|
|
104
|
+
|
|
105
|
+
__hash__ = WordDatatype.__hash__
|
|
106
|
+
|
|
107
|
+
def __contains__(self, a):
|
|
108
|
+
r"""
|
|
109
|
+
Test whether ``a`` is a letter of ``self``.
|
|
110
|
+
|
|
111
|
+
INPUT:
|
|
112
|
+
|
|
113
|
+
- ``a`` -- anything
|
|
114
|
+
|
|
115
|
+
OUTPUT: boolean
|
|
116
|
+
|
|
117
|
+
EXAMPLES::
|
|
118
|
+
|
|
119
|
+
sage: w = Word([0,1,1,0])
|
|
120
|
+
sage: 0 in w
|
|
121
|
+
True
|
|
122
|
+
sage: 3 in w
|
|
123
|
+
False
|
|
124
|
+
"""
|
|
125
|
+
return a in self._data
|
|
126
|
+
|
|
127
|
+
def __iter__(self):
|
|
128
|
+
r"""
|
|
129
|
+
Return an iterator that iterates through the letters of ``self``.
|
|
130
|
+
|
|
131
|
+
EXAMPLES::
|
|
132
|
+
|
|
133
|
+
sage: w = Word([0,1,1,0])
|
|
134
|
+
sage: list(iter(w))
|
|
135
|
+
[0, 1, 1, 0]
|
|
136
|
+
"""
|
|
137
|
+
return iter(self._data)
|
|
138
|
+
|
|
139
|
+
def __richcmp__(self, other, int op):
|
|
140
|
+
r"""
|
|
141
|
+
Equality test for ``self`` and ``other`` if other is an instance of
|
|
142
|
+
``WordDatype_list``.
|
|
143
|
+
|
|
144
|
+
INPUT:
|
|
145
|
+
|
|
146
|
+
- ``other`` -- a word
|
|
147
|
+
- ``op`` -- integer; 0, 1, 2, 3, 4 or 5
|
|
148
|
+
|
|
149
|
+
OUTPUT: boolean or NotImplemented
|
|
150
|
+
|
|
151
|
+
EXAMPLES::
|
|
152
|
+
|
|
153
|
+
sage: w = Word(range(10))
|
|
154
|
+
sage: w == w
|
|
155
|
+
True
|
|
156
|
+
sage: z = Word(range(20))
|
|
157
|
+
sage: w == z
|
|
158
|
+
False
|
|
159
|
+
sage: z == w
|
|
160
|
+
False
|
|
161
|
+
|
|
162
|
+
It works even if the parents are not the same::
|
|
163
|
+
|
|
164
|
+
sage: Words([0,1])([0,1,1]) == Words([0,1,2])([0,1,1])
|
|
165
|
+
True
|
|
166
|
+
|
|
167
|
+
REFERENCES:
|
|
168
|
+
|
|
169
|
+
http://docs.cython.org/docs/special_methods.html
|
|
170
|
+
"""
|
|
171
|
+
if isinstance(other, WordDatatype_list):
|
|
172
|
+
if op == Py_EQ:
|
|
173
|
+
return self._data == other._data
|
|
174
|
+
elif op == Py_NE:
|
|
175
|
+
return self._data != other._data
|
|
176
|
+
|
|
177
|
+
# Otherwise, force FiniteWord_class.__richcmp__ to do it
|
|
178
|
+
from sage.combinat.words.word import FiniteWord_class
|
|
179
|
+
return FiniteWord_class.__richcmp__(self, other, op)
|
|
180
|
+
|
|
181
|
+
def __len__(self):
|
|
182
|
+
r"""
|
|
183
|
+
Return the length of the word.
|
|
184
|
+
|
|
185
|
+
.. NOTE::
|
|
186
|
+
|
|
187
|
+
This function will be deprecated in a future version
|
|
188
|
+
of Sage. Use ``self.length()`` instead.
|
|
189
|
+
|
|
190
|
+
EXAMPLES::
|
|
191
|
+
|
|
192
|
+
sage: w = Word([0,1,1,0])
|
|
193
|
+
sage: len(w)
|
|
194
|
+
4
|
|
195
|
+
"""
|
|
196
|
+
return len(self._data)
|
|
197
|
+
|
|
198
|
+
def length(self):
|
|
199
|
+
r"""
|
|
200
|
+
Return the length of the word.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: w = Word([0,1,1,0])
|
|
205
|
+
sage: w.length()
|
|
206
|
+
4
|
|
207
|
+
"""
|
|
208
|
+
return len(self._data)
|
|
209
|
+
|
|
210
|
+
def __getitem__(self, key):
|
|
211
|
+
r"""
|
|
212
|
+
Implement :meth:`__getitem__` for words stored as lists.
|
|
213
|
+
|
|
214
|
+
INPUT:
|
|
215
|
+
|
|
216
|
+
- ``key`` -- integer
|
|
217
|
+
|
|
218
|
+
EXAMPLES::
|
|
219
|
+
|
|
220
|
+
sage: L = list(range(100))
|
|
221
|
+
sage: w = Word(L)
|
|
222
|
+
sage: w[4]
|
|
223
|
+
4
|
|
224
|
+
sage: w[-1]
|
|
225
|
+
99
|
|
226
|
+
sage: w[3:10:2]
|
|
227
|
+
word: 3579
|
|
228
|
+
"""
|
|
229
|
+
if isinstance(key, slice):
|
|
230
|
+
return self._parent(self._data[key])
|
|
231
|
+
else:
|
|
232
|
+
return self._data[key]
|
|
233
|
+
|
|
234
|
+
def __mul__(self, other):
|
|
235
|
+
r"""
|
|
236
|
+
Return the concatenation of ``self`` and ``other``.
|
|
237
|
+
|
|
238
|
+
INPUT:
|
|
239
|
+
|
|
240
|
+
- ``other`` -- word represented by a list
|
|
241
|
+
|
|
242
|
+
OUTPUT: word
|
|
243
|
+
|
|
244
|
+
EXAMPLES::
|
|
245
|
+
|
|
246
|
+
sage: w = Word(list(range(10)))
|
|
247
|
+
sage: w * w
|
|
248
|
+
word: 01234567890123456789
|
|
249
|
+
|
|
250
|
+
The type of the concatenation is preserved::
|
|
251
|
+
|
|
252
|
+
sage: type(w)
|
|
253
|
+
<class 'sage.combinat.words.word.FiniteWord_list'>
|
|
254
|
+
sage: type(w * w)
|
|
255
|
+
<class 'sage.combinat.words.word.FiniteWord_list'>
|
|
256
|
+
"""
|
|
257
|
+
if isinstance(other, WordDatatype_list):
|
|
258
|
+
return self._parent(self._data + other._data)
|
|
259
|
+
else:
|
|
260
|
+
return super().__mul__(other)
|
|
261
|
+
|
|
262
|
+
__add__ = __mul__
|
|
263
|
+
|
|
264
|
+
def number_of_letter_occurrences(self, a):
|
|
265
|
+
r"""
|
|
266
|
+
Return the number of occurrences of the letter ``a`` in the word
|
|
267
|
+
``self``.
|
|
268
|
+
|
|
269
|
+
INPUT:
|
|
270
|
+
|
|
271
|
+
- ``a`` -- a letter
|
|
272
|
+
|
|
273
|
+
OUTPUT: integer
|
|
274
|
+
|
|
275
|
+
EXAMPLES::
|
|
276
|
+
|
|
277
|
+
sage: w = Word([0,1,1,0,1])
|
|
278
|
+
sage: w.number_of_letter_occurrences(0)
|
|
279
|
+
2
|
|
280
|
+
sage: w.number_of_letter_occurrences(1)
|
|
281
|
+
3
|
|
282
|
+
sage: w.number_of_letter_occurrences(2)
|
|
283
|
+
0
|
|
284
|
+
|
|
285
|
+
.. SEEALSO::
|
|
286
|
+
|
|
287
|
+
:meth:`sage.combinat.words.finite_word.FiniteWord_class.number_of_factor_occurrences`
|
|
288
|
+
"""
|
|
289
|
+
return self._data.count(a)
|
|
290
|
+
|
|
291
|
+
cdef class WordDatatype_str(WordDatatype):
|
|
292
|
+
"""
|
|
293
|
+
Datatype for words defined by strings.
|
|
294
|
+
"""
|
|
295
|
+
cdef public str _data
|
|
296
|
+
|
|
297
|
+
# TODO : allow initialization from non string data
|
|
298
|
+
def __init__(self, parent=None, data=None):
|
|
299
|
+
r"""
|
|
300
|
+
Construct a word with parent ``parent`` from the string ``data``.
|
|
301
|
+
|
|
302
|
+
INPUT:
|
|
303
|
+
|
|
304
|
+
- ``parent`` -- instance of :class:`Words_all`
|
|
305
|
+
- ``data`` -- string
|
|
306
|
+
|
|
307
|
+
EXAMPLES::
|
|
308
|
+
|
|
309
|
+
sage: w = Word("abba")
|
|
310
|
+
sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype_str)
|
|
311
|
+
True
|
|
312
|
+
"""
|
|
313
|
+
self._parent = parent
|
|
314
|
+
if isinstance(data, str):
|
|
315
|
+
self._data = data
|
|
316
|
+
else:
|
|
317
|
+
self._data = "".join(str(u) for u in data)
|
|
318
|
+
self._hash = None
|
|
319
|
+
|
|
320
|
+
__hash__ = WordDatatype.__hash__
|
|
321
|
+
|
|
322
|
+
def __iter__(self):
|
|
323
|
+
r"""
|
|
324
|
+
Return an iterator that iterates through the letters of ``self``.
|
|
325
|
+
|
|
326
|
+
EXAMPLES::
|
|
327
|
+
|
|
328
|
+
sage: w = Word('abba')
|
|
329
|
+
sage: list(iter(w))
|
|
330
|
+
['a', 'b', 'b', 'a']
|
|
331
|
+
"""
|
|
332
|
+
return iter(self._data)
|
|
333
|
+
|
|
334
|
+
def __richcmp__(self, other, int op):
|
|
335
|
+
r"""
|
|
336
|
+
Equality test for ``self`` and ``other`` if other is an instance of
|
|
337
|
+
``WordDatype_str``.
|
|
338
|
+
|
|
339
|
+
INPUT:
|
|
340
|
+
|
|
341
|
+
- ``other`` -- a word
|
|
342
|
+
- ``op`` -- integer; 0, 1, 2, 3, 4 or 5
|
|
343
|
+
|
|
344
|
+
OUTPUT: boolean or NotImplemented
|
|
345
|
+
|
|
346
|
+
EXAMPLES::
|
|
347
|
+
|
|
348
|
+
sage: w = Word('abcde')
|
|
349
|
+
sage: w == w
|
|
350
|
+
True
|
|
351
|
+
sage: z = Word('epoisudfafgh')
|
|
352
|
+
sage: w == z
|
|
353
|
+
False
|
|
354
|
+
sage: z == w
|
|
355
|
+
False
|
|
356
|
+
|
|
357
|
+
It works even if the parents are not the same::
|
|
358
|
+
|
|
359
|
+
sage: Words('ab')('ababa') == Words('abcd')('ababa')
|
|
360
|
+
True
|
|
361
|
+
sage: Words('ab')('ababa') == Word('ababa')
|
|
362
|
+
True
|
|
363
|
+
|
|
364
|
+
REFERENCES:
|
|
365
|
+
|
|
366
|
+
http://docs.cython.org/docs/special_methods.html
|
|
367
|
+
"""
|
|
368
|
+
if isinstance(other, WordDatatype_str):
|
|
369
|
+
if op == Py_EQ:
|
|
370
|
+
return self._data == other._data
|
|
371
|
+
elif op == Py_NE:
|
|
372
|
+
return self._data != other._data
|
|
373
|
+
|
|
374
|
+
# Otherwise, force FiniteWord_class.__richcmp__ to do it
|
|
375
|
+
from sage.combinat.words.word import FiniteWord_class
|
|
376
|
+
return FiniteWord_class.__richcmp__(self, other, op)
|
|
377
|
+
|
|
378
|
+
def __contains__(self, a):
|
|
379
|
+
r"""
|
|
380
|
+
Test whether ``a`` is a letter of ``self``.
|
|
381
|
+
|
|
382
|
+
INPUT:
|
|
383
|
+
|
|
384
|
+
- ``a`` -- anything
|
|
385
|
+
|
|
386
|
+
EXAMPLES::
|
|
387
|
+
|
|
388
|
+
sage: w = Word('abba')
|
|
389
|
+
sage: 'a' in w
|
|
390
|
+
True
|
|
391
|
+
sage: 'c' in w
|
|
392
|
+
False
|
|
393
|
+
"""
|
|
394
|
+
# we need to override the non standard behaviour of
|
|
395
|
+
# the __contains__ of python str
|
|
396
|
+
if not isinstance(a, str):
|
|
397
|
+
return False
|
|
398
|
+
if len(a) != 1:
|
|
399
|
+
return False
|
|
400
|
+
else:
|
|
401
|
+
return a in self._data
|
|
402
|
+
|
|
403
|
+
cpdef _has_factor_naive(self, w):
|
|
404
|
+
r"""
|
|
405
|
+
A naive test for testing whether the word contains ``w`` as a factor.
|
|
406
|
+
|
|
407
|
+
.. NOTE::
|
|
408
|
+
|
|
409
|
+
This just wraps Python's builtin :meth:`__contains__` for :class:`str`.
|
|
410
|
+
|
|
411
|
+
INPUT:
|
|
412
|
+
|
|
413
|
+
- ``w`` -- a word, or something that behaves like one (``list``,
|
|
414
|
+
``tuple``, ``str``, ...)
|
|
415
|
+
|
|
416
|
+
OUTPUT: boolean
|
|
417
|
+
|
|
418
|
+
EXAMPLES::
|
|
419
|
+
|
|
420
|
+
sage: w = Word('abba')
|
|
421
|
+
sage: w._has_factor_naive('ba')
|
|
422
|
+
True
|
|
423
|
+
sage: w._has_factor_naive('bab')
|
|
424
|
+
False
|
|
425
|
+
"""
|
|
426
|
+
if isinstance(w, WordDatatype_str):
|
|
427
|
+
return w._data in self._data
|
|
428
|
+
elif isinstance(w, str):
|
|
429
|
+
return w in self._data
|
|
430
|
+
raise ValueError
|
|
431
|
+
|
|
432
|
+
cpdef find(self, sub, start=0, end=None):
|
|
433
|
+
r"""
|
|
434
|
+
Return the index of the first occurrence of sub in self,
|
|
435
|
+
such that sub is contained within self[start:end].
|
|
436
|
+
Returns -1 on failure.
|
|
437
|
+
|
|
438
|
+
INPUT:
|
|
439
|
+
|
|
440
|
+
- ``sub`` -- string or word to search for
|
|
441
|
+
- ``start`` -- nonnegative integer (default: 0) specifying
|
|
442
|
+
the position from which to start the search.
|
|
443
|
+
- ``end`` -- nonnegative integer (default: ``None``); specifying
|
|
444
|
+
the position at which the search must stop. If ``None``, then
|
|
445
|
+
the search is performed up to the end of the string.
|
|
446
|
+
|
|
447
|
+
OUTPUT: nonnegative integer or `-1`
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: w = Word("abbabaabababa")
|
|
452
|
+
sage: w.find("a")
|
|
453
|
+
0
|
|
454
|
+
sage: w.find("a", 4)
|
|
455
|
+
5
|
|
456
|
+
sage: w.find("a", 4, 5)
|
|
457
|
+
-1
|
|
458
|
+
"""
|
|
459
|
+
if end is None:
|
|
460
|
+
end = len(self._data)
|
|
461
|
+
if isinstance(sub, WordDatatype_str):
|
|
462
|
+
return self._data.find(sub._data, start, end)
|
|
463
|
+
elif isinstance(sub, str):
|
|
464
|
+
return self._data.find(sub, start, end)
|
|
465
|
+
else:
|
|
466
|
+
return super().find(sub, start, end)
|
|
467
|
+
|
|
468
|
+
def rfind(self, sub, start=0, end=None):
|
|
469
|
+
r"""
|
|
470
|
+
Return the index of the last occurrence of sub in self,
|
|
471
|
+
such that sub is contained within self[start:end].
|
|
472
|
+
Returns -1 on failure.
|
|
473
|
+
|
|
474
|
+
INPUT:
|
|
475
|
+
|
|
476
|
+
- ``sub`` -- string or word to search for
|
|
477
|
+
- ``start`` -- nonnegative integer (default: 0) specifying
|
|
478
|
+
the position at which the search must stop.
|
|
479
|
+
- ``end`` -- nonnegative integer (default: ``None``); specifying
|
|
480
|
+
the position from which to start the search. If ``None``, then
|
|
481
|
+
the search is performed up to the end of the string.
|
|
482
|
+
|
|
483
|
+
OUTPUT: nonnegative integer or `-1`
|
|
484
|
+
|
|
485
|
+
EXAMPLES::
|
|
486
|
+
|
|
487
|
+
sage: w = Word("abbabaabababa")
|
|
488
|
+
sage: w.rfind("a")
|
|
489
|
+
12
|
|
490
|
+
sage: w.rfind("a", 4, 8)
|
|
491
|
+
6
|
|
492
|
+
sage: w.rfind("a", 4, 5)
|
|
493
|
+
-1
|
|
494
|
+
"""
|
|
495
|
+
if end is None:
|
|
496
|
+
end = len(self._data)
|
|
497
|
+
if isinstance(sub, WordDatatype_str):
|
|
498
|
+
return self._data.rfind(sub._data, start, end)
|
|
499
|
+
elif isinstance(sub, str):
|
|
500
|
+
return self._data.rfind(sub, start, end)
|
|
501
|
+
else:
|
|
502
|
+
return super().rfind(sub, start, end)
|
|
503
|
+
|
|
504
|
+
def __len__(self):
|
|
505
|
+
r"""
|
|
506
|
+
Return the length of the word.
|
|
507
|
+
|
|
508
|
+
.. NOTE::
|
|
509
|
+
|
|
510
|
+
This function will be deprecated in a future version
|
|
511
|
+
of Sage. Use ``self.length()`` instead.
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: w = Word("abbabaabababa")
|
|
516
|
+
sage: len(w)
|
|
517
|
+
13
|
|
518
|
+
"""
|
|
519
|
+
return len(self._data)
|
|
520
|
+
|
|
521
|
+
def length(self):
|
|
522
|
+
r"""
|
|
523
|
+
Return the length of the word.
|
|
524
|
+
|
|
525
|
+
EXAMPLES::
|
|
526
|
+
|
|
527
|
+
sage: w = Word("abbabaabababa")
|
|
528
|
+
sage: w.length()
|
|
529
|
+
13
|
|
530
|
+
"""
|
|
531
|
+
return len(self._data)
|
|
532
|
+
|
|
533
|
+
def __getitem__(self, key):
|
|
534
|
+
r"""
|
|
535
|
+
Implement the :meth:`__getitem__`.
|
|
536
|
+
|
|
537
|
+
TESTS::
|
|
538
|
+
|
|
539
|
+
sage: alphabet = [chr(i) for i in range(97, 123)]
|
|
540
|
+
sage: w = Word(alphabet)
|
|
541
|
+
sage: w[4]
|
|
542
|
+
'e'
|
|
543
|
+
sage: w[-1]
|
|
544
|
+
'z'
|
|
545
|
+
sage: w[3:10:2]
|
|
546
|
+
word: dfhj
|
|
547
|
+
sage: all(chr(i+97) == w[i] for i in range(w.length()))
|
|
548
|
+
True
|
|
549
|
+
"""
|
|
550
|
+
if isinstance(key, slice):
|
|
551
|
+
return self._parent(self._data[key])
|
|
552
|
+
return self._data[key]
|
|
553
|
+
|
|
554
|
+
def __mul__(self, other):
|
|
555
|
+
r"""
|
|
556
|
+
Return the concatenation of ``self`` and ``other``.
|
|
557
|
+
|
|
558
|
+
INPUT:
|
|
559
|
+
|
|
560
|
+
- ``other`` -- word represented by a string
|
|
561
|
+
|
|
562
|
+
OUTPUT: word
|
|
563
|
+
|
|
564
|
+
EXAMPLES::
|
|
565
|
+
|
|
566
|
+
sage: w = Word('abcdef')
|
|
567
|
+
sage: w * w
|
|
568
|
+
word: abcdefabcdef
|
|
569
|
+
|
|
570
|
+
The type of the concatenation is preserved::
|
|
571
|
+
|
|
572
|
+
sage: type(w)
|
|
573
|
+
<class 'sage.combinat.words.word.FiniteWord_str'>
|
|
574
|
+
sage: type(w * w)
|
|
575
|
+
<class 'sage.combinat.words.word.FiniteWord_str'>
|
|
576
|
+
"""
|
|
577
|
+
if isinstance(other, WordDatatype_str):
|
|
578
|
+
return self._parent(self._data + other._data)
|
|
579
|
+
else:
|
|
580
|
+
return super().__mul__(other)
|
|
581
|
+
|
|
582
|
+
__add__ = __mul__
|
|
583
|
+
|
|
584
|
+
def number_of_letter_occurrences(self, letter):
|
|
585
|
+
r"""
|
|
586
|
+
Count the number of occurrences of ``letter``.
|
|
587
|
+
|
|
588
|
+
INPUT:
|
|
589
|
+
|
|
590
|
+
- ``letter`` -- a letter
|
|
591
|
+
|
|
592
|
+
OUTPUT: integer
|
|
593
|
+
|
|
594
|
+
EXAMPLES::
|
|
595
|
+
|
|
596
|
+
sage: w = Word("abbabaabababa")
|
|
597
|
+
sage: w.number_of_letter_occurrences('a')
|
|
598
|
+
7
|
|
599
|
+
sage: w.number_of_letter_occurrences('b')
|
|
600
|
+
6
|
|
601
|
+
sage: w.number_of_letter_occurrences('c')
|
|
602
|
+
0
|
|
603
|
+
|
|
604
|
+
::
|
|
605
|
+
|
|
606
|
+
sage: w.number_of_letter_occurrences('abb')
|
|
607
|
+
0
|
|
608
|
+
|
|
609
|
+
.. SEEALSO::
|
|
610
|
+
|
|
611
|
+
:meth:`sage.combinat.words.finite_word.FiniteWord_class.number_of_factor_occurrences`
|
|
612
|
+
"""
|
|
613
|
+
if len(letter) == 1:
|
|
614
|
+
return self._data.count(letter)
|
|
615
|
+
else:
|
|
616
|
+
return 0
|
|
617
|
+
|
|
618
|
+
def split(self, sep=None, maxsplit=None):
|
|
619
|
+
r"""
|
|
620
|
+
Return a list of words, using sep as a delimiter string.
|
|
621
|
+
If maxsplit is given, at most maxsplit splits are done.
|
|
622
|
+
|
|
623
|
+
See also the partition method.
|
|
624
|
+
|
|
625
|
+
.. NOTE::
|
|
626
|
+
|
|
627
|
+
This just wraps Python's builtin :meth:`str::split` for
|
|
628
|
+
:class:`str`.
|
|
629
|
+
|
|
630
|
+
INPUT:
|
|
631
|
+
|
|
632
|
+
- ``sep`` -- string or word (default: ``None``)
|
|
633
|
+
|
|
634
|
+
- ``maxsplit`` -- positive integer (default: ``None``)
|
|
635
|
+
|
|
636
|
+
OUTPUT: list of words
|
|
637
|
+
|
|
638
|
+
EXAMPLES:
|
|
639
|
+
|
|
640
|
+
You can split along white space to find words in a sentence::
|
|
641
|
+
|
|
642
|
+
sage: w = Word("My tailor is poor")
|
|
643
|
+
sage: w.split(" ")
|
|
644
|
+
[word: My, word: tailor, word: is, word: poor]
|
|
645
|
+
|
|
646
|
+
The python behavior is kept when no argument is given::
|
|
647
|
+
|
|
648
|
+
sage: w.split()
|
|
649
|
+
[word: My, word: tailor, word: is, word: poor]
|
|
650
|
+
|
|
651
|
+
You can split in two words letters to get the length of blocks in the
|
|
652
|
+
other letter::
|
|
653
|
+
|
|
654
|
+
sage: w = Word("ababbabaaba")
|
|
655
|
+
sage: w.split('a')
|
|
656
|
+
[word: , word: b, word: bb, word: b, word: , word: b, word: ]
|
|
657
|
+
sage: w.split('b')
|
|
658
|
+
[word: a, word: a, word: , word: a, word: aa, word: a]
|
|
659
|
+
|
|
660
|
+
You can split along words::
|
|
661
|
+
|
|
662
|
+
sage: w = Word("3230301030323212323032321")
|
|
663
|
+
sage: w.split("32")
|
|
664
|
+
[word: , word: 30301030, word: , word: 12, word: 30, word: , word: 1]
|
|
665
|
+
|
|
666
|
+
If the separator is not a string a :exc:`ValueError` is raised::
|
|
667
|
+
|
|
668
|
+
sage: w = Word("le papa du papa du papa etait un petit pioupiou")
|
|
669
|
+
sage: w.split(Word(['p','a','p','a']))
|
|
670
|
+
Traceback (most recent call last):
|
|
671
|
+
...
|
|
672
|
+
ValueError: the separator must be a string
|
|
673
|
+
"""
|
|
674
|
+
if sep is None or isinstance(sep, str):
|
|
675
|
+
pass
|
|
676
|
+
elif isinstance(sep, WordDatatype_str):
|
|
677
|
+
sep = sep._data
|
|
678
|
+
else:
|
|
679
|
+
raise ValueError("the separator must be a string")
|
|
680
|
+
if maxsplit is None:
|
|
681
|
+
maxsplit = -1
|
|
682
|
+
return [self._parent(z) for z in self._data.split(sep=sep,
|
|
683
|
+
maxsplit=maxsplit)]
|
|
684
|
+
|
|
685
|
+
def partition(self, sep):
|
|
686
|
+
r"""
|
|
687
|
+
Search for the separator sep in S, and return the part before it,
|
|
688
|
+
the separator itself, and the part after it. The concatenation of
|
|
689
|
+
the terms in the list gives back the initial word.
|
|
690
|
+
|
|
691
|
+
See also the split method.
|
|
692
|
+
|
|
693
|
+
.. NOTE::
|
|
694
|
+
|
|
695
|
+
This just wraps Python's builtin :meth:`str::partition` for
|
|
696
|
+
:class:`str`.
|
|
697
|
+
|
|
698
|
+
INPUT:
|
|
699
|
+
|
|
700
|
+
- ``sep`` -- string or word
|
|
701
|
+
|
|
702
|
+
EXAMPLES::
|
|
703
|
+
|
|
704
|
+
sage: w = Word("MyTailorIsPoor")
|
|
705
|
+
sage: w.partition("Tailor")
|
|
706
|
+
[word: My, word: Tailor, word: IsPoor]
|
|
707
|
+
|
|
708
|
+
::
|
|
709
|
+
|
|
710
|
+
sage: w = Word("3230301030323212323032321210121232121010")
|
|
711
|
+
sage: l = w.partition("323")
|
|
712
|
+
sage: print(l)
|
|
713
|
+
[word: , word: 323, word: 0301030323212323032321210121232121010]
|
|
714
|
+
sage: sum(l, Word('')) == w
|
|
715
|
+
True
|
|
716
|
+
|
|
717
|
+
If the separator is not a string an error is raised::
|
|
718
|
+
|
|
719
|
+
sage: w = Word("le papa du papa du papa etait un petit pioupiou")
|
|
720
|
+
sage: w.partition(Word(['p','a','p','a']))
|
|
721
|
+
Traceback (most recent call last):
|
|
722
|
+
...
|
|
723
|
+
ValueError: the separator must be a string
|
|
724
|
+
"""
|
|
725
|
+
if isinstance(sep, str):
|
|
726
|
+
return [self._parent(z) for z in self._data.partition(sep)]
|
|
727
|
+
elif isinstance(sep, WordDatatype_str):
|
|
728
|
+
return [self._parent(z) for z in self._data.partition(sep._data)]
|
|
729
|
+
raise ValueError("the separator must be a string")
|
|
730
|
+
|
|
731
|
+
def is_suffix(self, other) -> bool:
|
|
732
|
+
r"""
|
|
733
|
+
Test whether ``self`` is a suffix of ``other``.
|
|
734
|
+
|
|
735
|
+
INPUT:
|
|
736
|
+
|
|
737
|
+
- ``other`` -- a word (an instance of :class:`Word_class`) or a
|
|
738
|
+
:class:`str`
|
|
739
|
+
|
|
740
|
+
OUTPUT: boolean
|
|
741
|
+
|
|
742
|
+
EXAMPLES::
|
|
743
|
+
|
|
744
|
+
sage: w = Word("abbabaabababa")
|
|
745
|
+
sage: u = Word("ababa")
|
|
746
|
+
sage: w.is_suffix(u)
|
|
747
|
+
False
|
|
748
|
+
sage: u.is_suffix(w)
|
|
749
|
+
True
|
|
750
|
+
sage: u.is_suffix("abbabaabababa")
|
|
751
|
+
True
|
|
752
|
+
|
|
753
|
+
TESTS::
|
|
754
|
+
|
|
755
|
+
sage: w = Word("abbabaabababa")
|
|
756
|
+
sage: u = Word(['a','b','a','b','a'])
|
|
757
|
+
sage: w.is_suffix(u)
|
|
758
|
+
False
|
|
759
|
+
sage: u.is_suffix(w)
|
|
760
|
+
True
|
|
761
|
+
"""
|
|
762
|
+
if isinstance(other, WordDatatype_str):
|
|
763
|
+
return other._data.endswith(self._data)
|
|
764
|
+
elif isinstance(other, str):
|
|
765
|
+
return other.endswith(self._data)
|
|
766
|
+
else:
|
|
767
|
+
return super().is_suffix(other)
|
|
768
|
+
|
|
769
|
+
def has_suffix(self, other) -> bool:
|
|
770
|
+
"""
|
|
771
|
+
Test whether ``self`` has ``other`` as a suffix.
|
|
772
|
+
|
|
773
|
+
INPUT:
|
|
774
|
+
|
|
775
|
+
- ``other`` -- a word (an instance of :class:`Word_class`) or a
|
|
776
|
+
:class:`str`
|
|
777
|
+
|
|
778
|
+
OUTPUT: boolean
|
|
779
|
+
|
|
780
|
+
EXAMPLES::
|
|
781
|
+
|
|
782
|
+
sage: w = Word("abbabaabababa")
|
|
783
|
+
sage: u = Word("ababa")
|
|
784
|
+
sage: w.has_suffix(u)
|
|
785
|
+
True
|
|
786
|
+
sage: u.has_suffix(w)
|
|
787
|
+
False
|
|
788
|
+
sage: u.has_suffix("ababa")
|
|
789
|
+
True
|
|
790
|
+
"""
|
|
791
|
+
if isinstance(other, WordDatatype_str):
|
|
792
|
+
return self._data.endswith(other._data)
|
|
793
|
+
elif isinstance(other, str):
|
|
794
|
+
return self._data.endswith(other)
|
|
795
|
+
else:
|
|
796
|
+
return super().has_suffix(other)
|
|
797
|
+
|
|
798
|
+
def is_prefix(self, other) -> bool:
|
|
799
|
+
r"""
|
|
800
|
+
Test whether ``self`` is a prefix of ``other``.
|
|
801
|
+
|
|
802
|
+
INPUT:
|
|
803
|
+
|
|
804
|
+
- ``other`` -- a word (an instance of :class:`Word_class`) or a
|
|
805
|
+
:class:`str`
|
|
806
|
+
|
|
807
|
+
OUTPUT: boolean
|
|
808
|
+
|
|
809
|
+
EXAMPLES::
|
|
810
|
+
|
|
811
|
+
sage: w = Word("abbabaabababa")
|
|
812
|
+
sage: u = Word("abbab")
|
|
813
|
+
sage: w.is_prefix(u)
|
|
814
|
+
False
|
|
815
|
+
sage: u.is_prefix(w)
|
|
816
|
+
True
|
|
817
|
+
sage: u.is_prefix("abbabaabababa")
|
|
818
|
+
True
|
|
819
|
+
|
|
820
|
+
TESTS::
|
|
821
|
+
|
|
822
|
+
sage: ab = Word('ab')
|
|
823
|
+
sage: abba = Word(['a','b','b','a'])
|
|
824
|
+
sage: ab.is_prefix(abba)
|
|
825
|
+
True
|
|
826
|
+
sage: abba.is_prefix(ab)
|
|
827
|
+
False
|
|
828
|
+
"""
|
|
829
|
+
if isinstance(other, WordDatatype_str):
|
|
830
|
+
return other._data.startswith(self._data)
|
|
831
|
+
if isinstance(other, str):
|
|
832
|
+
return other.startswith(self._data)
|
|
833
|
+
return super().is_prefix(other)
|
|
834
|
+
|
|
835
|
+
def has_prefix(self, other) -> bool:
|
|
836
|
+
r"""
|
|
837
|
+
Test whether ``self`` has ``other`` as a prefix.
|
|
838
|
+
|
|
839
|
+
INPUT:
|
|
840
|
+
|
|
841
|
+
- ``other`` -- a word (an instance of :class:`Word_class`) or a
|
|
842
|
+
:class:`str`
|
|
843
|
+
|
|
844
|
+
OUTPUT: boolean
|
|
845
|
+
|
|
846
|
+
EXAMPLES::
|
|
847
|
+
|
|
848
|
+
sage: w = Word("abbabaabababa")
|
|
849
|
+
sage: u = Word("abbab")
|
|
850
|
+
sage: w.has_prefix(u)
|
|
851
|
+
True
|
|
852
|
+
sage: u.has_prefix(w)
|
|
853
|
+
False
|
|
854
|
+
sage: u.has_prefix("abbab")
|
|
855
|
+
True
|
|
856
|
+
|
|
857
|
+
TESTS::
|
|
858
|
+
|
|
859
|
+
sage: ab = Word('ab')
|
|
860
|
+
sage: abba = Word(['a','b','b','a'])
|
|
861
|
+
sage: ab.has_prefix(abba)
|
|
862
|
+
False
|
|
863
|
+
sage: abba.has_prefix(ab)
|
|
864
|
+
True
|
|
865
|
+
"""
|
|
866
|
+
if isinstance(other, WordDatatype_str):
|
|
867
|
+
return self._data.startswith(other._data)
|
|
868
|
+
if isinstance(other, str):
|
|
869
|
+
return self._data.startswith(other)
|
|
870
|
+
else:
|
|
871
|
+
return super().has_prefix(other)
|
|
872
|
+
|
|
873
|
+
cdef class WordDatatype_tuple(WordDatatype):
|
|
874
|
+
r"""
|
|
875
|
+
Datatype class for words defined by tuples.
|
|
876
|
+
"""
|
|
877
|
+
cdef public tuple _data
|
|
878
|
+
|
|
879
|
+
def __init__(self, parent=None, data=None):
|
|
880
|
+
r"""
|
|
881
|
+
Construct a word with parent ``parent`` from an iterable ``data``.
|
|
882
|
+
|
|
883
|
+
INPUT:
|
|
884
|
+
|
|
885
|
+
- ``parent`` -- instance of :class:`Words_all`
|
|
886
|
+
- ``data`` -- iterable
|
|
887
|
+
|
|
888
|
+
EXAMPLES::
|
|
889
|
+
|
|
890
|
+
sage: w = Word((0,1,1,0))
|
|
891
|
+
sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype_tuple)
|
|
892
|
+
True
|
|
893
|
+
sage: u = Word([0,1,1,0], datatype='tuple')
|
|
894
|
+
sage: isinstance(u, sage.combinat.words.word_datatypes.WordDatatype_tuple)
|
|
895
|
+
True
|
|
896
|
+
"""
|
|
897
|
+
self._parent = parent
|
|
898
|
+
if isinstance(data, tuple):
|
|
899
|
+
self._data = data
|
|
900
|
+
else:
|
|
901
|
+
self._data = tuple(data)
|
|
902
|
+
self._hash = None
|
|
903
|
+
|
|
904
|
+
__hash__ = WordDatatype.__hash__
|
|
905
|
+
|
|
906
|
+
def __iter__(self):
|
|
907
|
+
r"""
|
|
908
|
+
Return an iterator that iterates through the letters of ``self``.
|
|
909
|
+
|
|
910
|
+
EXAMPLES::
|
|
911
|
+
|
|
912
|
+
sage: w = Word((0,1,1,0))
|
|
913
|
+
sage: list(iter(w))
|
|
914
|
+
[0, 1, 1, 0]
|
|
915
|
+
"""
|
|
916
|
+
return iter(self._data)
|
|
917
|
+
|
|
918
|
+
def __richcmp__(self, other, int op):
|
|
919
|
+
r"""
|
|
920
|
+
Equality test for ``self`` and ``other`` if other is an instance of
|
|
921
|
+
``WordDatype_tuple``.
|
|
922
|
+
|
|
923
|
+
INPUT:
|
|
924
|
+
|
|
925
|
+
- ``other`` -- a word
|
|
926
|
+
- ``op`` -- integer; 0, 1, 2, 3, 4 or 5
|
|
927
|
+
|
|
928
|
+
OUTPUT: boolean or NotImplemented
|
|
929
|
+
|
|
930
|
+
EXAMPLES::
|
|
931
|
+
|
|
932
|
+
sage: Word((1,2,3)) == Word((1,2,3))
|
|
933
|
+
True
|
|
934
|
+
sage: Word((1,2,3)) == Word(())
|
|
935
|
+
False
|
|
936
|
+
sage: Word((1,2,3)) == Word((1,2,3,4))
|
|
937
|
+
False
|
|
938
|
+
sage: Word((1,2,3)) == Word((1,2,3,'a'))
|
|
939
|
+
False
|
|
940
|
+
|
|
941
|
+
It works even if the parents are not the same::
|
|
942
|
+
|
|
943
|
+
sage: Words([1,2])((1,1,1,2)) == Words([1,2,3])((1,1,1,2))
|
|
944
|
+
True
|
|
945
|
+
sage: Words([1,2])((1,1,1,2)) == Word((1,1,1,2))
|
|
946
|
+
True
|
|
947
|
+
|
|
948
|
+
REFERENCES:
|
|
949
|
+
|
|
950
|
+
http://docs.cython.org/docs/special_methods.html
|
|
951
|
+
"""
|
|
952
|
+
if isinstance(other, WordDatatype_tuple):
|
|
953
|
+
if op == Py_EQ:
|
|
954
|
+
return self._data == other._data
|
|
955
|
+
elif op == Py_NE:
|
|
956
|
+
return self._data != other._data
|
|
957
|
+
|
|
958
|
+
# Otherwise, force FiniteWord_class.__richcmp__ to do it
|
|
959
|
+
from sage.combinat.words.word import FiniteWord_class
|
|
960
|
+
return FiniteWord_class.__richcmp__(self, other, op)
|
|
961
|
+
|
|
962
|
+
def __len__(self):
|
|
963
|
+
r"""
|
|
964
|
+
Return the length of the word.
|
|
965
|
+
|
|
966
|
+
.. NOTE::
|
|
967
|
+
|
|
968
|
+
This function will be deprecated in a future version
|
|
969
|
+
of Sage. Use ``self.length()`` instead.
|
|
970
|
+
|
|
971
|
+
EXAMPLES::
|
|
972
|
+
|
|
973
|
+
sage: w = Word((0,1,1,0))
|
|
974
|
+
sage: len(w)
|
|
975
|
+
4
|
|
976
|
+
"""
|
|
977
|
+
return len(self._data)
|
|
978
|
+
|
|
979
|
+
def length(self):
|
|
980
|
+
r"""
|
|
981
|
+
Return the length of the word.
|
|
982
|
+
|
|
983
|
+
EXAMPLES::
|
|
984
|
+
|
|
985
|
+
sage: w = Word((0,1,1,0))
|
|
986
|
+
sage: w.length()
|
|
987
|
+
4
|
|
988
|
+
"""
|
|
989
|
+
return len(self._data)
|
|
990
|
+
|
|
991
|
+
def __contains__(self, a):
|
|
992
|
+
r"""
|
|
993
|
+
Test whether ``a`` is a letter of ``self``.
|
|
994
|
+
|
|
995
|
+
INPUT:
|
|
996
|
+
|
|
997
|
+
- ``a`` -- anything
|
|
998
|
+
|
|
999
|
+
EXAMPLES::
|
|
1000
|
+
|
|
1001
|
+
sage: w = Word((0,1,1,0))
|
|
1002
|
+
sage: 0 in w
|
|
1003
|
+
True
|
|
1004
|
+
sage: 3 in w
|
|
1005
|
+
False
|
|
1006
|
+
"""
|
|
1007
|
+
return a in self._data
|
|
1008
|
+
|
|
1009
|
+
def __getitem__(self, key):
|
|
1010
|
+
r"""
|
|
1011
|
+
Implement ``__getitem__`` for words stored as tuples.
|
|
1012
|
+
|
|
1013
|
+
INPUT:
|
|
1014
|
+
|
|
1015
|
+
- ``key`` -- integer
|
|
1016
|
+
|
|
1017
|
+
OUTPUT:
|
|
1018
|
+
|
|
1019
|
+
- can be anything (an object contained in the word)
|
|
1020
|
+
|
|
1021
|
+
EXAMPLES::
|
|
1022
|
+
|
|
1023
|
+
sage: w = Word(tuple(range(100)))
|
|
1024
|
+
sage: w[4]
|
|
1025
|
+
4
|
|
1026
|
+
sage: w[-1]
|
|
1027
|
+
99
|
|
1028
|
+
sage: w[3:10:2]
|
|
1029
|
+
word: 3579
|
|
1030
|
+
sage: all(w[i] == i for i in range(100))
|
|
1031
|
+
True
|
|
1032
|
+
"""
|
|
1033
|
+
if isinstance(key, slice):
|
|
1034
|
+
return self._parent(self._data[key])
|
|
1035
|
+
return self._data[key]
|
|
1036
|
+
|
|
1037
|
+
def __mul__(self, other):
|
|
1038
|
+
r"""
|
|
1039
|
+
Return the concatenation of ``self`` and ``other``.
|
|
1040
|
+
|
|
1041
|
+
INPUT:
|
|
1042
|
+
|
|
1043
|
+
- ``other`` -- word represented by a tuple
|
|
1044
|
+
|
|
1045
|
+
OUTPUT: word
|
|
1046
|
+
|
|
1047
|
+
EXAMPLES::
|
|
1048
|
+
|
|
1049
|
+
sage: w = Word((1,2,3,4))
|
|
1050
|
+
sage: w * w
|
|
1051
|
+
word: 12341234
|
|
1052
|
+
|
|
1053
|
+
The type of the concatenation is preserved::
|
|
1054
|
+
|
|
1055
|
+
sage: type(w)
|
|
1056
|
+
<class 'sage.combinat.words.word.FiniteWord_tuple'>
|
|
1057
|
+
sage: type(w * w)
|
|
1058
|
+
<class 'sage.combinat.words.word.FiniteWord_tuple'>
|
|
1059
|
+
sage: type(w + w)
|
|
1060
|
+
<class 'sage.combinat.words.word.FiniteWord_tuple'>
|
|
1061
|
+
"""
|
|
1062
|
+
if isinstance(other, WordDatatype_tuple):
|
|
1063
|
+
return self._parent(self._data + other._data)
|
|
1064
|
+
else:
|
|
1065
|
+
return super().__mul__(other)
|
|
1066
|
+
|
|
1067
|
+
__add__ = __mul__
|