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,1205 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.graphs sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Fully commutative stable Grothendieck crystal
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Jianping Pan (2020-08-31): initial version
|
|
9
|
+
|
|
10
|
+
- Wencin Poh (2020-08-31): initial version
|
|
11
|
+
|
|
12
|
+
- Anne Schilling (2020-08-31): initial version
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
# Copyright (C) 2020 Jianping Pan <jppan at math dot ucdavis dot edu>
|
|
17
|
+
# Wencin Poh <wpoh at ucdavis dot edu>
|
|
18
|
+
# Anne Schilling <anne at math dot ucdavis dot edu>
|
|
19
|
+
#
|
|
20
|
+
# This program is free software: you can redistribute it and/or modify
|
|
21
|
+
# it under the terms of the GNU General Public License as published by
|
|
22
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
23
|
+
# (at your option) any later version.
|
|
24
|
+
# https://www.gnu.org/licenses/
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
|
|
27
|
+
from sage.structure.element import Element
|
|
28
|
+
from sage.structure.parent import Parent
|
|
29
|
+
from sage.structure.richcmp import richcmp_by_eq_and_lt
|
|
30
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
31
|
+
from sage.categories.classical_crystals import ClassicalCrystals
|
|
32
|
+
from sage.categories.enumerated_sets import EnumeratedSets
|
|
33
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
34
|
+
from sage.combinat.root_system.cartan_type import CartanType
|
|
35
|
+
from sage.combinat import permutation
|
|
36
|
+
from sage.rings.integer import Integer
|
|
37
|
+
from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
|
|
38
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
39
|
+
from sage.misc.lazy_import import lazy_import
|
|
40
|
+
|
|
41
|
+
lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class DecreasingHeckeFactorization(Element, metaclass=InheritComparisonClasscallMetaclass):
|
|
45
|
+
"""
|
|
46
|
+
Class of decreasing factorizations in the 0-Hecke monoid.
|
|
47
|
+
|
|
48
|
+
INPUT:
|
|
49
|
+
|
|
50
|
+
- ``t`` -- decreasing factorization inputted as list of lists
|
|
51
|
+
|
|
52
|
+
- ``max_value`` -- maximal value of entries
|
|
53
|
+
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
57
|
+
sage: t = [[3, 2], [], [2, 1]]
|
|
58
|
+
sage: h = DecreasingHeckeFactorization(t, 3); h
|
|
59
|
+
(3, 2)()(2, 1)
|
|
60
|
+
sage: h.excess
|
|
61
|
+
1
|
|
62
|
+
sage: h.factors
|
|
63
|
+
3
|
|
64
|
+
sage: h.max_value
|
|
65
|
+
3
|
|
66
|
+
sage: h.value
|
|
67
|
+
((3, 2), (), (2, 1))
|
|
68
|
+
|
|
69
|
+
sage: u = [[3, 2, 1], [3], [2, 1]]
|
|
70
|
+
sage: h = DecreasingHeckeFactorization(u); h
|
|
71
|
+
(3, 2, 1)(3)(2, 1)
|
|
72
|
+
sage: h.weight()
|
|
73
|
+
(2, 1, 3)
|
|
74
|
+
sage: h.parent()
|
|
75
|
+
Decreasing Hecke factorizations with 3 factors associated to [2, 1, 3, 2, 1] with excess 1
|
|
76
|
+
"""
|
|
77
|
+
@staticmethod
|
|
78
|
+
def __classcall_private__(self, t, max_value=None, parent=None):
|
|
79
|
+
"""
|
|
80
|
+
Assign the correct parent for ``t`` and call ``t`` as an element of that parent.
|
|
81
|
+
|
|
82
|
+
EXAMPLES::
|
|
83
|
+
|
|
84
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
85
|
+
sage: h1 = DecreasingHeckeFactorization([[3, 1], [], [3, 2]])
|
|
86
|
+
sage: h1.parent()
|
|
87
|
+
Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 1
|
|
88
|
+
sage: h2 = DecreasingHeckeFactorization(h1)
|
|
89
|
+
sage: h1 == h2
|
|
90
|
+
True
|
|
91
|
+
|
|
92
|
+
sage: h1 = DecreasingHeckeFactorization([[3, 1], [2, 1], [2, 1]])
|
|
93
|
+
sage: F = h1.parent(); F
|
|
94
|
+
Decreasing Hecke factorizations with 3 factors associated to [1, 3, 2, 1] with excess 2
|
|
95
|
+
sage: h2 = F(h1)
|
|
96
|
+
sage: h1 == h2
|
|
97
|
+
True
|
|
98
|
+
|
|
99
|
+
TESTS::
|
|
100
|
+
|
|
101
|
+
sage: DecreasingHeckeFactorization([[]])
|
|
102
|
+
()
|
|
103
|
+
"""
|
|
104
|
+
_check_decreasing_hecke_factorization(t)
|
|
105
|
+
if isinstance(t, DecreasingHeckeFactorization):
|
|
106
|
+
u = t.value
|
|
107
|
+
if parent is None:
|
|
108
|
+
parent = t.parent()
|
|
109
|
+
else:
|
|
110
|
+
u = t
|
|
111
|
+
if parent is None:
|
|
112
|
+
if max_value is None:
|
|
113
|
+
letters = [x for factor in t for x in factor]
|
|
114
|
+
max_value = max(letters) if letters else 1
|
|
115
|
+
from sage.monoids.hecke_monoid import HeckeMonoid
|
|
116
|
+
S = SymmetricGroup(max_value+1)
|
|
117
|
+
H = HeckeMonoid(S)
|
|
118
|
+
word = H.from_reduced_word(x for factor in t for x in factor).reduced_word()
|
|
119
|
+
factors = len(t)
|
|
120
|
+
excess = sum(len(l) for l in t) - len(word)
|
|
121
|
+
|
|
122
|
+
p = permutation.from_reduced_word(word)
|
|
123
|
+
if p.has_pattern([3,2,1]):
|
|
124
|
+
word = S.from_reduced_word(word)
|
|
125
|
+
parent = DecreasingHeckeFactorizations(word, factors, excess)
|
|
126
|
+
else:
|
|
127
|
+
word = S.from_reduced_word(word)
|
|
128
|
+
parent = FullyCommutativeStableGrothendieckCrystal(word, factors, excess)
|
|
129
|
+
return parent.element_class(parent, u)
|
|
130
|
+
|
|
131
|
+
def __init__(self, parent, t):
|
|
132
|
+
"""
|
|
133
|
+
Initialize a decreasing factorization for ``self`` given the relevant data.
|
|
134
|
+
|
|
135
|
+
EXAMPLES::
|
|
136
|
+
|
|
137
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
138
|
+
sage: t = [[2, 1], [2], [], [1]]
|
|
139
|
+
sage: h1 = DecreasingHeckeFactorization(t); h1
|
|
140
|
+
(2, 1)(2)()(1)
|
|
141
|
+
sage: h1.excess
|
|
142
|
+
1
|
|
143
|
+
sage: h2 = DecreasingHeckeFactorization(t, 2)
|
|
144
|
+
sage: h2.value
|
|
145
|
+
((2, 1), (2,), (), (1,))
|
|
146
|
+
sage: h1 == h2
|
|
147
|
+
True
|
|
148
|
+
|
|
149
|
+
sage: t = [[2, 1], [2], [], [3, 1]]
|
|
150
|
+
sage: h = DecreasingHeckeFactorization(t, 5)
|
|
151
|
+
sage: h.max_value
|
|
152
|
+
5
|
|
153
|
+
sage: h.factors
|
|
154
|
+
4
|
|
155
|
+
sage: h.w
|
|
156
|
+
(1, 2, 1, 3)
|
|
157
|
+
|
|
158
|
+
TESTS::
|
|
159
|
+
|
|
160
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
161
|
+
sage: t1 = [[], [3, 1], [], [2, 1], [1]]
|
|
162
|
+
sage: t2 = [[], [3, 1], [], [2, 1], [2]]
|
|
163
|
+
sage: h1 = DecreasingHeckeFactorization(t1, 3)
|
|
164
|
+
sage: h2 = DecreasingHeckeFactorization(t2, 3)
|
|
165
|
+
sage: h3 = DecreasingHeckeFactorization(t1)
|
|
166
|
+
sage: h1 == h2, h1 == h3
|
|
167
|
+
(False, True)
|
|
168
|
+
sage: h1 != h2, h1 != h3
|
|
169
|
+
(True, False)
|
|
170
|
+
"""
|
|
171
|
+
Element.__init__(self, parent)
|
|
172
|
+
self.factors = parent.factors
|
|
173
|
+
self.max_value = parent.max_value
|
|
174
|
+
self.w = parent.w
|
|
175
|
+
self.excess = parent.excess
|
|
176
|
+
self.value = tuple(tuple(factors) for factors in t)
|
|
177
|
+
|
|
178
|
+
def _repr_(self):
|
|
179
|
+
"""
|
|
180
|
+
Return the representation of ``self``.
|
|
181
|
+
|
|
182
|
+
EXAMPLES::
|
|
183
|
+
|
|
184
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
185
|
+
sage: t = [[], [2, 1], [2], [], [2]]
|
|
186
|
+
sage: h = DecreasingHeckeFactorization(t); h
|
|
187
|
+
()(2, 1)(2)()(2)
|
|
188
|
+
"""
|
|
189
|
+
return "".join("("+repr(list(factor))[1:-1]+")" for factor in self.value)
|
|
190
|
+
|
|
191
|
+
def __hash__(self):
|
|
192
|
+
"""
|
|
193
|
+
Return hash of ``self``.
|
|
194
|
+
|
|
195
|
+
EXAMPLES::
|
|
196
|
+
|
|
197
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
198
|
+
sage: t = [[], [2, 1], [2], [], [2]]
|
|
199
|
+
sage: h1 = DecreasingHeckeFactorization(t)
|
|
200
|
+
sage: h2 = DecreasingHeckeFactorization(t, 3)
|
|
201
|
+
sage: h3 = DecreasingHeckeFactorization(t, 2)
|
|
202
|
+
sage: hash(h1) == hash(h2)
|
|
203
|
+
False
|
|
204
|
+
sage: hash(h1) == hash(h3)
|
|
205
|
+
True
|
|
206
|
+
"""
|
|
207
|
+
return hash((self.max_value, self.value))
|
|
208
|
+
|
|
209
|
+
_richcmp_ = richcmp_by_eq_and_lt("__eq__", "__lt__")
|
|
210
|
+
|
|
211
|
+
def __eq__(self, other):
|
|
212
|
+
"""
|
|
213
|
+
Return ``True`` if ``self`` equals ``other`` and ``False`` otherwise.
|
|
214
|
+
|
|
215
|
+
EXAMPLES::
|
|
216
|
+
|
|
217
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
218
|
+
sage: t = [[], [2, 1], [2], [], [2]]
|
|
219
|
+
sage: h1 = DecreasingHeckeFactorization(t)
|
|
220
|
+
sage: h2 = DecreasingHeckeFactorization(t, 3)
|
|
221
|
+
sage: h1 == h2
|
|
222
|
+
True
|
|
223
|
+
"""
|
|
224
|
+
return isinstance(self, type(other)) and self.value == other.value
|
|
225
|
+
|
|
226
|
+
def __lt__(self, other):
|
|
227
|
+
"""
|
|
228
|
+
Return ``True`` if ``self`` comes before ``other`` and ``False``
|
|
229
|
+
otherwise.
|
|
230
|
+
|
|
231
|
+
We say that `h_1` comes before `h_2` if either weight of `h_1 <` weight of `h_2`
|
|
232
|
+
lexicographically, or if both weights of `h_1` and `h_2` are equal,
|
|
233
|
+
but `h_1 < h_2` lexicographically.
|
|
234
|
+
This ordering is mainly used for sorting or comparison.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
239
|
+
sage: t1 = [[], [2, 1], [], [2, 1], [1]]
|
|
240
|
+
sage: t2 = [[], [2, 1], [], [2, 1], [2]]
|
|
241
|
+
sage: t3 = [[], [2, 1], [2], [1], [1]]
|
|
242
|
+
sage: h1 = DecreasingHeckeFactorization(t1)
|
|
243
|
+
sage: h2 = DecreasingHeckeFactorization(t2)
|
|
244
|
+
sage: h3 = DecreasingHeckeFactorization(t3)
|
|
245
|
+
sage: h1 < h2
|
|
246
|
+
True
|
|
247
|
+
sage: h1 < h3
|
|
248
|
+
False
|
|
249
|
+
"""
|
|
250
|
+
return (self.weight(), self.value) < (other.weight(), other.value)
|
|
251
|
+
|
|
252
|
+
def _latex_(self):
|
|
253
|
+
r"""
|
|
254
|
+
Return LaTeX code for ``self``.
|
|
255
|
+
|
|
256
|
+
EXAMPLES::
|
|
257
|
+
|
|
258
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
259
|
+
sage: t = [[2], [2, 1], [], [4, 3, 1]]
|
|
260
|
+
sage: h = DecreasingHeckeFactorization(t, 6)
|
|
261
|
+
sage: latex(h)
|
|
262
|
+
\left(2\right)\left(2, 1\right)\left(\;\right)\left(4, 3, 1\right)
|
|
263
|
+
"""
|
|
264
|
+
s = ""
|
|
265
|
+
for factor in self.value:
|
|
266
|
+
if factor:
|
|
267
|
+
s += r"\left("+repr(list(factor))[1:-1]+r"\right)"
|
|
268
|
+
else:
|
|
269
|
+
s += r"\left(\;\right)"
|
|
270
|
+
return s
|
|
271
|
+
|
|
272
|
+
def weight(self):
|
|
273
|
+
"""
|
|
274
|
+
Return the weight of ``self``.
|
|
275
|
+
|
|
276
|
+
EXAMPLES::
|
|
277
|
+
|
|
278
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
279
|
+
sage: t = [[2], [2, 1], [], [4, 3, 1]]
|
|
280
|
+
sage: h = DecreasingHeckeFactorization(t, 6)
|
|
281
|
+
sage: h.weight()
|
|
282
|
+
(3, 0, 2, 1)
|
|
283
|
+
"""
|
|
284
|
+
return tuple([len(l) for l in reversed(self.value)])
|
|
285
|
+
|
|
286
|
+
def to_word(self):
|
|
287
|
+
"""
|
|
288
|
+
Return the word associated to ``self`` in the 0-Hecke monoid.
|
|
289
|
+
|
|
290
|
+
EXAMPLES::
|
|
291
|
+
|
|
292
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
293
|
+
sage: t = [[2], [], [2, 1], [4, 3, 1]]
|
|
294
|
+
sage: h = DecreasingHeckeFactorization(t)
|
|
295
|
+
sage: h.to_word()
|
|
296
|
+
[2, 2, 1, 4, 3, 1]
|
|
297
|
+
"""
|
|
298
|
+
return [j for factors in self.value for j in factors]
|
|
299
|
+
|
|
300
|
+
def to_increasing_hecke_biword(self):
|
|
301
|
+
"""
|
|
302
|
+
Return the associated increasing Hecke biword of ``self``.
|
|
303
|
+
|
|
304
|
+
EXAMPLES::
|
|
305
|
+
|
|
306
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
307
|
+
sage: t = [[2], [], [2, 1],[4, 3, 1]]
|
|
308
|
+
sage: h = DecreasingHeckeFactorization(t, 4)
|
|
309
|
+
sage: h.to_increasing_hecke_biword()
|
|
310
|
+
[[1, 1, 1, 2, 2, 4], [1, 3, 4, 1, 2, 2]]
|
|
311
|
+
"""
|
|
312
|
+
L = [[],[]]
|
|
313
|
+
for j in range(len(self.value)):
|
|
314
|
+
L[1] += list(self.value[-j-1][::-1])
|
|
315
|
+
L[0] += [j+1]*len(self.value[-j-1])
|
|
316
|
+
return L
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
class DecreasingHeckeFactorizations(UniqueRepresentation, Parent):
|
|
320
|
+
"""
|
|
321
|
+
Set of decreasing factorizations in the 0-Hecke monoid.
|
|
322
|
+
|
|
323
|
+
INPUT:
|
|
324
|
+
|
|
325
|
+
- ``w`` -- an element in the symmetric group
|
|
326
|
+
|
|
327
|
+
- ``factors`` -- the number of factors in the factorization
|
|
328
|
+
|
|
329
|
+
- ``excess`` -- the total number of letters in the factorization minus the length of a reduced word for ``w``
|
|
330
|
+
|
|
331
|
+
EXAMPLES::
|
|
332
|
+
|
|
333
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
334
|
+
sage: S = SymmetricGroup(3+1)
|
|
335
|
+
sage: w = S.from_reduced_word([1, 3, 2, 1])
|
|
336
|
+
sage: F = DecreasingHeckeFactorizations(w, 3, 3); F
|
|
337
|
+
Decreasing Hecke factorizations with 3 factors associated to [1, 3, 2, 1] with excess 3
|
|
338
|
+
sage: F.list()
|
|
339
|
+
[(3, 1)(3, 1)(3, 2, 1), (3, 1)(3, 2, 1)(2, 1), (3, 2, 1)(2, 1)(2, 1)]
|
|
340
|
+
"""
|
|
341
|
+
@staticmethod
|
|
342
|
+
def __classcall_private__(cls, w, factors, excess):
|
|
343
|
+
"""
|
|
344
|
+
Classcall to mend the input.
|
|
345
|
+
|
|
346
|
+
EXAMPLES::
|
|
347
|
+
|
|
348
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
349
|
+
sage: S = SymmetricGroup(3+1)
|
|
350
|
+
sage: w = S.from_reduced_word([1, 2 ,1])
|
|
351
|
+
sage: F = DecreasingHeckeFactorizations(w, 4, 1); F
|
|
352
|
+
Decreasing Hecke factorizations with 4 factors associated to [1, 2, 1] with excess 1
|
|
353
|
+
|
|
354
|
+
sage: from sage.monoids.hecke_monoid import HeckeMonoid
|
|
355
|
+
sage: H = HeckeMonoid(SymmetricGroup(3+1))
|
|
356
|
+
sage: w = H.from_reduced_word([1, 2 ,1])
|
|
357
|
+
sage: G = DecreasingHeckeFactorizations(w, 4, 1); G
|
|
358
|
+
Decreasing Hecke factorizations with 4 factors associated to [1, 2, 1] with excess 1
|
|
359
|
+
sage: F is G
|
|
360
|
+
True
|
|
361
|
+
"""
|
|
362
|
+
from sage.monoids.hecke_monoid import HeckeMonoid
|
|
363
|
+
if isinstance(w.parent(), SymmetricGroup):
|
|
364
|
+
H = HeckeMonoid(w.parent())
|
|
365
|
+
w = H.from_reduced_word(w.reduced_word())
|
|
366
|
+
if (not w.reduced_word()) and excess != 0:
|
|
367
|
+
raise ValueError("excess must be 0 for the empty word")
|
|
368
|
+
return super().__classcall__(cls, w, factors, excess)
|
|
369
|
+
|
|
370
|
+
def __init__(self, w, factors, excess):
|
|
371
|
+
"""
|
|
372
|
+
Initialize a set for ``self`` given reduced word ``w`` in the symmetric group,
|
|
373
|
+
number of factors ``factors`` and``excess`` extra letters.
|
|
374
|
+
|
|
375
|
+
EXAMPLES::
|
|
376
|
+
|
|
377
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
378
|
+
sage: S = SymmetricGroup(3+1)
|
|
379
|
+
sage: w = S.from_reduced_word([2, 1, 3, 2, 1])
|
|
380
|
+
sage: F = DecreasingHeckeFactorizations(w, 4, 2)
|
|
381
|
+
sage: F.w
|
|
382
|
+
(2, 1, 3, 2, 1)
|
|
383
|
+
sage: F.factors
|
|
384
|
+
4
|
|
385
|
+
sage: F.excess
|
|
386
|
+
2
|
|
387
|
+
sage: F.H
|
|
388
|
+
0-Hecke monoid of the Symmetric group of order 4! as a permutation group
|
|
389
|
+
|
|
390
|
+
TESTS::
|
|
391
|
+
|
|
392
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
393
|
+
sage: S = SymmetricGroup(2+1)
|
|
394
|
+
sage: w = S.from_reduced_word([1, 2, 1])
|
|
395
|
+
sage: F = DecreasingHeckeFactorizations(w, 3, 1)
|
|
396
|
+
sage: TestSuite(F).run()
|
|
397
|
+
"""
|
|
398
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
399
|
+
self.w = tuple(w.reduced_word())
|
|
400
|
+
self.factors = factors
|
|
401
|
+
self.H = w.parent()
|
|
402
|
+
self.max_value = len(self.H.gens())
|
|
403
|
+
self.excess = excess
|
|
404
|
+
|
|
405
|
+
def _repr_(self):
|
|
406
|
+
"""
|
|
407
|
+
Return a representation of ``self``.
|
|
408
|
+
|
|
409
|
+
EXAMPLES::
|
|
410
|
+
|
|
411
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
412
|
+
sage: S = SymmetricGroup(3+1)
|
|
413
|
+
sage: w = S.from_reduced_word([2, 1, 3, 2])
|
|
414
|
+
sage: DecreasingHeckeFactorizations(w, 3, 1)
|
|
415
|
+
Decreasing Hecke factorizations with 3 factors associated to [2, 1, 3, 2] with excess 1
|
|
416
|
+
"""
|
|
417
|
+
return "Decreasing Hecke factorizations with {} factors associated to {} with excess {}".format(self.factors, list(self.w), self.excess)
|
|
418
|
+
|
|
419
|
+
def list(self):
|
|
420
|
+
"""
|
|
421
|
+
Return list of all elements of ``self``.
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorizations
|
|
426
|
+
sage: S = SymmetricGroup(3+1)
|
|
427
|
+
sage: w = S.from_reduced_word([1, 3, 2, 1])
|
|
428
|
+
sage: F = DecreasingHeckeFactorizations(w, 3, 3)
|
|
429
|
+
sage: F.list()
|
|
430
|
+
[(3, 1)(3, 1)(3, 2, 1), (3, 1)(3, 2, 1)(2, 1), (3, 2, 1)(2, 1)(2, 1)]
|
|
431
|
+
"""
|
|
432
|
+
return _generate_decreasing_hecke_factorizations(self.w, self.factors, self.excess, parent=self)
|
|
433
|
+
|
|
434
|
+
# temporary workaround while an_element is overridden by Parent
|
|
435
|
+
_an_element_ = EnumeratedSets.ParentMethods._an_element_
|
|
436
|
+
|
|
437
|
+
Element = DecreasingHeckeFactorization
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
class FullyCommutativeStableGrothendieckCrystal(UniqueRepresentation, Parent):
|
|
441
|
+
"""
|
|
442
|
+
The crystal on fully commutative decreasing factorizations in the 0-Hecke
|
|
443
|
+
monoid, as introduced by [MPPS2020]_.
|
|
444
|
+
|
|
445
|
+
INPUT:
|
|
446
|
+
|
|
447
|
+
- ``w`` -- an element in the symmetric group or a (skew) shape
|
|
448
|
+
|
|
449
|
+
- ``factors`` -- the number of factors in the factorization
|
|
450
|
+
|
|
451
|
+
- ``excess`` -- the total number of letters in the factorization minus the
|
|
452
|
+
length of a reduced word for ``w``
|
|
453
|
+
|
|
454
|
+
- ``shape`` -- boolean (default: ``False``); indicator for input ``w``,
|
|
455
|
+
``True`` if ``w`` is entered as a (skew) shape and ``False`` otherwise
|
|
456
|
+
|
|
457
|
+
EXAMPLES::
|
|
458
|
+
|
|
459
|
+
sage: S = SymmetricGroup(3+1)
|
|
460
|
+
sage: w = S.from_reduced_word([1, 3, 2])
|
|
461
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2); B
|
|
462
|
+
Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 2
|
|
463
|
+
sage: B.list()
|
|
464
|
+
[(1)(3, 1)(3, 2),
|
|
465
|
+
(3, 1)(1)(3, 2),
|
|
466
|
+
(3, 1)(3, 1)(2),
|
|
467
|
+
(3)(3, 1)(3, 2),
|
|
468
|
+
(3, 1)(3)(3, 2),
|
|
469
|
+
(3, 1)(3, 2)(2)]
|
|
470
|
+
|
|
471
|
+
We can also access the crystal by specifying a skew shape::
|
|
472
|
+
|
|
473
|
+
sage: crystals.FullyCommutativeStableGrothendieck([[2, 2], [1]], 4, 1, shape=True)
|
|
474
|
+
Fully commutative stable Grothendieck crystal of type A_3 associated to [2, 1, 3] with excess 1
|
|
475
|
+
|
|
476
|
+
We can compute the highest weight elements::
|
|
477
|
+
|
|
478
|
+
sage: hw = [w for w in B if w.is_highest_weight()]
|
|
479
|
+
sage: hw
|
|
480
|
+
[(1)(3, 1)(3, 2), (3)(3, 1)(3, 2)]
|
|
481
|
+
sage: hw[0].weight()
|
|
482
|
+
(2, 2, 1)
|
|
483
|
+
|
|
484
|
+
The crystal operators themselves move elements between adjacent factors::
|
|
485
|
+
|
|
486
|
+
sage: b = hw[0]; b
|
|
487
|
+
(1)(3, 1)(3, 2)
|
|
488
|
+
sage: b.f(2)
|
|
489
|
+
(3, 1)(1)(3, 2)
|
|
490
|
+
"""
|
|
491
|
+
@staticmethod
|
|
492
|
+
def __classcall_private__(cls, w, factors, excess, shape=False):
|
|
493
|
+
"""
|
|
494
|
+
Classcall to mend the input.
|
|
495
|
+
|
|
496
|
+
EXAMPLES::
|
|
497
|
+
|
|
498
|
+
sage: A = crystals.FullyCommutativeStableGrothendieck([[3, 3], [2, 1]], 4, 1, shape=True); A
|
|
499
|
+
Fully commutative stable Grothendieck crystal of type A_3 associated to [3, 2, 4] with excess 1
|
|
500
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(SkewPartition([[3, 3], [2, 1]]), 4, 1, shape=True)
|
|
501
|
+
sage: A is B
|
|
502
|
+
True
|
|
503
|
+
|
|
504
|
+
sage: C = crystals.FullyCommutativeStableGrothendieck((2, 1), 3, 2, shape=True); C
|
|
505
|
+
Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 2
|
|
506
|
+
sage: D = crystals.FullyCommutativeStableGrothendieck(Partition([2, 1]), 3, 2, shape=True)
|
|
507
|
+
sage: C is D
|
|
508
|
+
True
|
|
509
|
+
"""
|
|
510
|
+
from sage.monoids.hecke_monoid import HeckeMonoid
|
|
511
|
+
if shape:
|
|
512
|
+
from sage.combinat.partition import _Partitions
|
|
513
|
+
from sage.combinat.skew_partition import SkewPartition
|
|
514
|
+
cond1 = isinstance(w, (tuple, list)) and len(w) == 2 and w[0] in _Partitions and w[1] in _Partitions
|
|
515
|
+
cond2 = isinstance(w, SkewPartition)
|
|
516
|
+
if cond1 or cond2:
|
|
517
|
+
sh = SkewPartition([w[0], w[1]])
|
|
518
|
+
elif w in _Partitions:
|
|
519
|
+
sh = SkewPartition([w, []])
|
|
520
|
+
else:
|
|
521
|
+
raise ValueError("w needs to be a (skew) partition")
|
|
522
|
+
word = _to_reduced_word(sh)
|
|
523
|
+
max_value = max(word) if word else 1
|
|
524
|
+
H = HeckeMonoid(SymmetricGroup(max_value+1))
|
|
525
|
+
w = H.from_reduced_word(word)
|
|
526
|
+
else:
|
|
527
|
+
if isinstance(w.parent(), SymmetricGroup):
|
|
528
|
+
H = HeckeMonoid(w.parent())
|
|
529
|
+
w = H.from_reduced_word(w.reduced_word())
|
|
530
|
+
if (not w.reduced_word()) and excess != 0:
|
|
531
|
+
raise ValueError("excess must be 0 for the empty word")
|
|
532
|
+
return super().__classcall__(cls, w, factors, excess)
|
|
533
|
+
|
|
534
|
+
def __init__(self, w, factors, excess):
|
|
535
|
+
"""
|
|
536
|
+
Initialize a crystal for ``self`` given reduced word ``w`` in the symmetric group,
|
|
537
|
+
number of factors ``factors`` and``excess`` extra letters.
|
|
538
|
+
|
|
539
|
+
EXAMPLES::
|
|
540
|
+
|
|
541
|
+
sage: S = SymmetricGroup(3+1)
|
|
542
|
+
sage: w = S.from_reduced_word([1, 3, 2])
|
|
543
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
|
|
544
|
+
sage: B.w
|
|
545
|
+
(1, 3, 2)
|
|
546
|
+
sage: B.factors
|
|
547
|
+
3
|
|
548
|
+
sage: B.excess
|
|
549
|
+
2
|
|
550
|
+
sage: B.H
|
|
551
|
+
0-Hecke monoid of the Symmetric group of order 4! as a permutation group
|
|
552
|
+
|
|
553
|
+
The reduced word ``w`` should be fully commutative, that is, its
|
|
554
|
+
associated permutation should avoid the pattern 321::
|
|
555
|
+
|
|
556
|
+
sage: S = SymmetricGroup(3+1)
|
|
557
|
+
sage: w = S.from_reduced_word([1, 2, 1])
|
|
558
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
|
|
559
|
+
Traceback (most recent call last):
|
|
560
|
+
...
|
|
561
|
+
ValueError: w should be fully commutative
|
|
562
|
+
|
|
563
|
+
TESTS::
|
|
564
|
+
|
|
565
|
+
sage: S = SymmetricGroup(3+1)
|
|
566
|
+
sage: w = S.from_reduced_word([2, 3, 1])
|
|
567
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
|
|
568
|
+
sage: TestSuite(B).run()
|
|
569
|
+
"""
|
|
570
|
+
# Check if w is fully commutative
|
|
571
|
+
word = w.reduced_word()
|
|
572
|
+
p = permutation.from_reduced_word(word)
|
|
573
|
+
if p.has_pattern([3,2,1]):
|
|
574
|
+
raise ValueError("w should be fully commutative")
|
|
575
|
+
|
|
576
|
+
Parent.__init__(self, category=ClassicalCrystals())
|
|
577
|
+
self.w = tuple(word)
|
|
578
|
+
self.factors = factors
|
|
579
|
+
self.H = w.parent()
|
|
580
|
+
self.max_value = len(self.H.gens())
|
|
581
|
+
self.excess = excess
|
|
582
|
+
self._cartan_type = CartanType(['A', self.factors-1])
|
|
583
|
+
|
|
584
|
+
@lazy_attribute
|
|
585
|
+
def module_generators(self):
|
|
586
|
+
"""
|
|
587
|
+
Return generators for ``self`` as a crystal.
|
|
588
|
+
|
|
589
|
+
EXAMPLES::
|
|
590
|
+
|
|
591
|
+
sage: S = SymmetricGroup(3+1)
|
|
592
|
+
sage: w = S.from_reduced_word([1, 3, 2])
|
|
593
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
|
|
594
|
+
sage: B.module_generators
|
|
595
|
+
((1)(3, 1)(3, 2), (3)(3, 1)(3, 2))
|
|
596
|
+
sage: C = crystals.FullyCommutativeStableGrothendieck(w, 4, 2)
|
|
597
|
+
sage: C.module_generators
|
|
598
|
+
(()(1)(3, 1)(3, 2),
|
|
599
|
+
()(3)(3, 1)(3, 2),
|
|
600
|
+
(1)(1)(1)(3, 2),
|
|
601
|
+
(1)(1)(3)(3, 2),
|
|
602
|
+
(1)(3)(3)(3, 2))
|
|
603
|
+
"""
|
|
604
|
+
return tuple(self(x).to_highest_weight()[0] for x in _lowest_weights(self.w, self.factors, self.excess, parent=self))
|
|
605
|
+
|
|
606
|
+
def _repr_(self):
|
|
607
|
+
"""
|
|
608
|
+
Return a representation of ``self``.
|
|
609
|
+
|
|
610
|
+
EXAMPLES::
|
|
611
|
+
|
|
612
|
+
sage: S = SymmetricGroup(3+1)
|
|
613
|
+
sage: w = S.from_reduced_word([2, 1, 3, 2])
|
|
614
|
+
sage: crystals.FullyCommutativeStableGrothendieck(w, 3, 1)
|
|
615
|
+
Fully commutative stable Grothendieck crystal of type A_2 associated to [2, 1, 3, 2] with excess 1
|
|
616
|
+
"""
|
|
617
|
+
return "Fully commutative stable Grothendieck crystal of type A_{} associated to {} with excess {}".format(self.factors-1, list(self.w), self.excess)
|
|
618
|
+
|
|
619
|
+
class Element(DecreasingHeckeFactorization):
|
|
620
|
+
def __init__(self, parent, t):
|
|
621
|
+
"""
|
|
622
|
+
Create an instance ``self`` of element ``t``.
|
|
623
|
+
|
|
624
|
+
This method takes into account the constraints on the word,
|
|
625
|
+
the number of factors, and excess statistic associated to the parent class.
|
|
626
|
+
|
|
627
|
+
EXAMPLES::
|
|
628
|
+
|
|
629
|
+
sage: S = SymmetricGroup(3+1)
|
|
630
|
+
sage: w = S.from_reduced_word([1, 3, 2])
|
|
631
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
|
|
632
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization
|
|
633
|
+
sage: h = DecreasingHeckeFactorization([[3, 1], [3], [3, 2]], 4)
|
|
634
|
+
sage: u = B(h); u.value
|
|
635
|
+
((3, 1), (3,), (3, 2))
|
|
636
|
+
sage: v = B([[3, 1], [3], [3, 2]]); v.value
|
|
637
|
+
((3, 1), (3,), (3, 2))
|
|
638
|
+
"""
|
|
639
|
+
u = t
|
|
640
|
+
if isinstance(t, DecreasingHeckeFactorization):
|
|
641
|
+
u = t.value
|
|
642
|
+
_check_decreasing_hecke_factorization(t)
|
|
643
|
+
_check_containment(t, parent)
|
|
644
|
+
DecreasingHeckeFactorization.__init__(self, parent, u)
|
|
645
|
+
|
|
646
|
+
def e(self, i):
|
|
647
|
+
"""
|
|
648
|
+
Return the action of `e_i` on ``self`` using the rules described in [MPPS2020]_.
|
|
649
|
+
|
|
650
|
+
EXAMPLES::
|
|
651
|
+
|
|
652
|
+
sage: S = SymmetricGroup(4+1)
|
|
653
|
+
sage: w = S.from_reduced_word([2, 1, 4, 3, 2])
|
|
654
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 3)
|
|
655
|
+
sage: h = B([[4, 2], [4, 2, 1], [3, 2], [2]]); h
|
|
656
|
+
(4, 2)(4, 2, 1)(3, 2)(2)
|
|
657
|
+
sage: h.e(1)
|
|
658
|
+
(4, 2)(4, 2, 1)(3)(3, 2)
|
|
659
|
+
sage: h.e(2)
|
|
660
|
+
(4, 2)(2, 1)(4, 3, 2)(2)
|
|
661
|
+
sage: h.e(3)
|
|
662
|
+
"""
|
|
663
|
+
P = self.parent()
|
|
664
|
+
m = P.factors
|
|
665
|
+
L = list(self.value[m-i-1])
|
|
666
|
+
R = list(self.value[m-i])
|
|
667
|
+
b = self.bracketing(i)
|
|
668
|
+
if not b[0]:
|
|
669
|
+
return None
|
|
670
|
+
y = b[0][-1]
|
|
671
|
+
if y-1 in L and y-1 in R:
|
|
672
|
+
# special case: (--x+1--)(--x+1,x--) -->> (--x+1,x--)(--x--)
|
|
673
|
+
L.remove(y-1)
|
|
674
|
+
else:
|
|
675
|
+
L.remove(y)
|
|
676
|
+
R.append(y)
|
|
677
|
+
L.sort(reverse=True)
|
|
678
|
+
R.sort(reverse=True)
|
|
679
|
+
s = [self.value[j] for j in range(m-i-1)]+[L]+[R]+[self.value[j] for j in range(m-i+1, m)]
|
|
680
|
+
return P.element_class(P, s)
|
|
681
|
+
|
|
682
|
+
def f(self, i):
|
|
683
|
+
"""
|
|
684
|
+
Return the action of `f_i` on ``self`` using the rules described in [MPPS2020]_.
|
|
685
|
+
|
|
686
|
+
EXAMPLES::
|
|
687
|
+
|
|
688
|
+
sage: S = SymmetricGroup(4+1)
|
|
689
|
+
sage: w = S.from_reduced_word([3, 2, 1, 4, 3])
|
|
690
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 4, 3)
|
|
691
|
+
sage: h = B([[3, 2], [2, 1], [4, 3], [3, 1]]); h
|
|
692
|
+
(3, 2)(2, 1)(4, 3)(3, 1)
|
|
693
|
+
sage: h.f(1)
|
|
694
|
+
(3, 2)(2, 1)(4, 3, 1)(3)
|
|
695
|
+
sage: h.f(2)
|
|
696
|
+
sage: h.f(3)
|
|
697
|
+
(3, 2, 1)(1)(4, 3)(3, 1)
|
|
698
|
+
"""
|
|
699
|
+
P = self.parent()
|
|
700
|
+
m = P.factors
|
|
701
|
+
L = list(self.value[m-i-1])
|
|
702
|
+
R = list(self.value[m-i])
|
|
703
|
+
b = self.bracketing(i)
|
|
704
|
+
if not b[1]:
|
|
705
|
+
return None
|
|
706
|
+
x = b[1][0]
|
|
707
|
+
if x+1 in L and x+1 in R:
|
|
708
|
+
# special case: (--x+1--)(--x+1,x--) -->> (--x+1,x--)(--x--)
|
|
709
|
+
R.remove(x+1)
|
|
710
|
+
else:
|
|
711
|
+
R.remove(x)
|
|
712
|
+
L.append(x)
|
|
713
|
+
L.sort(reverse=True)
|
|
714
|
+
R.sort(reverse=True)
|
|
715
|
+
s = [self.value[j] for j in range(m-i-1)]+[L]+[R]+[self.value[j] for j in range(m-i+1, m)]
|
|
716
|
+
return P.element_class(P, s)
|
|
717
|
+
|
|
718
|
+
def bracketing(self, i):
|
|
719
|
+
"""
|
|
720
|
+
Remove all bracketed letters between `i`-th and `(i+1)`-th entry.
|
|
721
|
+
|
|
722
|
+
EXAMPLES::
|
|
723
|
+
|
|
724
|
+
sage: S = SymmetricGroup(4+1)
|
|
725
|
+
sage: w = S.from_reduced_word([3, 2, 1, 4, 3])
|
|
726
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
|
|
727
|
+
sage: h = B([[3], [4, 2, 1], [4, 3, 1]])
|
|
728
|
+
sage: h.bracketing(1)
|
|
729
|
+
[[], []]
|
|
730
|
+
sage: h.bracketing(2)
|
|
731
|
+
[[], [2, 1]]
|
|
732
|
+
"""
|
|
733
|
+
P = self.parent()
|
|
734
|
+
m = P.factors
|
|
735
|
+
L = list(self.value[m-i-1])
|
|
736
|
+
R = list(self.value[m-i])
|
|
737
|
+
right_n = list(R)
|
|
738
|
+
left_n = list(L)
|
|
739
|
+
left_unbracketed = []
|
|
740
|
+
while left_n:
|
|
741
|
+
m = max(left_n)
|
|
742
|
+
left_n.remove(m)
|
|
743
|
+
l = [j for j in right_n if j >= m]
|
|
744
|
+
if l:
|
|
745
|
+
right_n.remove(min(l))
|
|
746
|
+
else:
|
|
747
|
+
left_unbracketed += [m]
|
|
748
|
+
return [list(left_unbracketed), list(right_n)]
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
####################
|
|
752
|
+
# Helper functions #
|
|
753
|
+
####################
|
|
754
|
+
|
|
755
|
+
def _check_decreasing_hecke_factorization(t):
|
|
756
|
+
"""
|
|
757
|
+
Check if ``t`` is a suitable data type for a decreasing factorization in a 0-Hecke monoid.
|
|
758
|
+
|
|
759
|
+
EXAMPLES::
|
|
760
|
+
|
|
761
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _check_decreasing_hecke_factorization
|
|
762
|
+
sage: _check_decreasing_hecke_factorization([[3, 2], [2, 1], [4]])
|
|
763
|
+
sage: _check_decreasing_hecke_factorization([[3, 2, 2], [2, 1], [4]])
|
|
764
|
+
Traceback (most recent call last):
|
|
765
|
+
...
|
|
766
|
+
ValueError: each nonempty factor should be a strictly decreasing sequence
|
|
767
|
+
sage: _check_decreasing_hecke_factorization([[3, 'a'], [2, 1], [4]])
|
|
768
|
+
Traceback (most recent call last):
|
|
769
|
+
...
|
|
770
|
+
ValueError: each nonempty factor should contain integers
|
|
771
|
+
sage: _check_decreasing_hecke_factorization([[3, 2], [2, 1], 4])
|
|
772
|
+
Traceback (most recent call last):
|
|
773
|
+
...
|
|
774
|
+
ValueError: each factor in t should be a list or tuple
|
|
775
|
+
"""
|
|
776
|
+
if not isinstance(t, DecreasingHeckeFactorization):
|
|
777
|
+
if not isinstance(t, (tuple, list)):
|
|
778
|
+
raise ValueError("t should be a list or tuple")
|
|
779
|
+
for factor in t:
|
|
780
|
+
if not isinstance(factor, (tuple, list)):
|
|
781
|
+
raise ValueError("each factor in t should be a list or tuple")
|
|
782
|
+
if not all(isinstance(x,(int, Integer)) for x in factor):
|
|
783
|
+
raise ValueError("each nonempty factor should contain integers")
|
|
784
|
+
for i in range(len(factor)-1):
|
|
785
|
+
if factor[i] <= factor[i+1]:
|
|
786
|
+
raise ValueError("each nonempty factor should be a strictly decreasing sequence")
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
def _check_containment(t, parent):
|
|
790
|
+
"""
|
|
791
|
+
Check if ``t`` is an element of ``parent``.
|
|
792
|
+
|
|
793
|
+
EXAMPLES::
|
|
794
|
+
|
|
795
|
+
sage: S = SymmetricGroup(3+1)
|
|
796
|
+
sage: w = S.from_reduced_word([1, 3, 2])
|
|
797
|
+
sage: B = crystals.FullyCommutativeStableGrothendieck(w, 3, 2)
|
|
798
|
+
|
|
799
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import DecreasingHeckeFactorization, _check_containment
|
|
800
|
+
sage: h1 = DecreasingHeckeFactorization([[3, 1], [3], [3, 2]], 4)
|
|
801
|
+
sage: _check_containment(h1, B)
|
|
802
|
+
|
|
803
|
+
sage: h2 = DecreasingHeckeFactorization([[3, 1], [3], [], [3, 2]])
|
|
804
|
+
sage: _check_containment(h2, B)
|
|
805
|
+
Traceback (most recent call last):
|
|
806
|
+
...
|
|
807
|
+
ValueError: number of factors do not match
|
|
808
|
+
|
|
809
|
+
sage: h3 = [[3, 1], [2], [3, 2]]
|
|
810
|
+
sage: _check_containment(h3, B)
|
|
811
|
+
Traceback (most recent call last):
|
|
812
|
+
...
|
|
813
|
+
ValueError: self and parent must be specified based on equivalent words
|
|
814
|
+
|
|
815
|
+
sage: h4 = DecreasingHeckeFactorization([[3, 1], [3, 1], [3, 2]], 3)
|
|
816
|
+
sage: _check_containment(h4, B)
|
|
817
|
+
Traceback (most recent call last):
|
|
818
|
+
...
|
|
819
|
+
ValueError: number of excess letters do not match
|
|
820
|
+
"""
|
|
821
|
+
if isinstance(t, DecreasingHeckeFactorization):
|
|
822
|
+
factors = t.factors
|
|
823
|
+
w = t.w
|
|
824
|
+
excess = t.excess
|
|
825
|
+
else:
|
|
826
|
+
factors = len(t)
|
|
827
|
+
max_value = parent.max_value
|
|
828
|
+
from sage.monoids.hecke_monoid import HeckeMonoid
|
|
829
|
+
H = HeckeMonoid(SymmetricGroup(max_value+1))
|
|
830
|
+
w = tuple(H.from_reduced_word(x for factor in t for x in factor).reduced_word())
|
|
831
|
+
excess = sum(len(l) for l in t) - len(w)
|
|
832
|
+
|
|
833
|
+
if factors != parent.factors:
|
|
834
|
+
raise ValueError("number of factors do not match")
|
|
835
|
+
if w != parent.w:
|
|
836
|
+
raise ValueError("self and parent must be specified based on equivalent words")
|
|
837
|
+
if excess != parent.excess:
|
|
838
|
+
raise ValueError("number of excess letters do not match")
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def _generate_decreasing_hecke_factorizations(w, factors, ex, weight=None, parent=None):
|
|
842
|
+
"""
|
|
843
|
+
Generate all decreasing factorizations of word ``w`` in a 0-Hecke monoid
|
|
844
|
+
with fixed excess and number of factors.
|
|
845
|
+
|
|
846
|
+
INPUT:
|
|
847
|
+
|
|
848
|
+
- ``w`` -- a reduced word, expressed as an iterable
|
|
849
|
+
|
|
850
|
+
- ``factors`` -- number of factors for each decreasing factorization
|
|
851
|
+
|
|
852
|
+
- ``ex`` -- number of extra letters in each decreasing factorizations
|
|
853
|
+
|
|
854
|
+
- ``weight`` -- (default: ``None``) if ``None``, returns all possible
|
|
855
|
+
decreasing factorizations, otherwise return all those with the specified
|
|
856
|
+
weight
|
|
857
|
+
|
|
858
|
+
EXAMPLES::
|
|
859
|
+
|
|
860
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _generate_decreasing_hecke_factorizations
|
|
861
|
+
sage: _generate_decreasing_hecke_factorizations([1, 2, 1], 3, 1)
|
|
862
|
+
[()(2, 1)(2, 1),
|
|
863
|
+
(2)(1)(2, 1),
|
|
864
|
+
(1)(2)(2, 1),
|
|
865
|
+
(1)(1)(2, 1),
|
|
866
|
+
(2, 1)()(2, 1),
|
|
867
|
+
(2)(2, 1)(2),
|
|
868
|
+
(1)(2, 1)(2),
|
|
869
|
+
(1)(2, 1)(1),
|
|
870
|
+
(2, 1)(2)(2),
|
|
871
|
+
(2, 1)(2)(1),
|
|
872
|
+
(2, 1)(1)(2),
|
|
873
|
+
(2, 1)(2, 1)()]
|
|
874
|
+
|
|
875
|
+
sage: _generate_decreasing_hecke_factorizations([1, 2, 1], 3, 1, weight=[1, 1, 2])
|
|
876
|
+
[(2, 1)(2)(2), (2, 1)(2)(1), (2, 1)(1)(2)]
|
|
877
|
+
"""
|
|
878
|
+
if parent is None:
|
|
879
|
+
max_value = max(w) if w else 1
|
|
880
|
+
S = SymmetricGroup(max_value+1)
|
|
881
|
+
v = S.from_reduced_word(w)
|
|
882
|
+
parent = DecreasingHeckeFactorizations(v, factors, ex)
|
|
883
|
+
|
|
884
|
+
_canonical_word = lambda w, ex: [list(w)[0]]*ex + list(w)
|
|
885
|
+
wt = lambda t:[len(factor) for factor in reversed(t)]
|
|
886
|
+
|
|
887
|
+
L = _list_equivalent_words(_canonical_word(w, ex))
|
|
888
|
+
Factors = []
|
|
889
|
+
for word in L:
|
|
890
|
+
F = _list_all_decreasing_runs(word, factors)
|
|
891
|
+
for f in F:
|
|
892
|
+
t = [[word[j] for j in range(len(word)) if f[j] == i] for i in range(factors, 0, -1)]
|
|
893
|
+
if weight is None or weight == wt(t):
|
|
894
|
+
Factors.append(parent.element_class(parent, t))
|
|
895
|
+
return sorted(Factors, reverse=True)
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
def _list_all_decreasing_runs(word, m):
|
|
899
|
+
"""
|
|
900
|
+
List all possible decreasing runs into ``m`` factors for ``word`` in a
|
|
901
|
+
0-Hecke monoid.
|
|
902
|
+
|
|
903
|
+
EXAMPLES::
|
|
904
|
+
|
|
905
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _list_all_decreasing_runs
|
|
906
|
+
sage: _list_all_decreasing_runs([2, 1, 2, 1], 3)
|
|
907
|
+
[[2, 2, 1, 1], [3, 2, 1, 1], [3, 3, 1, 1], [3, 3, 2, 1], [3, 3, 2, 2]]
|
|
908
|
+
"""
|
|
909
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
910
|
+
J = _jumps(word)
|
|
911
|
+
jump_vector = [1]+[int(j in J) for j in range(1, len(word))]
|
|
912
|
+
I = sorted(IntegerVectors(m-1-len(J), len(word)+1), reverse=True)
|
|
913
|
+
P = [[elt[i]+jump_vector[i] for i in range(len(word))] for elt in I]
|
|
914
|
+
V = [[m+1-sum(elt[:i+1]) for i in range(len(elt))] for elt in P]
|
|
915
|
+
return V
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
def _to_reduced_word(P):
|
|
919
|
+
"""
|
|
920
|
+
Return a reduced word associated to skew partition ``P``.
|
|
921
|
+
|
|
922
|
+
EXAMPLES::
|
|
923
|
+
|
|
924
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
|
|
925
|
+
sage: P = SkewPartition([[2, 2], [1]])
|
|
926
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
|
|
927
|
+
sage: _to_reduced_word(P)
|
|
928
|
+
[2, 1, 3]
|
|
929
|
+
|
|
930
|
+
sage: P = SkewPartition([[], []])
|
|
931
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
|
|
932
|
+
sage: _to_reduced_word(P)
|
|
933
|
+
[]
|
|
934
|
+
|
|
935
|
+
sage: P = SkewPartition([[2, 1], []])
|
|
936
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _to_reduced_word
|
|
937
|
+
sage: _to_reduced_word(P)
|
|
938
|
+
[1, 3, 2]
|
|
939
|
+
"""
|
|
940
|
+
cells = P.cells()
|
|
941
|
+
if not cells:
|
|
942
|
+
return []
|
|
943
|
+
m = max(cell[0] for cell in cells) + 1
|
|
944
|
+
n = max(cell[1] for cell in cells) + 1
|
|
945
|
+
L = []
|
|
946
|
+
for i in range(m, -1, -1):
|
|
947
|
+
for j in range(n, -1, -1):
|
|
948
|
+
if (i, j) in cells:
|
|
949
|
+
L += [j-i+m]
|
|
950
|
+
return L
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
def _lowest_weights(w, factors, ex, parent=None):
|
|
954
|
+
"""
|
|
955
|
+
Generate all decreasing factorizations in the 0-Hecke monoid that correspond
|
|
956
|
+
to some valid semistandard Young tableaux.
|
|
957
|
+
|
|
958
|
+
The semistandard Young tableaux should have at most ``factors`` columns and their
|
|
959
|
+
column reading words should be equivalent to ``w`` in a 0-Hecke monoid.
|
|
960
|
+
|
|
961
|
+
INPUT:
|
|
962
|
+
|
|
963
|
+
- ``w`` -- a fully commutative reduced word, expressed as an iterable
|
|
964
|
+
|
|
965
|
+
- ``factors`` -- number of factors for each decreasing factorization
|
|
966
|
+
|
|
967
|
+
- ``ex`` -- number of extra letters in each decreasing factorizations
|
|
968
|
+
|
|
969
|
+
- ``parent`` -- (default: ``None``) parent of the decreasing
|
|
970
|
+
factorizations, automatically assigned if it is None
|
|
971
|
+
|
|
972
|
+
EXAMPLES::
|
|
973
|
+
|
|
974
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _lowest_weights
|
|
975
|
+
sage: _lowest_weights([1, 2, 1], 3, 1)
|
|
976
|
+
Traceback (most recent call last):
|
|
977
|
+
...
|
|
978
|
+
ValueError: the word w should be fully commutative
|
|
979
|
+
|
|
980
|
+
sage: _lowest_weights([2, 1, 3, 2], 4, 3)
|
|
981
|
+
[(2, 1)(3, 1)(3, 1)(2), (2, 1)(3, 1)(3, 2)(2)]
|
|
982
|
+
|
|
983
|
+
sage: _lowest_weights([2, 1, 3, 2], 5, 3)
|
|
984
|
+
[(2, 1)(3, 1)(3, 1)(2)(),
|
|
985
|
+
(2, 1)(3, 1)(3, 2)(2)(),
|
|
986
|
+
(2, 1)(3, 1)(1)(1)(2),
|
|
987
|
+
(2, 1)(3, 1)(1)(2)(2),
|
|
988
|
+
(2, 1)(3, 1)(2)(2)(2),
|
|
989
|
+
(2, 1)(3, 2)(2)(2)(2)]
|
|
990
|
+
|
|
991
|
+
sage: _lowest_weights([1, 3], 3, 1)
|
|
992
|
+
[(3, 1)(1)(), (3, 1)(3)(), (1)(1)(3), (1)(3)(3)]
|
|
993
|
+
|
|
994
|
+
sage: _lowest_weights([3, 2, 1], 5, 2)
|
|
995
|
+
[(3, 2, 1)(1)(1)()()]
|
|
996
|
+
"""
|
|
997
|
+
p = permutation.from_reduced_word(w)
|
|
998
|
+
if p.has_pattern([3,2,1]):
|
|
999
|
+
raise ValueError("the word w should be fully commutative")
|
|
1000
|
+
if parent is None:
|
|
1001
|
+
k = max(w)
|
|
1002
|
+
S = SymmetricGroup(k+1)
|
|
1003
|
+
word = S.from_reduced_word(w)
|
|
1004
|
+
parent = FullyCommutativeStableGrothendieckCrystal(word, factors, ex)
|
|
1005
|
+
|
|
1006
|
+
_canonical_word = lambda w, ex: [list(w)[0]]*ex + list(w)
|
|
1007
|
+
L = _list_equivalent_words(_canonical_word(w, ex))
|
|
1008
|
+
|
|
1009
|
+
M = []
|
|
1010
|
+
for v in L:
|
|
1011
|
+
if _is_valid_column_word(v, factors):
|
|
1012
|
+
J = [0] + _jumps(v) + [len(v)]
|
|
1013
|
+
t = [v[J[i]:J[i+1]] for i in range(len(J)-1)]
|
|
1014
|
+
if len(J) < factors+1:
|
|
1015
|
+
t += [()]*(factors+1-len(J))
|
|
1016
|
+
M.append(parent.element_class(parent, t))
|
|
1017
|
+
return sorted(M)
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
def _jumps(w):
|
|
1021
|
+
"""
|
|
1022
|
+
Detect all positions where letters weakly increase in ``w``.
|
|
1023
|
+
|
|
1024
|
+
EXAMPLES::
|
|
1025
|
+
|
|
1026
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _jumps
|
|
1027
|
+
sage: w = [4, 1, 2, 1, 4, 3, 2, 1, 3, 2, 2]
|
|
1028
|
+
sage: _jumps(w)
|
|
1029
|
+
[2, 4, 8, 10]
|
|
1030
|
+
"""
|
|
1031
|
+
return [i+1 for i in range(len(w)-1) if w[i] <= w[i+1]]
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
def _is_valid_column_word(w, m=None):
|
|
1035
|
+
"""
|
|
1036
|
+
Determine if ``w`` is actually a valid column reading word of some
|
|
1037
|
+
semistandard Young tableau with at most ``m`` columns.
|
|
1038
|
+
|
|
1039
|
+
If ``m`` is None, then we determine if ``w`` is a valid column reading word
|
|
1040
|
+
of some semistandard Young tableau.
|
|
1041
|
+
|
|
1042
|
+
EXAMPLES::
|
|
1043
|
+
|
|
1044
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _is_valid_column_word
|
|
1045
|
+
sage: w = [3, 2, 2, 1, 1]
|
|
1046
|
+
sage: _is_valid_column_word(w)
|
|
1047
|
+
False
|
|
1048
|
+
|
|
1049
|
+
sage: w = [3, 2, 1, 1, 1]
|
|
1050
|
+
sage: _is_valid_column_word(w,3)
|
|
1051
|
+
True
|
|
1052
|
+
|
|
1053
|
+
sage: w = [3, 2, 1, 1, 1]
|
|
1054
|
+
sage: _is_valid_column_word(w,2)
|
|
1055
|
+
False
|
|
1056
|
+
|
|
1057
|
+
sage: w = [3, 2, 1, 3, 1]
|
|
1058
|
+
sage: _is_valid_column_word(w,2)
|
|
1059
|
+
True
|
|
1060
|
+
"""
|
|
1061
|
+
J = [0] + _jumps(w) + [len(w)]
|
|
1062
|
+
L = [w[J[i+1]-1:J[i]:-1] for i in range(len(J)-1)]
|
|
1063
|
+
if all(len(L[i]) >= len(L[i+1]) for i in range(len(L)-1)):
|
|
1064
|
+
if m is None or len(_jumps(w)) <= m-1:
|
|
1065
|
+
# By construction the sequences along rows of L are strictly
|
|
1066
|
+
# decreasing, so it remains to verify that the sequences along
|
|
1067
|
+
# columns of L are weakly increasing
|
|
1068
|
+
return all(L[i+1][j] >= L[i][j] for i in range(len(L)-1)
|
|
1069
|
+
for j in range(len(L[i+1])))
|
|
1070
|
+
return False
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
def _list_equivalent_words(w):
|
|
1074
|
+
"""
|
|
1075
|
+
List all words equivalent to ``w`` in a 0-Hecke monoid.
|
|
1076
|
+
|
|
1077
|
+
EXAMPLES::
|
|
1078
|
+
|
|
1079
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _list_equivalent_words
|
|
1080
|
+
sage: _list_equivalent_words([1, 1, 2, 1])
|
|
1081
|
+
[(1, 1, 2, 1),
|
|
1082
|
+
(1, 2, 1, 1),
|
|
1083
|
+
(1, 2, 1, 2),
|
|
1084
|
+
(1, 2, 2, 1),
|
|
1085
|
+
(2, 1, 1, 2),
|
|
1086
|
+
(2, 1, 2, 1),
|
|
1087
|
+
(2, 1, 2, 2),
|
|
1088
|
+
(2, 2, 1, 2)]
|
|
1089
|
+
|
|
1090
|
+
sage: _list_equivalent_words([2,1,3,1,2])
|
|
1091
|
+
[(2, 1, 1, 3, 2),
|
|
1092
|
+
(2, 1, 3, 1, 2),
|
|
1093
|
+
(2, 1, 3, 2, 2),
|
|
1094
|
+
(2, 1, 3, 3, 2),
|
|
1095
|
+
(2, 2, 1, 3, 2),
|
|
1096
|
+
(2, 2, 3, 1, 2),
|
|
1097
|
+
(2, 3, 1, 1, 2),
|
|
1098
|
+
(2, 3, 1, 2, 2),
|
|
1099
|
+
(2, 3, 1, 3, 2),
|
|
1100
|
+
(2, 3, 3, 1, 2)]
|
|
1101
|
+
"""
|
|
1102
|
+
if all(isinstance(i, (int, Integer)) for i in w):
|
|
1103
|
+
u = w
|
|
1104
|
+
else:
|
|
1105
|
+
raise ValueError("w needs to be a tuple of integers")
|
|
1106
|
+
|
|
1107
|
+
def _applicable_relations(word):
|
|
1108
|
+
"""
|
|
1109
|
+
Return all positions where a relation can be applied on ``word``
|
|
1110
|
+
along with the type of relation.
|
|
1111
|
+
"""
|
|
1112
|
+
L = []
|
|
1113
|
+
for i in range(len(word)-2):
|
|
1114
|
+
p, q, r = word[i:(i+2)+1]
|
|
1115
|
+
if abs(p-q) > 1:
|
|
1116
|
+
L += [[i,"pq=qp"]]
|
|
1117
|
+
elif abs(p-q) == 1:
|
|
1118
|
+
if p == r: # p != q by the abs test
|
|
1119
|
+
L += [[i,"pqp=qpq"]]
|
|
1120
|
+
elif r != p: # We must have p == q
|
|
1121
|
+
L += [[i,"ppq=pqq"]]
|
|
1122
|
+
if q == r and r != p:
|
|
1123
|
+
L += [[i,"pqq=ppq"]]
|
|
1124
|
+
if len(word) > 1 and abs(word[-2]-word[-1]) > 1:
|
|
1125
|
+
L += [[len(word)-2,"pq=qp"]]
|
|
1126
|
+
return L
|
|
1127
|
+
|
|
1128
|
+
V = set()
|
|
1129
|
+
queue = [tuple(u)]
|
|
1130
|
+
while queue:
|
|
1131
|
+
v = queue.pop(0)
|
|
1132
|
+
if tuple(v) not in V:
|
|
1133
|
+
V.add(tuple(v))
|
|
1134
|
+
L = _applicable_relations(v)
|
|
1135
|
+
for pair in L:
|
|
1136
|
+
position, move = pair
|
|
1137
|
+
t = _apply_relations(v, position, move)
|
|
1138
|
+
queue += [tuple(t)]
|
|
1139
|
+
return sorted(v for v in list(V))
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
def _apply_relations(word, position, move):
|
|
1143
|
+
"""
|
|
1144
|
+
Apply a particular type of ``move`` on ``word`` at the specified
|
|
1145
|
+
``position`` using a relation in a 0-Hecke monoid .
|
|
1146
|
+
|
|
1147
|
+
EXAMPLES::
|
|
1148
|
+
|
|
1149
|
+
sage: from sage.combinat.crystals.fully_commutative_stable_grothendieck import _apply_relations
|
|
1150
|
+
sage: w = [2, 1, 3, 4]
|
|
1151
|
+
sage: _apply_relations(w, position=1, move='pq=qp')
|
|
1152
|
+
[2, 3, 1, 4]
|
|
1153
|
+
|
|
1154
|
+
sage: w = [1, 3, 2, 1, 2, 4]
|
|
1155
|
+
sage: _apply_relations(w, position=2, move='pqp=qpq')
|
|
1156
|
+
[1, 3, 1, 2, 1, 4]
|
|
1157
|
+
|
|
1158
|
+
sage: w = [2, 3, 1, 2, 2, 3]
|
|
1159
|
+
sage: _apply_relations(w, position=3, move='pp=p')
|
|
1160
|
+
[2, 3, 1, 2, 3]
|
|
1161
|
+
|
|
1162
|
+
sage: w = [2, 3, 1, 2, 3]
|
|
1163
|
+
sage: _apply_relations(w, position=3, move='p=pp')
|
|
1164
|
+
[2, 3, 1, 2, 2, 3]
|
|
1165
|
+
|
|
1166
|
+
sage: w = [2, 3, 1, 2, 2, 3]
|
|
1167
|
+
sage: _apply_relations(w, position=2, move='pqq=ppq')
|
|
1168
|
+
[2, 3, 1, 1, 2, 3]
|
|
1169
|
+
|
|
1170
|
+
sage: w = [2, 3, 1, 1, 2, 3]
|
|
1171
|
+
sage: _apply_relations(w, position=2, move='ppq=pqq')
|
|
1172
|
+
[2, 3, 1, 2, 2, 3]
|
|
1173
|
+
"""
|
|
1174
|
+
w = list(word)
|
|
1175
|
+
# Type 1
|
|
1176
|
+
if move == "pq=qp":
|
|
1177
|
+
p = w[position]
|
|
1178
|
+
q = w[position+1]
|
|
1179
|
+
w[position] = q
|
|
1180
|
+
w[position+1] = p
|
|
1181
|
+
# Type 2
|
|
1182
|
+
elif move == "pqp=qpq":
|
|
1183
|
+
p = w[position]
|
|
1184
|
+
q = w[position+1]
|
|
1185
|
+
w[position] = q
|
|
1186
|
+
w[position+1] = p
|
|
1187
|
+
w[position+2] = q
|
|
1188
|
+
# Type 3
|
|
1189
|
+
elif move == "pqq=ppq":
|
|
1190
|
+
p = w[position]
|
|
1191
|
+
q = w[position+2]
|
|
1192
|
+
w[position+1] = p
|
|
1193
|
+
# Type 4
|
|
1194
|
+
elif move == "ppq=pqq":
|
|
1195
|
+
p = w[position]
|
|
1196
|
+
q = w[position+2]
|
|
1197
|
+
w[position+1] = q
|
|
1198
|
+
# Type 5
|
|
1199
|
+
elif move == "pp=p":
|
|
1200
|
+
p = w[position]
|
|
1201
|
+
w = w[:position+1] + w[position+2:]
|
|
1202
|
+
elif move == "p=pp":
|
|
1203
|
+
p = w[position]
|
|
1204
|
+
w = w[:position+1] + [p] + w[position+1:]
|
|
1205
|
+
return w
|