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
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
"""
|
|
3
|
+
Necklaces
|
|
4
|
+
|
|
5
|
+
The algorithm used in this file comes from
|
|
6
|
+
|
|
7
|
+
- Sawada, Joe. *A fast algorithm to generate necklaces with fixed content*,
|
|
8
|
+
Theoretical Computer Science archive Volume 301, Issue 1-3 (May 2003)
|
|
9
|
+
:doi:`10.1016/S0304-3975(03)00049-5`
|
|
10
|
+
"""
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
|
|
13
|
+
#
|
|
14
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
15
|
+
#
|
|
16
|
+
# This code is distributed in the hope that it will be useful,
|
|
17
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
19
|
+
# General Public License for more details.
|
|
20
|
+
#
|
|
21
|
+
# The full text of the GPL is available at:
|
|
22
|
+
#
|
|
23
|
+
# https://www.gnu.org/licenses/
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
|
|
26
|
+
from sage.arith.misc import divisors, euler_phi, factorial, gcd
|
|
27
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
28
|
+
from sage.combinat.composition import Composition
|
|
29
|
+
from sage.combinat.misc import DoublyLinkedList
|
|
30
|
+
from sage.misc.misc_c import prod
|
|
31
|
+
from sage.rings.integer import Integer
|
|
32
|
+
from sage.rings.integer_ring import ZZ
|
|
33
|
+
from sage.structure.parent import Parent
|
|
34
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def Necklaces(content):
|
|
38
|
+
r"""
|
|
39
|
+
Return the set of necklaces with evaluation ``content``.
|
|
40
|
+
|
|
41
|
+
A necklace is a list of integers that such that the list is
|
|
42
|
+
the smallest lexicographic representative of all the cyclic shifts
|
|
43
|
+
of the list.
|
|
44
|
+
|
|
45
|
+
.. SEEALSO::
|
|
46
|
+
|
|
47
|
+
:class:`LyndonWords`
|
|
48
|
+
|
|
49
|
+
INPUT:
|
|
50
|
+
|
|
51
|
+
- ``content`` -- list or tuple of nonnegative integers
|
|
52
|
+
|
|
53
|
+
EXAMPLES::
|
|
54
|
+
|
|
55
|
+
sage: Necklaces([2,1,1])
|
|
56
|
+
Necklaces with evaluation [2, 1, 1]
|
|
57
|
+
sage: Necklaces([2,1,1]).cardinality()
|
|
58
|
+
3
|
|
59
|
+
sage: Necklaces([2,1,1]).first()
|
|
60
|
+
[1, 1, 2, 3]
|
|
61
|
+
sage: Necklaces([2,1,1]).last()
|
|
62
|
+
[1, 2, 1, 3]
|
|
63
|
+
sage: Necklaces([2,1,1]).list()
|
|
64
|
+
[[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3]]
|
|
65
|
+
sage: Necklaces([0,2,1,1]).list()
|
|
66
|
+
[[2, 2, 3, 4], [2, 2, 4, 3], [2, 3, 2, 4]]
|
|
67
|
+
sage: Necklaces([2,0,1,1]).list()
|
|
68
|
+
[[1, 1, 3, 4], [1, 1, 4, 3], [1, 3, 1, 4]]
|
|
69
|
+
"""
|
|
70
|
+
return Necklaces_evaluation(content)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Necklaces_evaluation(UniqueRepresentation, Parent):
|
|
74
|
+
"""
|
|
75
|
+
Necklaces with a fixed evaluation (content).
|
|
76
|
+
|
|
77
|
+
INPUT:
|
|
78
|
+
|
|
79
|
+
- ``content`` -- list or tuple of nonnegative integers
|
|
80
|
+
"""
|
|
81
|
+
@staticmethod
|
|
82
|
+
def __classcall_private__(cls, content):
|
|
83
|
+
"""
|
|
84
|
+
Return the correct parent object, with standardized parameters.
|
|
85
|
+
|
|
86
|
+
EXAMPLES::
|
|
87
|
+
|
|
88
|
+
sage: Necklaces([2,1,1]) is Necklaces(Composition([2,1,1]))
|
|
89
|
+
True
|
|
90
|
+
"""
|
|
91
|
+
if not isinstance(content, Composition):
|
|
92
|
+
content = Composition(content)
|
|
93
|
+
return super().__classcall__(cls, content)
|
|
94
|
+
|
|
95
|
+
def __init__(self, content):
|
|
96
|
+
r"""
|
|
97
|
+
Initialize ``self``.
|
|
98
|
+
|
|
99
|
+
TESTS::
|
|
100
|
+
|
|
101
|
+
sage: N = Necklaces([2,2,2])
|
|
102
|
+
sage: N == loads(dumps(N))
|
|
103
|
+
True
|
|
104
|
+
sage: T = Necklaces([2,1])
|
|
105
|
+
sage: TestSuite(T).run()
|
|
106
|
+
"""
|
|
107
|
+
self._content = content
|
|
108
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
109
|
+
|
|
110
|
+
def content(self):
|
|
111
|
+
"""
|
|
112
|
+
Return the content (or evaluation) of the necklaces.
|
|
113
|
+
|
|
114
|
+
EXAMPLES::
|
|
115
|
+
|
|
116
|
+
sage: N = Necklaces([2,2,2])
|
|
117
|
+
sage: N.content()
|
|
118
|
+
[2, 2, 2]
|
|
119
|
+
"""
|
|
120
|
+
return self._content
|
|
121
|
+
|
|
122
|
+
def __repr__(self) -> str:
|
|
123
|
+
r"""
|
|
124
|
+
TESTS::
|
|
125
|
+
|
|
126
|
+
sage: repr(Necklaces([2,1,1]))
|
|
127
|
+
'Necklaces with evaluation [2, 1, 1]'
|
|
128
|
+
"""
|
|
129
|
+
return "Necklaces with evaluation %s" % self._content
|
|
130
|
+
|
|
131
|
+
def __contains__(self, x) -> bool:
|
|
132
|
+
r"""
|
|
133
|
+
Return ``True`` if ``x`` is the smallest word of all its cyclic shifts
|
|
134
|
+
and the content vector of ``x`` is equal to ``content``.
|
|
135
|
+
|
|
136
|
+
INPUT:
|
|
137
|
+
|
|
138
|
+
- ``x`` -- list of integers
|
|
139
|
+
|
|
140
|
+
EXAMPLES::
|
|
141
|
+
|
|
142
|
+
sage: [2,1,2,1] in Necklaces([2,2])
|
|
143
|
+
False
|
|
144
|
+
sage: [1,2,1,2] in Necklaces([2,2])
|
|
145
|
+
True
|
|
146
|
+
sage: [1,1,2,2] in Necklaces([2,2])
|
|
147
|
+
True
|
|
148
|
+
sage: [1,2,2,2] in Necklaces([2,2])
|
|
149
|
+
False
|
|
150
|
+
sage: all(n in Necklaces([2,1,3,1]) for n in Necklaces([2,1,3,1]))
|
|
151
|
+
True
|
|
152
|
+
sage: all(n in Necklaces([0,1,2,3]) for n in Necklaces([0,1,2,3]))
|
|
153
|
+
True
|
|
154
|
+
"""
|
|
155
|
+
xl = list(x)
|
|
156
|
+
e = [0] * len(self._content)
|
|
157
|
+
if len(xl) != sum(self._content):
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
# Check to make sure xl is a list of integers
|
|
161
|
+
for i in xl:
|
|
162
|
+
if not isinstance(i, (int, Integer)):
|
|
163
|
+
return False
|
|
164
|
+
if i <= 0:
|
|
165
|
+
return False
|
|
166
|
+
if i > len(self._content):
|
|
167
|
+
return False
|
|
168
|
+
e[i - 1] += 1
|
|
169
|
+
|
|
170
|
+
# Check to make sure the evaluation is the same
|
|
171
|
+
if e != self._content:
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
# Check to make sure that x is lexicographically less
|
|
175
|
+
# than all of its cyclic shifts
|
|
176
|
+
cyclic_shift = xl[:]
|
|
177
|
+
for i in range(len(xl) - 1):
|
|
178
|
+
cyclic_shift = cyclic_shift[1:] + cyclic_shift[:1]
|
|
179
|
+
if cyclic_shift < xl:
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
def cardinality(self) -> Integer:
|
|
185
|
+
r"""
|
|
186
|
+
Return the number of integer necklaces with the evaluation ``content``.
|
|
187
|
+
|
|
188
|
+
The formula for the number of necklaces of content `\alpha`
|
|
189
|
+
a composition of `n` is:
|
|
190
|
+
|
|
191
|
+
.. MATH::
|
|
192
|
+
|
|
193
|
+
\sum_{d|gcd(\alpha)} \phi(d)
|
|
194
|
+
\binom{n/d}{\alpha_1/d, \ldots, \alpha_\ell/d},
|
|
195
|
+
|
|
196
|
+
where `\phi(d)` is the Euler `\phi` function.
|
|
197
|
+
|
|
198
|
+
EXAMPLES::
|
|
199
|
+
|
|
200
|
+
sage: Necklaces([]).cardinality()
|
|
201
|
+
0
|
|
202
|
+
sage: Necklaces([2,2]).cardinality()
|
|
203
|
+
2
|
|
204
|
+
sage: Necklaces([2,3,2]).cardinality()
|
|
205
|
+
30
|
|
206
|
+
sage: Necklaces([0,3,2]).cardinality()
|
|
207
|
+
2
|
|
208
|
+
|
|
209
|
+
Check to make sure that the count matches up with the number of
|
|
210
|
+
necklace words generated.
|
|
211
|
+
|
|
212
|
+
::
|
|
213
|
+
|
|
214
|
+
sage: comps = [[],[2,2],[3,2,7],[4,2],[0,4,2],[2,0,4]] + Compositions(4).list()
|
|
215
|
+
sage: ns = [Necklaces(comp) for comp in comps]
|
|
216
|
+
sage: all(n.cardinality() == len(n.list()) for n in ns) # needs sage.libs.pari
|
|
217
|
+
True
|
|
218
|
+
"""
|
|
219
|
+
evaluation = self._content
|
|
220
|
+
le = list(evaluation)
|
|
221
|
+
if not le:
|
|
222
|
+
return ZZ.zero()
|
|
223
|
+
|
|
224
|
+
n = sum(le)
|
|
225
|
+
|
|
226
|
+
return ZZ.sum(euler_phi(j) * factorial(n // j) //
|
|
227
|
+
prod(factorial(ni // j) for ni in evaluation)
|
|
228
|
+
for j in divisors(gcd(le))) // n
|
|
229
|
+
|
|
230
|
+
def __iter__(self):
|
|
231
|
+
r"""
|
|
232
|
+
An iterator for the integer necklaces with evaluation ``content``.
|
|
233
|
+
|
|
234
|
+
EXAMPLES::
|
|
235
|
+
|
|
236
|
+
sage: Necklaces([]).list() #indirect test
|
|
237
|
+
[]
|
|
238
|
+
sage: Necklaces([1]).list() #indirect test
|
|
239
|
+
[[1]]
|
|
240
|
+
sage: Necklaces([2]).list() #indirect test
|
|
241
|
+
[[1, 1]]
|
|
242
|
+
sage: Necklaces([3]).list() #indirect test
|
|
243
|
+
[[1, 1, 1]]
|
|
244
|
+
sage: Necklaces([3,3]).list() #indirect test
|
|
245
|
+
[[1, 1, 1, 2, 2, 2],
|
|
246
|
+
[1, 1, 2, 1, 2, 2],
|
|
247
|
+
[1, 1, 2, 2, 1, 2],
|
|
248
|
+
[1, 2, 1, 2, 1, 2]]
|
|
249
|
+
sage: Necklaces([2,1,3]).list() #indirect test
|
|
250
|
+
[[1, 1, 2, 3, 3, 3],
|
|
251
|
+
[1, 1, 3, 2, 3, 3],
|
|
252
|
+
[1, 1, 3, 3, 2, 3],
|
|
253
|
+
[1, 1, 3, 3, 3, 2],
|
|
254
|
+
[1, 2, 1, 3, 3, 3],
|
|
255
|
+
[1, 2, 3, 1, 3, 3],
|
|
256
|
+
[1, 2, 3, 3, 1, 3],
|
|
257
|
+
[1, 3, 1, 3, 2, 3],
|
|
258
|
+
[1, 3, 1, 3, 3, 2],
|
|
259
|
+
[1, 3, 2, 1, 3, 3]]
|
|
260
|
+
"""
|
|
261
|
+
if not self._content:
|
|
262
|
+
return
|
|
263
|
+
k = 0
|
|
264
|
+
while not self._content[k]: # == 0
|
|
265
|
+
k += 1
|
|
266
|
+
for z in _sfc(self._content[k:]):
|
|
267
|
+
yield [x + 1 + k for x in z]
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
################################
|
|
271
|
+
# Fast Fixed Content Algorithm #
|
|
272
|
+
################################
|
|
273
|
+
def _ffc(content, equality=False):
|
|
274
|
+
"""
|
|
275
|
+
EXAMPLES::
|
|
276
|
+
|
|
277
|
+
sage: from sage.combinat.necklace import _ffc
|
|
278
|
+
sage: list(_ffc([3,3])) #necklaces
|
|
279
|
+
[[0, 1, 0, 1, 0, 1],
|
|
280
|
+
[0, 0, 1, 1, 0, 1],
|
|
281
|
+
[0, 0, 1, 0, 1, 1],
|
|
282
|
+
[0, 0, 0, 1, 1, 1]]
|
|
283
|
+
sage: list(_ffc([3,3], equality=True)) #Lyndon words
|
|
284
|
+
[[0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 1, 1, 1]]
|
|
285
|
+
"""
|
|
286
|
+
e = list(content)
|
|
287
|
+
a = [len(e) - 1] * sum(e)
|
|
288
|
+
r = [0] * sum(e)
|
|
289
|
+
a[0] = 0
|
|
290
|
+
e[0] -= 1
|
|
291
|
+
k = len(e)
|
|
292
|
+
|
|
293
|
+
rng_k = list(range(k))
|
|
294
|
+
rng_k.reverse()
|
|
295
|
+
dll = DoublyLinkedList(rng_k)
|
|
296
|
+
if not e[0]: # == 0
|
|
297
|
+
dll.hide(0)
|
|
298
|
+
|
|
299
|
+
yield from _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False):
|
|
303
|
+
"""
|
|
304
|
+
EXAMPLES::
|
|
305
|
+
|
|
306
|
+
sage: from sage.combinat.necklace import _fast_fixed_content
|
|
307
|
+
sage: from sage.combinat.misc import DoublyLinkedList
|
|
308
|
+
sage: e = [3,3]
|
|
309
|
+
sage: a = [len(e)-1]*sum(e)
|
|
310
|
+
sage: r = [0]*sum(e)
|
|
311
|
+
sage: a[0] = 0
|
|
312
|
+
sage: e[0] -= 1
|
|
313
|
+
sage: k = len(e)
|
|
314
|
+
sage: dll = DoublyLinkedList(list(reversed(range(k))))
|
|
315
|
+
sage: if e[0] == 0: dll.hide(0)
|
|
316
|
+
sage: list(_fast_fixed_content(a,e,2,1,k,r,2,dll))
|
|
317
|
+
[[0, 1, 0, 1, 0, 1],
|
|
318
|
+
[0, 0, 1, 1, 0, 1],
|
|
319
|
+
[0, 0, 1, 0, 1, 1],
|
|
320
|
+
[0, 0, 0, 1, 1, 1]]
|
|
321
|
+
sage: list(_fast_fixed_content(a,e,2,1,k,r,2,dll,True))
|
|
322
|
+
[[0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 1, 1, 1]]
|
|
323
|
+
"""
|
|
324
|
+
n = len(a)
|
|
325
|
+
if content[k - 1] == n - t + 1:
|
|
326
|
+
if content[k - 1] == r[t - p - 1]:
|
|
327
|
+
if equality:
|
|
328
|
+
if n == p:
|
|
329
|
+
yield a
|
|
330
|
+
else:
|
|
331
|
+
if not n % p: # == 0
|
|
332
|
+
yield a
|
|
333
|
+
elif content[k - 1] > r[t - p - 1]:
|
|
334
|
+
yield a
|
|
335
|
+
elif content[0] != n - t + 1:
|
|
336
|
+
j = dll.head()
|
|
337
|
+
sp = s
|
|
338
|
+
while j != 'end' and j >= a[t - p - 1]:
|
|
339
|
+
r[s - 1] = t - s
|
|
340
|
+
a[t - 1] = j
|
|
341
|
+
content[j] -= 1
|
|
342
|
+
|
|
343
|
+
if not content[j]: # == 0
|
|
344
|
+
dll.hide(j)
|
|
345
|
+
|
|
346
|
+
if j != k - 1:
|
|
347
|
+
sp = t + 1
|
|
348
|
+
|
|
349
|
+
if j == a[t - p - 1]:
|
|
350
|
+
yield from _fast_fixed_content(a[:], content, t + 1, p,
|
|
351
|
+
k, r, sp, dll,
|
|
352
|
+
equality=equality)
|
|
353
|
+
else:
|
|
354
|
+
yield from _fast_fixed_content(a[:], content, t + 1, t,
|
|
355
|
+
k, r, sp, dll,
|
|
356
|
+
equality=equality)
|
|
357
|
+
|
|
358
|
+
if not content[j]: # == 0
|
|
359
|
+
dll.unhide(j)
|
|
360
|
+
|
|
361
|
+
content[j] += 1
|
|
362
|
+
j = dll.next(j)
|
|
363
|
+
a[t - 1] = k - 1
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
# ###############################
|
|
367
|
+
# List Fixed Content Algorithm #
|
|
368
|
+
# ###############################
|
|
369
|
+
def _lfc(content, equality=False):
|
|
370
|
+
"""
|
|
371
|
+
EXAMPLES::
|
|
372
|
+
|
|
373
|
+
sage: from sage.combinat.necklace import _lfc
|
|
374
|
+
sage: list(_lfc([3,3])) #necklaces
|
|
375
|
+
[[0, 1, 0, 1, 0, 1],
|
|
376
|
+
[0, 0, 1, 1, 0, 1],
|
|
377
|
+
[0, 0, 1, 0, 1, 1],
|
|
378
|
+
[0, 0, 0, 1, 1, 1]]
|
|
379
|
+
sage: list(_lfc([3,3], equality=True)) #Lyndon words
|
|
380
|
+
[[0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 1, 1, 1]]
|
|
381
|
+
"""
|
|
382
|
+
content = list(content)
|
|
383
|
+
a = [0] * sum(content)
|
|
384
|
+
content[0] -= 1
|
|
385
|
+
k = len(content)
|
|
386
|
+
|
|
387
|
+
rng_k = list(range(k))
|
|
388
|
+
rng_k.reverse()
|
|
389
|
+
dll = DoublyLinkedList(rng_k)
|
|
390
|
+
|
|
391
|
+
if not content[0]: # == 0
|
|
392
|
+
dll.hide(0)
|
|
393
|
+
|
|
394
|
+
yield from _list_fixed_content(a, content, 2, 1, k, dll, equality=equality)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _list_fixed_content(a, content, t, p, k, dll, equality=False):
|
|
398
|
+
"""
|
|
399
|
+
EXAMPLES::
|
|
400
|
+
|
|
401
|
+
sage: from sage.combinat.necklace import _list_fixed_content
|
|
402
|
+
sage: from sage.combinat.misc import DoublyLinkedList
|
|
403
|
+
sage: e = [3,3]
|
|
404
|
+
sage: a = [0]*sum(e)
|
|
405
|
+
sage: e[0] -= 1
|
|
406
|
+
sage: k = len(e)
|
|
407
|
+
sage: dll = DoublyLinkedList(list(reversed(range(k))))
|
|
408
|
+
sage: if e[0] == 0: dll.hide(0)
|
|
409
|
+
sage: list(_list_fixed_content(a,e,2,1,k,dll))
|
|
410
|
+
[[0, 1, 0, 1, 0, 1],
|
|
411
|
+
[0, 0, 1, 1, 0, 1],
|
|
412
|
+
[0, 0, 1, 0, 1, 1],
|
|
413
|
+
[0, 0, 0, 1, 1, 1]]
|
|
414
|
+
sage: list(_list_fixed_content(a,e,2,1,k,dll,True))
|
|
415
|
+
[[0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 1, 1, 1]]
|
|
416
|
+
"""
|
|
417
|
+
n = len(a)
|
|
418
|
+
if t > n:
|
|
419
|
+
if equality:
|
|
420
|
+
if n == p:
|
|
421
|
+
yield a
|
|
422
|
+
else:
|
|
423
|
+
if not n % p: # == 0
|
|
424
|
+
yield a
|
|
425
|
+
else:
|
|
426
|
+
j = dll.head()
|
|
427
|
+
while j != 'end' and j >= a[t - p - 1]:
|
|
428
|
+
a[t - 1] = j
|
|
429
|
+
content[j] -= 1
|
|
430
|
+
|
|
431
|
+
if not content[j]: # == 0
|
|
432
|
+
dll.hide(j)
|
|
433
|
+
|
|
434
|
+
if j == a[t - p - 1]:
|
|
435
|
+
yield from _list_fixed_content(a[:], content[:], t + 1, p,
|
|
436
|
+
k, dll, equality=equality)
|
|
437
|
+
else:
|
|
438
|
+
yield from _list_fixed_content(a[:], content[:], t + 1, t,
|
|
439
|
+
k, dll, equality=equality)
|
|
440
|
+
|
|
441
|
+
if not content[j]: # == 0
|
|
442
|
+
dll.unhide(j)
|
|
443
|
+
|
|
444
|
+
content[j] += 1
|
|
445
|
+
j = dll.next(j)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
##################################
|
|
449
|
+
# Simple Fixed Content Algorithm #
|
|
450
|
+
##################################
|
|
451
|
+
def _sfc(content, equality=False):
|
|
452
|
+
"""
|
|
453
|
+
This wrapper function calls :meth:`sage.combinat.necklace._simple_fixed_content`.
|
|
454
|
+
If ``equality`` is ``True`` the function returns Lyndon words with content
|
|
455
|
+
vector equal to ``content``, otherwise it returns necklaces.
|
|
456
|
+
|
|
457
|
+
INPUT:
|
|
458
|
+
|
|
459
|
+
- ``content`` -- list of nonnegative integers with no leading 0s
|
|
460
|
+
- ``equality`` -- boolean (default: ``True``)
|
|
461
|
+
|
|
462
|
+
.. WARNING::
|
|
463
|
+
|
|
464
|
+
You will get incorrect results if there are leading 0s in ``content``.
|
|
465
|
+
See :issue:`12997` and :issue:`17436`.
|
|
466
|
+
|
|
467
|
+
EXAMPLES::
|
|
468
|
+
|
|
469
|
+
sage: from sage.combinat.necklace import _sfc
|
|
470
|
+
sage: list(_sfc([3,3])) #necklaces
|
|
471
|
+
[[0, 0, 0, 1, 1, 1],
|
|
472
|
+
[0, 0, 1, 0, 1, 1],
|
|
473
|
+
[0, 0, 1, 1, 0, 1],
|
|
474
|
+
[0, 1, 0, 1, 0, 1]]
|
|
475
|
+
sage: list(_sfc([3,3], equality=True)) #Lyndon words
|
|
476
|
+
[[0, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 1]]
|
|
477
|
+
"""
|
|
478
|
+
content = list(content)
|
|
479
|
+
a = [0] * sum(content)
|
|
480
|
+
content[0] -= 1
|
|
481
|
+
k = len(content)
|
|
482
|
+
return _simple_fixed_content(a, content, 2, 1, k, equality=equality)
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def _simple_fixed_content(a, content, t, p, k, equality=False):
|
|
486
|
+
"""
|
|
487
|
+
EXAMPLES::
|
|
488
|
+
|
|
489
|
+
sage: from sage.combinat.necklace import _simple_fixed_content
|
|
490
|
+
sage: content = [3,3]
|
|
491
|
+
sage: a = [0]*sum(content)
|
|
492
|
+
sage: content[0] -= 1
|
|
493
|
+
sage: k = len(content); k
|
|
494
|
+
2
|
|
495
|
+
sage: list(_simple_fixed_content(a, content, 2, 1, k))
|
|
496
|
+
[[0, 0, 0, 1, 1, 1],
|
|
497
|
+
[0, 0, 1, 0, 1, 1],
|
|
498
|
+
[0, 0, 1, 1, 0, 1],
|
|
499
|
+
[0, 1, 0, 1, 0, 1]]
|
|
500
|
+
sage: list(_simple_fixed_content(a, content, 2, 1, k, True))
|
|
501
|
+
[[0, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 1]]
|
|
502
|
+
"""
|
|
503
|
+
n = len(a)
|
|
504
|
+
if t > n:
|
|
505
|
+
if equality:
|
|
506
|
+
if n == p:
|
|
507
|
+
yield a
|
|
508
|
+
else:
|
|
509
|
+
if not n % p: # == 0
|
|
510
|
+
yield a
|
|
511
|
+
else:
|
|
512
|
+
r = list(range(a[t - p - 1], k))
|
|
513
|
+
for j in r:
|
|
514
|
+
if content[j] > 0:
|
|
515
|
+
a[t - 1] = j
|
|
516
|
+
content[j] -= 1
|
|
517
|
+
if j == a[t - p - 1]:
|
|
518
|
+
yield from _simple_fixed_content(a[:], content, t + 1, p,
|
|
519
|
+
k, equality=equality)
|
|
520
|
+
else:
|
|
521
|
+
yield from _simple_fixed_content(a[:], content, t + 1, t,
|
|
522
|
+
k, equality=equality)
|
|
523
|
+
content[j] += 1
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def _lyn(w):
|
|
527
|
+
"""
|
|
528
|
+
Return the length of the longest prefix of ``w`` that is a Lyndon word.
|
|
529
|
+
|
|
530
|
+
EXAMPLES::
|
|
531
|
+
|
|
532
|
+
sage: import sage.combinat.necklace as necklace
|
|
533
|
+
sage: necklace._lyn([0,1,1,0,0,1,2])
|
|
534
|
+
3
|
|
535
|
+
sage: necklace._lyn([0,0,0,1])
|
|
536
|
+
4
|
|
537
|
+
sage: necklace._lyn([2,1,0,0,2,2,1])
|
|
538
|
+
1
|
|
539
|
+
"""
|
|
540
|
+
p = 1
|
|
541
|
+
k = max(w) + 1
|
|
542
|
+
for i in range(1, len(w)):
|
|
543
|
+
b = w[i]
|
|
544
|
+
a = w[:i]
|
|
545
|
+
if b < a[i - p] or b > k - 1:
|
|
546
|
+
return p
|
|
547
|
+
elif b == a[i - p]:
|
|
548
|
+
pass
|
|
549
|
+
else:
|
|
550
|
+
p = i + 1
|
|
551
|
+
return p
|