passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +400 -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-0e7fc84e.so.10.5.0 +0 -0
- passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +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 +35 -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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
sage/combinat/shuffle.py
ADDED
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
Shuffle product of iterables
|
|
4
|
+
|
|
5
|
+
The shuffle product of two sequences of lengths `m` and `n` is a
|
|
6
|
+
sum over the `\binom{m+n}{n}` ways of interleaving the two sequences.
|
|
7
|
+
|
|
8
|
+
That could be defined inductively by:
|
|
9
|
+
|
|
10
|
+
.. MATH::
|
|
11
|
+
|
|
12
|
+
(a_n)_{n \geqslant 0} \Cup (b_m)_{m \geqslant 0} =
|
|
13
|
+
a_0 \cdot \left((a_n)_{n \geqslant 1} \Cup (b_m)_{m \geqslant 0}\right)
|
|
14
|
+
+ b_0 \cdot \left((a_n)_{n \geqslant 0} \Cup (b_m)_{m \geqslant 1}\right)
|
|
15
|
+
|
|
16
|
+
with `(a_n)` and `(b_m)` two non-empty sequences and if one of them is empty
|
|
17
|
+
then the product is equals to the other.
|
|
18
|
+
|
|
19
|
+
The shuffle product has been introduced by S. Eilenberg and S. Mac Lane in
|
|
20
|
+
1953 [EilLan53]_.
|
|
21
|
+
|
|
22
|
+
EXAMPLES::
|
|
23
|
+
|
|
24
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
25
|
+
sage: list(ShuffleProduct([1,2], ["a", "b", "c"]))
|
|
26
|
+
[[1, 2, 'a', 'b', 'c'],
|
|
27
|
+
['a', 1, 2, 'b', 'c'],
|
|
28
|
+
[1, 'a', 2, 'b', 'c'],
|
|
29
|
+
['a', 'b', 1, 2, 'c'],
|
|
30
|
+
['a', 1, 'b', 2, 'c'],
|
|
31
|
+
[1, 'a', 'b', 2, 'c'],
|
|
32
|
+
['a', 'b', 'c', 1, 2],
|
|
33
|
+
['a', 'b', 1, 'c', 2],
|
|
34
|
+
['a', 1, 'b', 'c', 2],
|
|
35
|
+
[1, 'a', 'b', 'c', 2]]
|
|
36
|
+
|
|
37
|
+
References:
|
|
38
|
+
|
|
39
|
+
.. [EilLan53] On the groups `H(\pi, n)`, I,
|
|
40
|
+
Samuel Eilenberg and
|
|
41
|
+
Saunders Mac Lane,
|
|
42
|
+
1953.
|
|
43
|
+
|
|
44
|
+
Author:
|
|
45
|
+
|
|
46
|
+
- Jean-Baptiste Priez
|
|
47
|
+
"""
|
|
48
|
+
# ****************************************************************************
|
|
49
|
+
# Copyright (C) 2014 Jean-Baptiste Priez <jbp@kerios.fr>
|
|
50
|
+
#
|
|
51
|
+
# This program is free software: you can redistribute it and/or modify
|
|
52
|
+
# it under the terms of the GNU General Public License as published by
|
|
53
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
54
|
+
# (at your option) any later version.
|
|
55
|
+
# https://www.gnu.org/licenses/
|
|
56
|
+
# ****************************************************************************
|
|
57
|
+
|
|
58
|
+
from collections.abc import Iterable
|
|
59
|
+
import itertools
|
|
60
|
+
import operator
|
|
61
|
+
|
|
62
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
63
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
64
|
+
from sage.combinat.words.abstract_word import Word_class
|
|
65
|
+
from sage.rings.integer import Integer
|
|
66
|
+
from sage.structure.parent import Parent
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# TODO: Think about Parent/Element for this and the category
|
|
70
|
+
# sage.categories.finite_enumerated_sets.FiniteEnumeratedSets
|
|
71
|
+
|
|
72
|
+
class ShuffleProduct_abstract(Parent):
|
|
73
|
+
"""
|
|
74
|
+
Abstract base class for shuffle products.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, l1, l2, element_constructor=None):
|
|
78
|
+
"""
|
|
79
|
+
Initialize ``self``.
|
|
80
|
+
|
|
81
|
+
TESTS::
|
|
82
|
+
|
|
83
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
84
|
+
sage: SP = ShuffleProduct([1,2],[4,5,7,8,9])
|
|
85
|
+
sage: TestSuite(SP).run(skip='_test_an_element')
|
|
86
|
+
"""
|
|
87
|
+
self._l1 = l1
|
|
88
|
+
self._l2 = l2
|
|
89
|
+
if element_constructor is None:
|
|
90
|
+
self._element_constructor_ = self._constructor_
|
|
91
|
+
else:
|
|
92
|
+
self._element_constructor_ = element_constructor
|
|
93
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
94
|
+
|
|
95
|
+
def _constructor_(self, x):
|
|
96
|
+
"""
|
|
97
|
+
This is used by default to produce elements when iterating.
|
|
98
|
+
|
|
99
|
+
TESTS::
|
|
100
|
+
|
|
101
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
102
|
+
sage: S = ShuffleProduct([1,2,3],[4,5])
|
|
103
|
+
sage: S._constructor_((1,2,3))
|
|
104
|
+
[1, 2, 3]
|
|
105
|
+
|
|
106
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping
|
|
107
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
108
|
+
sage: S = ShuffleProduct_overlapping(w,u)
|
|
109
|
+
sage: S._constructor_((1,2,3))
|
|
110
|
+
[1, 2, 3]
|
|
111
|
+
|
|
112
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
113
|
+
sage: S = SetShuffleProduct([[1,2],[3,4]], [[1,4]])
|
|
114
|
+
sage: S._constructor_((1,2,3))
|
|
115
|
+
[1, 2, 3]
|
|
116
|
+
|
|
117
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
118
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
119
|
+
sage: S = ShuffleProduct_overlapping_r(w,u,1)
|
|
120
|
+
sage: S._constructor_((1,2,3))
|
|
121
|
+
[1, 2, 3]
|
|
122
|
+
"""
|
|
123
|
+
return list(x)
|
|
124
|
+
|
|
125
|
+
def __eq__(self, other):
|
|
126
|
+
"""
|
|
127
|
+
Test for equality.
|
|
128
|
+
|
|
129
|
+
TESTS::
|
|
130
|
+
|
|
131
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
132
|
+
sage: SP = ShuffleProduct([1,2],[4,5,7,8,9])
|
|
133
|
+
sage: loads(dumps(SP)) == SP
|
|
134
|
+
True
|
|
135
|
+
sage: SP == ShuffleProduct([1,2],[4,5,7])
|
|
136
|
+
False
|
|
137
|
+
"""
|
|
138
|
+
if not isinstance(other, type(self)):
|
|
139
|
+
return False
|
|
140
|
+
return self._l1 == other._l1 and self._l2 == other._l2
|
|
141
|
+
|
|
142
|
+
def __ne__(self, other):
|
|
143
|
+
"""
|
|
144
|
+
Test for unequality.
|
|
145
|
+
|
|
146
|
+
EXAMPLES::
|
|
147
|
+
|
|
148
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
149
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
150
|
+
sage: A = ShuffleProduct_overlapping_r(w,u,1)
|
|
151
|
+
sage: B = ShuffleProduct_overlapping_r(u,w,2)
|
|
152
|
+
sage: A != A
|
|
153
|
+
False
|
|
154
|
+
sage: A != B
|
|
155
|
+
True
|
|
156
|
+
"""
|
|
157
|
+
return not (self == other)
|
|
158
|
+
|
|
159
|
+
def __contains__(self, x):
|
|
160
|
+
"""
|
|
161
|
+
Check containment.
|
|
162
|
+
|
|
163
|
+
TESTS::
|
|
164
|
+
|
|
165
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
166
|
+
sage: SP = ShuffleProduct([1,2],[4,5,7])
|
|
167
|
+
sage: [1,4,5,2,7] in SP
|
|
168
|
+
True
|
|
169
|
+
sage: (1,4,5,2,7) in SP
|
|
170
|
+
False
|
|
171
|
+
sage: [2,1,4,5,7] in SP
|
|
172
|
+
False
|
|
173
|
+
"""
|
|
174
|
+
return x in self.list()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class SetShuffleProduct(ShuffleProduct_abstract):
|
|
178
|
+
"""
|
|
179
|
+
The union of all possible shuffle products of two sets of iterables.
|
|
180
|
+
|
|
181
|
+
EXAMPLES::
|
|
182
|
+
|
|
183
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
184
|
+
sage: sorted(SetShuffleProduct({(1,), (2,3)}, {(4,5), (6,)}))
|
|
185
|
+
[[1, 4, 5],
|
|
186
|
+
[1, 6],
|
|
187
|
+
[2, 3, 4, 5],
|
|
188
|
+
[2, 3, 6],
|
|
189
|
+
[2, 4, 3, 5],
|
|
190
|
+
[2, 4, 5, 3],
|
|
191
|
+
[2, 6, 3],
|
|
192
|
+
[4, 1, 5],
|
|
193
|
+
[4, 2, 3, 5],
|
|
194
|
+
[4, 2, 5, 3],
|
|
195
|
+
[4, 5, 1],
|
|
196
|
+
[4, 5, 2, 3],
|
|
197
|
+
[6, 1],
|
|
198
|
+
[6, 2, 3]]
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
def __init__(self, l1, l2, element_constructor=None):
|
|
202
|
+
"""
|
|
203
|
+
Construct the set of all possible shuffle products of two sets of iterables.
|
|
204
|
+
|
|
205
|
+
INPUT:
|
|
206
|
+
|
|
207
|
+
- ``l1``, ``l2`` -- iterable: the sets to shuffle
|
|
208
|
+
|
|
209
|
+
- ``element_constructor`` -- constructor for the returned elements
|
|
210
|
+
|
|
211
|
+
TESTS::
|
|
212
|
+
|
|
213
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
214
|
+
sage: X = SetShuffleProduct({(1,2,3), (2,3,4)}, {(5,)})
|
|
215
|
+
sage: X # random
|
|
216
|
+
Shuffle set product of: [(2, 3, 4), (1, 2, 3)] and [(5,)]
|
|
217
|
+
sage: TestSuite(X).run(skip='_test_an_element')
|
|
218
|
+
|
|
219
|
+
sage: list(SetShuffleProduct({(1,2,3), (2,3,4)}, {(5,)})) # random
|
|
220
|
+
[[2, 3, 4, 5], [2, 5, 3, 4], [5, 2, 3, 4], [2, 3, 5, 4],
|
|
221
|
+
[1, 2, 3, 5], [1, 5, 2, 3], [5, 1, 2, 3], [1, 2, 5, 3]]
|
|
222
|
+
"""
|
|
223
|
+
assert isinstance(l1, Iterable) and isinstance(l2, Iterable)
|
|
224
|
+
assert all(isinstance(elem, Iterable) for elem in l1)
|
|
225
|
+
assert all(isinstance(elem, Iterable) for elem in l2)
|
|
226
|
+
|
|
227
|
+
if element_constructor is None:
|
|
228
|
+
try:
|
|
229
|
+
e = next(iter(l1))
|
|
230
|
+
try:
|
|
231
|
+
element_constructor = e.parent()._element_constructor_
|
|
232
|
+
except AttributeError:
|
|
233
|
+
pass
|
|
234
|
+
except StopIteration:
|
|
235
|
+
pass
|
|
236
|
+
ShuffleProduct_abstract.__init__(self, list(l1), list(l2), element_constructor)
|
|
237
|
+
|
|
238
|
+
def _repr_(self):
|
|
239
|
+
"""
|
|
240
|
+
TESTS::
|
|
241
|
+
|
|
242
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
243
|
+
sage: SetShuffleProduct([[1,2],[3,4]], [[1,4]])
|
|
244
|
+
Shuffle set product of: [[1, 2], [3, 4]] and [[1, 4]]
|
|
245
|
+
sage: SetShuffleProduct([()], [[1,4]])
|
|
246
|
+
Shuffle set product of: [()] and [[1, 4]]
|
|
247
|
+
"""
|
|
248
|
+
return "Shuffle set product of: %s and %s" % (self._element_constructor_(self._l1),
|
|
249
|
+
self._element_constructor_(self._l2))
|
|
250
|
+
|
|
251
|
+
def _ascii_art_(self):
|
|
252
|
+
r"""
|
|
253
|
+
TESTS::
|
|
254
|
+
|
|
255
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
256
|
+
sage: ascii_art(SetShuffleProduct([[BinaryTree()], [BinaryTree([]), BinaryTree([[],[]])]], # needs sage.graphs
|
|
257
|
+
....: [[1,4]]))
|
|
258
|
+
Set shuffle product of:
|
|
259
|
+
[ [ o, o ] ]
|
|
260
|
+
[ [ / \ ] ]
|
|
261
|
+
[ [ ], [ o o ] ] and [ [ 1, 4 ] ]
|
|
262
|
+
"""
|
|
263
|
+
from sage.typeset.ascii_art import ascii_art
|
|
264
|
+
return (ascii_art("Set shuffle product of:") *
|
|
265
|
+
(ascii_art(self._l1) + ascii_art(" and ") +
|
|
266
|
+
ascii_art(self._l2)))
|
|
267
|
+
|
|
268
|
+
def __iter__(self):
|
|
269
|
+
"""
|
|
270
|
+
TESTS::
|
|
271
|
+
|
|
272
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
273
|
+
sage: list(SetShuffleProduct([[],[]], [[]]))
|
|
274
|
+
[[], []]
|
|
275
|
+
sage: list(SetShuffleProduct([[1,2],[3]], [[4]]))
|
|
276
|
+
[[1, 2, 4], [4, 1, 2], [1, 4, 2], [3, 4], [4, 3]]
|
|
277
|
+
sage: list(SetShuffleProduct([[1,2],[3,4]], [[1,4]], element_constructor=set))
|
|
278
|
+
[{1, 2, 4},
|
|
279
|
+
{1, 2, 4},
|
|
280
|
+
{1, 2, 4},
|
|
281
|
+
{1, 2, 4},
|
|
282
|
+
{1, 2, 4},
|
|
283
|
+
{1, 2, 4},
|
|
284
|
+
{1, 3, 4},
|
|
285
|
+
{1, 3, 4},
|
|
286
|
+
{1, 3, 4},
|
|
287
|
+
{1, 3, 4},
|
|
288
|
+
{1, 3, 4},
|
|
289
|
+
{1, 3, 4}]
|
|
290
|
+
"""
|
|
291
|
+
return itertools.chain.from_iterable(
|
|
292
|
+
ShuffleProduct(*pair,
|
|
293
|
+
element_constructor=self._element_constructor_)
|
|
294
|
+
for pair in itertools.product(self._l1, self._l2))
|
|
295
|
+
|
|
296
|
+
def cardinality(self):
|
|
297
|
+
"""
|
|
298
|
+
The cardinality is defined by the sum of the cardinality of all shuffles.
|
|
299
|
+
That means by a sum of binomials.
|
|
300
|
+
|
|
301
|
+
TESTS::
|
|
302
|
+
|
|
303
|
+
sage: from sage.combinat.shuffle import SetShuffleProduct
|
|
304
|
+
sage: SetShuffleProduct([[1,2],[3,4]], [[1,4]], element_constructor=set).cardinality()
|
|
305
|
+
12
|
|
306
|
+
"""
|
|
307
|
+
def comp_binom(el1, el2):
|
|
308
|
+
ll1 = Integer(len(el1))
|
|
309
|
+
ll2 = Integer(len(el2))
|
|
310
|
+
return (ll1 + ll2).binomial(ll2)
|
|
311
|
+
|
|
312
|
+
return sum(comp_binom(el1, el2)
|
|
313
|
+
for (el1, el2) in itertools.product(self._l1, self._l2))
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class ShuffleProduct(ShuffleProduct_abstract):
|
|
317
|
+
"""
|
|
318
|
+
Shuffle product of two iterables.
|
|
319
|
+
|
|
320
|
+
EXAMPLES::
|
|
321
|
+
|
|
322
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
323
|
+
sage: list(ShuffleProduct("abc", "de", element_constructor="".join))
|
|
324
|
+
['abcde',
|
|
325
|
+
'adbce',
|
|
326
|
+
'dabce',
|
|
327
|
+
'abdce',
|
|
328
|
+
'adebc',
|
|
329
|
+
'daebc',
|
|
330
|
+
'deabc',
|
|
331
|
+
'adbec',
|
|
332
|
+
'dabec',
|
|
333
|
+
'abdec']
|
|
334
|
+
sage: list(ShuffleProduct("", "de", element_constructor="".join))
|
|
335
|
+
['de']
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
def __init__(self, l1, l2, element_constructor=None):
|
|
339
|
+
"""
|
|
340
|
+
Construct the shuffle product of two iterable.
|
|
341
|
+
|
|
342
|
+
INPUT:
|
|
343
|
+
|
|
344
|
+
- ``l1``, ``l2`` -- iterable: iterables to shuffle
|
|
345
|
+
|
|
346
|
+
- ``element_constructor`` -- constructor for the returned elements
|
|
347
|
+
|
|
348
|
+
TESTS::
|
|
349
|
+
|
|
350
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
351
|
+
sage: SP = ShuffleProduct([1,2,3],[4,5])
|
|
352
|
+
sage: SP
|
|
353
|
+
Shuffle product of: [1, 2, 3] and [4, 5]
|
|
354
|
+
sage: TestSuite(SP).run(skip='_test_an_element')
|
|
355
|
+
|
|
356
|
+
sage: list(ShuffleProduct(Word("aa"), Word("bbb"), Word))
|
|
357
|
+
[word: aabbb, word: baabb, word: ababb, word: bbaab, word: babab, word: abbab,
|
|
358
|
+
word: bbbaa, word: bbaba, word: babba, word: abbba]
|
|
359
|
+
"""
|
|
360
|
+
assert isinstance(l1, Iterable) and isinstance(l2, Iterable)
|
|
361
|
+
|
|
362
|
+
if element_constructor is None:
|
|
363
|
+
try:
|
|
364
|
+
element_constructor = l1.parent()._element_constructor_
|
|
365
|
+
except AttributeError:
|
|
366
|
+
pass
|
|
367
|
+
ShuffleProduct_abstract.__init__(self, list(l1), list(l2), element_constructor)
|
|
368
|
+
|
|
369
|
+
def _repr_(self):
|
|
370
|
+
"""
|
|
371
|
+
TESTS::
|
|
372
|
+
|
|
373
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
374
|
+
sage: ShuffleProduct([1,2,3],[4,5])
|
|
375
|
+
Shuffle product of: [1, 2, 3] and [4, 5]
|
|
376
|
+
sage: B = BinaryTree # needs sage.graphs
|
|
377
|
+
sage: ShuffleProduct([B(), B([[],[]])], []) # needs sage.graphs
|
|
378
|
+
Shuffle product of: [., [[., .], [., .]]] and []
|
|
379
|
+
"""
|
|
380
|
+
return "Shuffle product of: %s and %s" % (self._l1, self._l2)
|
|
381
|
+
|
|
382
|
+
def _ascii_art_(self):
|
|
383
|
+
r"""
|
|
384
|
+
TESTS::
|
|
385
|
+
|
|
386
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
387
|
+
sage: ascii_art(ShuffleProduct([1,2,3],[4,5]))
|
|
388
|
+
Shuffle product of:
|
|
389
|
+
[ 1, 2, 3 ] and [ 4, 5 ]
|
|
390
|
+
sage: B = BinaryTree # needs sage.graphs
|
|
391
|
+
sage: ascii_art(ShuffleProduct([B([]), B([[],[]])], # needs sage.graphs
|
|
392
|
+
....: [B([[[],[]],[[],None]])]))
|
|
393
|
+
Shuffle product of:
|
|
394
|
+
[ __o__ ]
|
|
395
|
+
[ / \ ]
|
|
396
|
+
[ o, o ] [ o o ]
|
|
397
|
+
[ / \ ] [ / \ / ]
|
|
398
|
+
[ o o ] and [ o o o ]
|
|
399
|
+
"""
|
|
400
|
+
from sage.typeset.ascii_art import ascii_art
|
|
401
|
+
return ascii_art("Shuffle product of:") * \
|
|
402
|
+
(ascii_art(self._l1) + ascii_art(" and ") +
|
|
403
|
+
ascii_art(self._l2))
|
|
404
|
+
|
|
405
|
+
def __iter__(self):
|
|
406
|
+
r"""
|
|
407
|
+
Efficient iteration from a gray code on binary words in `B(n,k)`.
|
|
408
|
+
|
|
409
|
+
(with `B(n,k)` the number of binary words of size `n` with `k` one.
|
|
410
|
+
|
|
411
|
+
TESTS::
|
|
412
|
+
|
|
413
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
414
|
+
sage: list(ShuffleProduct([1,2,3],[4,5]))
|
|
415
|
+
[[1, 2, 3, 4, 5], [1, 4, 2, 3, 5], [4, 1, 2, 3, 5], [1, 2, 4, 3, 5], [1, 4, 5, 2, 3],
|
|
416
|
+
[4, 1, 5, 2, 3], [4, 5, 1, 2, 3], [1, 4, 2, 5, 3], [4, 1, 2, 5, 3], [1, 2, 4, 5, 3]]
|
|
417
|
+
sage: B = BinaryTree # needs sage.graphs
|
|
418
|
+
sage: ascii_art(list(ShuffleProduct([B([]), B([[],[]])], # needs sage.graphs
|
|
419
|
+
....: [B([[[],[]],[[],None]])])))
|
|
420
|
+
[ [ o, o , __o__ ] [ __o__ , o, o ]
|
|
421
|
+
[ [ / \ / \ ] [ / \ / \ ]
|
|
422
|
+
[ [ o o o o ] [ o o o o ]
|
|
423
|
+
[ [ / \ / ] [ / \ / ]
|
|
424
|
+
[ [ o o o ], [ o o o ],
|
|
425
|
+
<BLANKLINE>
|
|
426
|
+
[ o, __o__ , o ] ]
|
|
427
|
+
[ / \ / \ ] ]
|
|
428
|
+
[ o o o o ] ]
|
|
429
|
+
[ / \ / ] ]
|
|
430
|
+
[ o o o ] ]
|
|
431
|
+
"""
|
|
432
|
+
|
|
433
|
+
# -------------- Gray code --------------
|
|
434
|
+
def swap(i, j):
|
|
435
|
+
l[i - 1], l[j - 1] = l[j - 1], l[i - 1]
|
|
436
|
+
|
|
437
|
+
def gen(n, k):
|
|
438
|
+
if 0 < k < n:
|
|
439
|
+
for _ in gen(n - 1, k):
|
|
440
|
+
yield
|
|
441
|
+
|
|
442
|
+
if k == 1:
|
|
443
|
+
swap(n, n - 1)
|
|
444
|
+
else:
|
|
445
|
+
swap(n, k - 1)
|
|
446
|
+
yield
|
|
447
|
+
|
|
448
|
+
for _ in neg(n - 1, k - 1):
|
|
449
|
+
yield
|
|
450
|
+
|
|
451
|
+
def neg(n, k):
|
|
452
|
+
if 0 < k < n:
|
|
453
|
+
for _ in gen(n - 1, k - 1):
|
|
454
|
+
yield
|
|
455
|
+
|
|
456
|
+
if k == 1:
|
|
457
|
+
swap(n, n - 1)
|
|
458
|
+
else:
|
|
459
|
+
swap(n, k - 1)
|
|
460
|
+
yield
|
|
461
|
+
|
|
462
|
+
for _ in neg(n - 1, k):
|
|
463
|
+
yield
|
|
464
|
+
|
|
465
|
+
####################################
|
|
466
|
+
|
|
467
|
+
m = len(self._l1)
|
|
468
|
+
n = len(self._l2)
|
|
469
|
+
mn = m + n
|
|
470
|
+
l = [0] * m + [1] * n # [0, 0 ... m times, 1, 1, 1 ... n times]
|
|
471
|
+
|
|
472
|
+
EC = self._element_constructor_
|
|
473
|
+
yield EC(self._l1 + self._l2)
|
|
474
|
+
|
|
475
|
+
for _ in gen(mn, m):
|
|
476
|
+
l1 = iter(self._l1)
|
|
477
|
+
l2 = iter(self._l2)
|
|
478
|
+
yield EC([next(l2) if l[k] else next(l1) for k in range(mn)])
|
|
479
|
+
|
|
480
|
+
def __contains__(self, iterable):
|
|
481
|
+
"""
|
|
482
|
+
TESTS::
|
|
483
|
+
|
|
484
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
485
|
+
sage: sh = ShuffleProduct([1,2,3],[4,5])
|
|
486
|
+
sage: list(range(1,6)) in sh
|
|
487
|
+
True
|
|
488
|
+
sage: list(range(1,7)) in sh
|
|
489
|
+
False
|
|
490
|
+
sage: [3,4,5,1,2] in sh
|
|
491
|
+
False
|
|
492
|
+
sage: [1,4,2,5,3] in sh
|
|
493
|
+
True
|
|
494
|
+
sage: [1,4,2,2,5,3] in sh
|
|
495
|
+
False
|
|
496
|
+
"""
|
|
497
|
+
if not isinstance(iterable, type(self._element_constructor_([]))):
|
|
498
|
+
return False
|
|
499
|
+
|
|
500
|
+
l1 = self._l1
|
|
501
|
+
l2 = self._l2
|
|
502
|
+
len_l1 = len(l1)
|
|
503
|
+
len_l2 = len(l2)
|
|
504
|
+
i_l1 = i_l2 = 0
|
|
505
|
+
iterable = list(iterable)
|
|
506
|
+
|
|
507
|
+
for i, el in enumerate(iterable):
|
|
508
|
+
if l1[i_l1] == el:
|
|
509
|
+
i_l1 += 1
|
|
510
|
+
elif l2[i_l2] == el:
|
|
511
|
+
i_l2 += 1
|
|
512
|
+
else:
|
|
513
|
+
return False
|
|
514
|
+
if i_l1 == len_l1:
|
|
515
|
+
return iterable[i + 1:] == l2[i_l2:]
|
|
516
|
+
if i_l2 == len_l2:
|
|
517
|
+
return iterable[i + 1:] == l1[i_l1:]
|
|
518
|
+
return i_l1 + 1 == len_l1 and i_l2 + 1 == len_l2
|
|
519
|
+
|
|
520
|
+
def cardinality(self):
|
|
521
|
+
r"""
|
|
522
|
+
Return the number of shuffles of `l_1` and `l_2`, respectively of
|
|
523
|
+
lengths `m` and `n`, which is `\binom{m+n}{n}`.
|
|
524
|
+
|
|
525
|
+
TESTS::
|
|
526
|
+
|
|
527
|
+
sage: from sage.combinat.shuffle import ShuffleProduct
|
|
528
|
+
sage: ShuffleProduct([3,1,2], [4,2,1,3]).cardinality()
|
|
529
|
+
35
|
|
530
|
+
sage: ShuffleProduct([3,1,2,5,6,4], [4,2,1,3]).cardinality() == binomial(10,4)
|
|
531
|
+
True
|
|
532
|
+
"""
|
|
533
|
+
ll1 = Integer(len(self._l1))
|
|
534
|
+
ll2 = Integer(len(self._l2))
|
|
535
|
+
return (ll1 + ll2).binomial(ll1)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
class ShuffleProduct_overlapping_r(ShuffleProduct_abstract):
|
|
539
|
+
"""
|
|
540
|
+
The overlapping shuffle product of the two words ``w1`` and ``w2``
|
|
541
|
+
with precisely ``r`` overlaps.
|
|
542
|
+
|
|
543
|
+
See :class:`ShuffleProduct_overlapping` for a definition.
|
|
544
|
+
|
|
545
|
+
EXAMPLES::
|
|
546
|
+
|
|
547
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
548
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
549
|
+
sage: S = ShuffleProduct_overlapping_r(w,u,1)
|
|
550
|
+
sage: list(S)
|
|
551
|
+
[word: 11,9,1,
|
|
552
|
+
word: 2,18,1,
|
|
553
|
+
word: 11,1,9,
|
|
554
|
+
word: 2,9,10,
|
|
555
|
+
word: 939,
|
|
556
|
+
word: 9,2,10]
|
|
557
|
+
"""
|
|
558
|
+
|
|
559
|
+
def __init__(self, w1, w2, r, element_constructor=None, add=operator.add):
|
|
560
|
+
"""
|
|
561
|
+
Initialize ``self``.
|
|
562
|
+
|
|
563
|
+
EXAMPLES::
|
|
564
|
+
|
|
565
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
566
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
567
|
+
sage: S = ShuffleProduct_overlapping_r(w,u,1)
|
|
568
|
+
sage: TestSuite(S).run(skip='_test_an_element')
|
|
569
|
+
"""
|
|
570
|
+
self.r = r
|
|
571
|
+
self.add = add
|
|
572
|
+
|
|
573
|
+
if element_constructor is None:
|
|
574
|
+
# Special case for words since their parent has a __call__ but
|
|
575
|
+
# not an _element_constructor_
|
|
576
|
+
if isinstance(w1, Word_class):
|
|
577
|
+
element_constructor = w1.parent()
|
|
578
|
+
else:
|
|
579
|
+
try:
|
|
580
|
+
element_constructor = w1.parent()._element_constructor_
|
|
581
|
+
except AttributeError:
|
|
582
|
+
pass
|
|
583
|
+
ShuffleProduct_abstract.__init__(self, w1, w2, element_constructor)
|
|
584
|
+
|
|
585
|
+
def _repr_(self):
|
|
586
|
+
"""
|
|
587
|
+
EXAMPLES::
|
|
588
|
+
|
|
589
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
590
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
591
|
+
sage: ShuffleProduct_overlapping_r(w,u,1).__repr__()
|
|
592
|
+
'Overlapping shuffle product of word: 29 and word: 91 with 1 overlaps'
|
|
593
|
+
"""
|
|
594
|
+
return "Overlapping shuffle product of %s and %s with %s overlaps" % (repr(self._l1), repr(self._l2), self.r)
|
|
595
|
+
|
|
596
|
+
def __eq__(self, other):
|
|
597
|
+
"""
|
|
598
|
+
Check equality.
|
|
599
|
+
|
|
600
|
+
EXAMPLES::
|
|
601
|
+
|
|
602
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
603
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
604
|
+
sage: A = ShuffleProduct_overlapping_r(w,u,1)
|
|
605
|
+
sage: B = ShuffleProduct_overlapping_r(u,w,2)
|
|
606
|
+
sage: A == A
|
|
607
|
+
True
|
|
608
|
+
sage: A == B
|
|
609
|
+
False
|
|
610
|
+
"""
|
|
611
|
+
return ShuffleProduct_abstract.__eq__(self, other) and self.r == other.r
|
|
612
|
+
|
|
613
|
+
def __iter__(self):
|
|
614
|
+
"""
|
|
615
|
+
EXAMPLES::
|
|
616
|
+
|
|
617
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping_r
|
|
618
|
+
sage: w, u = Word([1,2]), Word([3,4])
|
|
619
|
+
sage: ShuffleProduct_overlapping_r(w,u,1).list()
|
|
620
|
+
[word: 424, word: 154, word: 442, word: 136, word: 352, word: 316]
|
|
621
|
+
sage: w, u = map(Words(range(1,7)), [[1,2], [3,4]])
|
|
622
|
+
sage: W = Words(range(1,7))
|
|
623
|
+
sage: w, u = W([1,2]), W([3,4])
|
|
624
|
+
sage: ShuffleProduct_overlapping_r(w, u, 1).list() #indirect doctest
|
|
625
|
+
[word: 424, word: 154, word: 442, word: 136, word: 352, word: 316]
|
|
626
|
+
|
|
627
|
+
sage: I, J = Composition([2, 2]), Composition([1, 1])
|
|
628
|
+
sage: S = ShuffleProduct_overlapping_r(I, J, 1)
|
|
629
|
+
sage: S.list()
|
|
630
|
+
[[3, 2, 1], [2, 3, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2], [1, 2, 3]]
|
|
631
|
+
|
|
632
|
+
TESTS:
|
|
633
|
+
|
|
634
|
+
We need to be explicitly more generic about the resulting parent
|
|
635
|
+
when shuffling two compositions `I` and `J` (:issue:`15131`)::
|
|
636
|
+
|
|
637
|
+
sage: I, J = Compositions(4)([2, 2]), Composition([1, 1])
|
|
638
|
+
sage: S = ShuffleProduct_overlapping_r(I, J, 1, Compositions())
|
|
639
|
+
sage: S.list()
|
|
640
|
+
[[3, 2, 1], [2, 3, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2], [1, 2, 3]]
|
|
641
|
+
"""
|
|
642
|
+
EC = self._element_constructor_
|
|
643
|
+
|
|
644
|
+
m = len(self._l1)
|
|
645
|
+
n = len(self._l2)
|
|
646
|
+
r = self.r
|
|
647
|
+
add = self.add
|
|
648
|
+
|
|
649
|
+
wc1, wc2 = self._l1, self._l2
|
|
650
|
+
|
|
651
|
+
blank = [None] * (m + n - r)
|
|
652
|
+
for iv in IntegerVectors(m, m + n - r, max_part=1):
|
|
653
|
+
w = blank[:]
|
|
654
|
+
filled_places = []
|
|
655
|
+
unfilled_places = []
|
|
656
|
+
# Fill in w1 into the iv slots
|
|
657
|
+
i = 0
|
|
658
|
+
for j in range(len(iv)):
|
|
659
|
+
if iv[j] == 1:
|
|
660
|
+
w[j] = wc1[i]
|
|
661
|
+
i += 1
|
|
662
|
+
filled_places.append(j)
|
|
663
|
+
else:
|
|
664
|
+
unfilled_places.append(j)
|
|
665
|
+
|
|
666
|
+
# Choose r of these filled places
|
|
667
|
+
for subset in itertools.combinations(filled_places, r):
|
|
668
|
+
places_to_fill = sorted(unfilled_places + list(subset))
|
|
669
|
+
|
|
670
|
+
# Fill in w2 into the places
|
|
671
|
+
i = 0
|
|
672
|
+
res = w[:]
|
|
673
|
+
for j in places_to_fill:
|
|
674
|
+
if res[j] is not None:
|
|
675
|
+
res[j] = add(res[j], wc2[i])
|
|
676
|
+
else:
|
|
677
|
+
res[j] = wc2[i]
|
|
678
|
+
i += 1
|
|
679
|
+
|
|
680
|
+
yield EC(res)
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
class ShuffleProduct_overlapping(ShuffleProduct_abstract):
|
|
684
|
+
r"""
|
|
685
|
+
The overlapping shuffle product of the two words ``w1`` and
|
|
686
|
+
``w2``.
|
|
687
|
+
|
|
688
|
+
If `u` and `v` are two words whose letters belong to an
|
|
689
|
+
additive monoid or to another kind of alphabet on which addition
|
|
690
|
+
is well-defined, then the *overlapping shuffle product* of
|
|
691
|
+
`u` and `v` is a certain multiset of words defined as follows:
|
|
692
|
+
Let `a` and `b` be the lengths of `u` and `v`, respectively.
|
|
693
|
+
Let `A` be the set `\{(0, 1), (0, 2), \cdots, (0, a)\}`, and
|
|
694
|
+
let `B` be the set `\{(1, 1), (1, 2), \cdots, (1, b)\}`.
|
|
695
|
+
Notice that the sets `A` and `B` are disjoint. We can make
|
|
696
|
+
`A` and `B` into posets by setting `(k, i) \leq (k, j)` for
|
|
697
|
+
all `k \in \{0, 1\}` and `i \leq j`. Then, `A \cup B` becomes
|
|
698
|
+
a poset by disjoint union (we don't set `(0, i) \leq (1, i)`).
|
|
699
|
+
Let `p` be the map from `A \cup B` to the set of all letters
|
|
700
|
+
which sends every `(0, i)` to the `i`-th letter of `u`, and
|
|
701
|
+
every `(1, j)` to the `j`-th letter of `v`. For every
|
|
702
|
+
nonnegative integer `c` and every surjective map
|
|
703
|
+
`f : A \cup B \to \{ 1, 2, \cdots, c \}` for which both
|
|
704
|
+
restrictions `f \mid_A` and `f \mid_B` are strictly increasing,
|
|
705
|
+
let `w(f)` be the length-`c` word such that for every
|
|
706
|
+
`1 \leq k \leq c`, the `k`-th letter of `w(f)` equals
|
|
707
|
+
`\sum_{j \in f^{-1}(k)} p(j)` (this sum always has either
|
|
708
|
+
one or two addends). The overlapping shuffle product of `u`
|
|
709
|
+
and `v` is then the multiset of all `w(f)` with `c` ranging
|
|
710
|
+
over all nonnegative integers and `f` ranging
|
|
711
|
+
over the surjective maps
|
|
712
|
+
`f : A \cup B \to \{ 1, 2, \cdots, c \}` for which both
|
|
713
|
+
restrictions `f \mid_A` and `f \mid_B` are strictly increasing.
|
|
714
|
+
|
|
715
|
+
If one restricts `c` to a particular fixed nonnegative
|
|
716
|
+
integer, then the multiset is instead called the *overlapping
|
|
717
|
+
shuffle product with precisely `a + b - c` overlaps*. This is
|
|
718
|
+
nonempty only if `\max \{a, b\} \leq c \leq a + b`.
|
|
719
|
+
|
|
720
|
+
If `c = a + b`, then the overlapping shuffle product with
|
|
721
|
+
precisely `a + b - c` overlaps is plainly the shuffle product
|
|
722
|
+
(:class:`ShuffleProduct_w1w2`).
|
|
723
|
+
|
|
724
|
+
INPUT:
|
|
725
|
+
|
|
726
|
+
- ``w1``, ``w2`` -- iterables
|
|
727
|
+
- ``element_constructor`` -- (default: the parent of ``w1``)
|
|
728
|
+
the function used to construct the output
|
|
729
|
+
- ``add`` -- (default: ``+``) the addition function
|
|
730
|
+
|
|
731
|
+
EXAMPLES::
|
|
732
|
+
|
|
733
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping
|
|
734
|
+
sage: w, u = [[2, 9], [9, 1]]
|
|
735
|
+
sage: S = ShuffleProduct_overlapping(w, u)
|
|
736
|
+
sage: sorted(S)
|
|
737
|
+
[[2, 9, 1, 9],
|
|
738
|
+
[2, 9, 9, 1],
|
|
739
|
+
[2, 9, 9, 1],
|
|
740
|
+
[2, 9, 10],
|
|
741
|
+
[2, 18, 1],
|
|
742
|
+
[9, 1, 2, 9],
|
|
743
|
+
[9, 2, 1, 9],
|
|
744
|
+
[9, 2, 9, 1],
|
|
745
|
+
[9, 2, 10],
|
|
746
|
+
[9, 3, 9],
|
|
747
|
+
[11, 1, 9],
|
|
748
|
+
[11, 9, 1],
|
|
749
|
+
[11, 10]]
|
|
750
|
+
sage: A = [{1,2}, {3,4}]
|
|
751
|
+
sage: B = [{2,3}, {4,5,6}]
|
|
752
|
+
sage: S = ShuffleProduct_overlapping(A, B, add=lambda X,Y: X.union(Y))
|
|
753
|
+
sage: list(S)
|
|
754
|
+
[[{1, 2}, {3, 4}, {2, 3}, {4, 5, 6}],
|
|
755
|
+
[{1, 2}, {2, 3}, {3, 4}, {4, 5, 6}],
|
|
756
|
+
[{1, 2}, {2, 3}, {4, 5, 6}, {3, 4}],
|
|
757
|
+
[{2, 3}, {1, 2}, {3, 4}, {4, 5, 6}],
|
|
758
|
+
[{2, 3}, {1, 2}, {4, 5, 6}, {3, 4}],
|
|
759
|
+
[{2, 3}, {4, 5, 6}, {1, 2}, {3, 4}],
|
|
760
|
+
[{1, 2, 3}, {3, 4}, {4, 5, 6}],
|
|
761
|
+
[{1, 2}, {2, 3, 4}, {4, 5, 6}],
|
|
762
|
+
[{1, 2, 3}, {4, 5, 6}, {3, 4}],
|
|
763
|
+
[{1, 2}, {2, 3}, {3, 4, 5, 6}],
|
|
764
|
+
[{2, 3}, {1, 2, 4, 5, 6}, {3, 4}],
|
|
765
|
+
[{2, 3}, {1, 2}, {3, 4, 5, 6}],
|
|
766
|
+
[{1, 2, 3}, {3, 4, 5, 6}]]
|
|
767
|
+
"""
|
|
768
|
+
|
|
769
|
+
def __init__(self, w1, w2, element_constructor=None, add=operator.add):
|
|
770
|
+
"""
|
|
771
|
+
Initialize ``self``.
|
|
772
|
+
|
|
773
|
+
TESTS::
|
|
774
|
+
|
|
775
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping
|
|
776
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
777
|
+
sage: S = ShuffleProduct_overlapping(w,u)
|
|
778
|
+
sage: TestSuite(S).run(skip='_test_an_element')
|
|
779
|
+
"""
|
|
780
|
+
self._add = add
|
|
781
|
+
|
|
782
|
+
if element_constructor is None:
|
|
783
|
+
# Special case for words since their parent has a __call__ but
|
|
784
|
+
# not an _element_constructor_
|
|
785
|
+
if isinstance(w1, Word_class):
|
|
786
|
+
element_constructor = w1.parent()
|
|
787
|
+
else:
|
|
788
|
+
try:
|
|
789
|
+
element_constructor = self._l1.parent()._element_constructor_
|
|
790
|
+
except AttributeError:
|
|
791
|
+
pass
|
|
792
|
+
ShuffleProduct_abstract.__init__(self, w1, w2, element_constructor)
|
|
793
|
+
|
|
794
|
+
def _repr_(self):
|
|
795
|
+
"""
|
|
796
|
+
EXAMPLES::
|
|
797
|
+
|
|
798
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping
|
|
799
|
+
sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]])
|
|
800
|
+
sage: ShuffleProduct_overlapping(w,u).__repr__()
|
|
801
|
+
'Overlapping shuffle product of word: 29 and word: 91'
|
|
802
|
+
"""
|
|
803
|
+
return "Overlapping shuffle product of %s and %s" % (repr(self._l1),
|
|
804
|
+
repr(self._l2))
|
|
805
|
+
|
|
806
|
+
def __iter__(self):
|
|
807
|
+
"""
|
|
808
|
+
EXAMPLES::
|
|
809
|
+
|
|
810
|
+
sage: from sage.combinat.shuffle import ShuffleProduct_overlapping
|
|
811
|
+
sage: w, u = map(Words(range(10)), [[0,1],[2,3]])
|
|
812
|
+
sage: S = ShuffleProduct_overlapping(w,u)
|
|
813
|
+
sage: S.list()
|
|
814
|
+
[word: 0123, word: 0213, word: 0231, word: 2013, word: 2031,
|
|
815
|
+
word: 2301, word: 213, word: 033, word: 231, word: 024,
|
|
816
|
+
word: 231, word: 204, word: 24]
|
|
817
|
+
|
|
818
|
+
sage: w, u = map(Words(range(1,10)), [[1,2],[3,4]])
|
|
819
|
+
sage: S = ShuffleProduct_overlapping(w,u)
|
|
820
|
+
sage: S.list()
|
|
821
|
+
[word: 1234, word: 1324, word: 1342, word: 3124, word: 3142,
|
|
822
|
+
word: 3412, word: 424, word: 154, word: 442, word: 136,
|
|
823
|
+
word: 352, word: 316, word: 46]
|
|
824
|
+
"""
|
|
825
|
+
m = len(self._l1)
|
|
826
|
+
n = len(self._l2)
|
|
827
|
+
for r in range(min(m, n) + 1):
|
|
828
|
+
yield from ShuffleProduct_overlapping_r(self._l1, self._l2, r,
|
|
829
|
+
self._element_constructor_,
|
|
830
|
+
add=self._add)
|