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
|
Binary file
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
This module contains Cython code for a backtracking algorithm to solve Sudoku puzzles.
|
|
4
|
+
|
|
5
|
+
Once Cython implements closures and the ``yield`` keyword is possible, this can be moved into the ``sage.games.sudoku`` module, as part of the ``Sudoku.backtrack`` method, and this module can be banned.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def backtrack_all(n, puzzle):
|
|
10
|
+
r"""
|
|
11
|
+
A routine to compute all the solutions to a Sudoku puzzle.
|
|
12
|
+
|
|
13
|
+
INPUT:
|
|
14
|
+
|
|
15
|
+
- ``n`` -- the size of the puzzle, where the array is an `n^2\times n^2` grid
|
|
16
|
+
|
|
17
|
+
- ``puzzle`` -- list of the entries of the puzzle (1-based), in row-major order
|
|
18
|
+
|
|
19
|
+
OUTPUT:
|
|
20
|
+
|
|
21
|
+
A list of solutions, where each solution is a (1-based) list similar to ``puzzle``.
|
|
22
|
+
|
|
23
|
+
TESTS:
|
|
24
|
+
|
|
25
|
+
This is just a cursory test here, since eventually this code will move.
|
|
26
|
+
See the `backtrack` method of the `Sudoku` class in the
|
|
27
|
+
`sage.games.sudoku` module for more enlightening examples. ::
|
|
28
|
+
|
|
29
|
+
sage: from sage.games.sudoku_backtrack import backtrack_all
|
|
30
|
+
sage: c = [0, 0, 0, 0, 1, 0, 9, 0, 0, 8, 0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 3, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 8, 0, 6, 0, 0, 0, 0, 1, 3, 0, 7, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0]
|
|
31
|
+
sage: print(backtrack_all(3, c))
|
|
32
|
+
[[6, 5, 4, 3, 1, 2, 9, 8, 7, 8, 3, 1, 4, 7, 9, 5, 2, 6, 2, 9, 7, 6, 8, 5, 4, 1, 3, 4, 7, 2, 5, 3, 8, 6, 9, 1, 3, 8, 5, 1, 9, 6, 2, 7, 4, 9, 1, 6, 7, 2, 4, 3, 5, 8, 5, 6, 8, 9, 4, 7, 1, 3, 2, 7, 4, 3, 2, 5, 1, 8, 6, 9, 1, 2, 9, 8, 6, 3, 7, 4, 5]]
|
|
33
|
+
|
|
34
|
+
ALGORITHM:
|
|
35
|
+
|
|
36
|
+
We traverse a search tree depth-first. Each level of the tree corresponds to a location in the grid, listed in row-major order. At each location we maintain a list of the symbols which may be used in that location as follows.
|
|
37
|
+
|
|
38
|
+
A location has "peers", which are the locations in the same row, column or box (sub-grid). As symbols are chosen (or fixed initially) at a location, they become ineligible for use at a peer. We track this in the ``available`` array where at each location each symbol has a count of how many times it has been made ineligible. As this counter transitions between 0 and 1, the number of eligible symbols at a location is tracked in the ``card`` array. When the number of eligible symbols at any location becomes 1, then we know that *must* be the symbol employed in that location. This then allows us to further update the eligible symbols at the peers of that location. When the number of the eligible symbols at any location becomes 0, then we know that we can prune the search tree.
|
|
39
|
+
|
|
40
|
+
So at each new level of the search tree, we propagate as many fixed symbols as we can, placing them into a two-ended queue (``fixed`` and ``fixed_symbol``) that we process until it is empty or we need to prune. All this recording of ineligible symbols and numbers of eligible symbols has to be unwound as we backup the tree, though.
|
|
41
|
+
|
|
42
|
+
The notion of propagating singleton cells forward comes from an essay by Peter Norvig [sudoku:norvig]_.
|
|
43
|
+
"""
|
|
44
|
+
cdef:
|
|
45
|
+
# Arrays sizes are n^4, and n^2, with 3n^2-2n-1 for second slot of peers, n = 4
|
|
46
|
+
int i, j, count, level, apeer
|
|
47
|
+
int nsquare, npeers, nboxes
|
|
48
|
+
int grid_row, grid_col, grid_corner
|
|
49
|
+
int peers[256][39]
|
|
50
|
+
int box[256]
|
|
51
|
+
int available[256][16]
|
|
52
|
+
int card[256]
|
|
53
|
+
int hint, symbol, abox
|
|
54
|
+
int feasible
|
|
55
|
+
int nfixed[256]
|
|
56
|
+
int fixed[256][256]
|
|
57
|
+
int fixed_symbol[256][256]
|
|
58
|
+
|
|
59
|
+
int process, asymbol, alevel, process_level, process_symbol
|
|
60
|
+
|
|
61
|
+
# sanity check on size (types)
|
|
62
|
+
# n is "base" dimension
|
|
63
|
+
# nsquare is size of a grid
|
|
64
|
+
# nboxes is total number of entries
|
|
65
|
+
nsquare = n*n
|
|
66
|
+
nboxes = nsquare * nsquare
|
|
67
|
+
npeers = 3*n*n-2*n-1 # 2(n^2-1)+n^2-2n+1
|
|
68
|
+
|
|
69
|
+
# "Peers" of a box are boxes in the same column, row or grid
|
|
70
|
+
# Like the conflict graph when expressed as a graph coloring problem
|
|
71
|
+
for level in range(nboxes):
|
|
72
|
+
# location as row and column in square
|
|
73
|
+
# grids are numbered similarly, in row-major order
|
|
74
|
+
row = level // nsquare
|
|
75
|
+
col = level % nsquare
|
|
76
|
+
grid_corner = (row - (row % n))*nsquare + (col - (col % n))
|
|
77
|
+
grid_row = row // n
|
|
78
|
+
grid_col = col // n
|
|
79
|
+
count = -1
|
|
80
|
+
# Peers' levels in same grid, but not the box itself
|
|
81
|
+
for i in range(n):
|
|
82
|
+
for j in range(n):
|
|
83
|
+
grid_level = grid_corner + i*nsquare + j
|
|
84
|
+
if grid_level != level:
|
|
85
|
+
count += 1
|
|
86
|
+
peers[level][count] = grid_level
|
|
87
|
+
# Peers' levels in the same row, but not in grid
|
|
88
|
+
for i in range(nsquare):
|
|
89
|
+
if (i // 3 != grid_col):
|
|
90
|
+
count += 1
|
|
91
|
+
peers[level][count] = row*nsquare + i
|
|
92
|
+
# Peers' levels in same column, but not in grid
|
|
93
|
+
for i in range(nsquare):
|
|
94
|
+
if (i // 3 != grid_row):
|
|
95
|
+
count += 1
|
|
96
|
+
peers[level][count] = col + i*nsquare
|
|
97
|
+
|
|
98
|
+
# Initialize data structures
|
|
99
|
+
# Make every symbol available initially for a box
|
|
100
|
+
# And make set cardinality the size of symbol set
|
|
101
|
+
for level in range(nboxes):
|
|
102
|
+
box[level] = -1
|
|
103
|
+
card[level] = nsquare
|
|
104
|
+
for j in range(nsquare):
|
|
105
|
+
available[level][j] = 0
|
|
106
|
+
|
|
107
|
+
# For nonzero entries of input puzzle
|
|
108
|
+
# (1) Convert to zero-based indexing
|
|
109
|
+
# (2) Make a set of size 1 available initially
|
|
110
|
+
for level in range(nboxes):
|
|
111
|
+
# location as row and column in square
|
|
112
|
+
# grids are numbered similarly, in row-major order
|
|
113
|
+
hint = puzzle[level] - 1
|
|
114
|
+
if hint != -1:
|
|
115
|
+
# Limit symbol set at the hint's location to a singleton
|
|
116
|
+
for j in range(nsquare):
|
|
117
|
+
available[level][j] = 1
|
|
118
|
+
available[level][hint] = 0
|
|
119
|
+
card[level] = 1
|
|
120
|
+
# Remove hint from all peers' available symbols
|
|
121
|
+
# Track cardinality as sets adjust
|
|
122
|
+
for i in range(npeers):
|
|
123
|
+
apeer = peers[level][i]
|
|
124
|
+
available[apeer][hint] += 1
|
|
125
|
+
if available[apeer][hint] == 1:
|
|
126
|
+
card[apeer] -= 1
|
|
127
|
+
|
|
128
|
+
# Start backtracking
|
|
129
|
+
solutions = []
|
|
130
|
+
level = 0
|
|
131
|
+
box[level] = -1
|
|
132
|
+
while (level > -1):
|
|
133
|
+
symbol = box[level]
|
|
134
|
+
if (symbol != -1):
|
|
135
|
+
# restore symbols to peers
|
|
136
|
+
for i in range(nfixed[level]):
|
|
137
|
+
alevel = fixed[level][i]
|
|
138
|
+
asymbol = fixed_symbol[level][i]
|
|
139
|
+
for j in range(npeers):
|
|
140
|
+
abox = peers[alevel][j]
|
|
141
|
+
available[abox][asymbol] -= 1
|
|
142
|
+
if available[abox][asymbol] == 0:
|
|
143
|
+
card[abox] += 1
|
|
144
|
+
# move sideways in search tree to next available symbol
|
|
145
|
+
symbol += 1
|
|
146
|
+
while (symbol < nsquare) and (available[level][symbol] != 0):
|
|
147
|
+
symbol += 1
|
|
148
|
+
if symbol == nsquare:
|
|
149
|
+
# fell off the end sideways, backup
|
|
150
|
+
level = level - 1
|
|
151
|
+
else:
|
|
152
|
+
box[level] = symbol
|
|
153
|
+
# Remove elements of sets, adjust cardinalities
|
|
154
|
+
# Descend in search tree if no empty sets created
|
|
155
|
+
# Can't break early at an empty set
|
|
156
|
+
# or we will confuse restore that happens immediately
|
|
157
|
+
feasible = True
|
|
158
|
+
fixed[level][0] = level
|
|
159
|
+
fixed_symbol[level][0] = symbol
|
|
160
|
+
count = 0
|
|
161
|
+
process = -1
|
|
162
|
+
while (process < count) and feasible:
|
|
163
|
+
process += 1
|
|
164
|
+
process_level = fixed[level][process]
|
|
165
|
+
process_symbol = fixed_symbol[level][process]
|
|
166
|
+
for i in range(npeers):
|
|
167
|
+
abox = peers[process_level][i]
|
|
168
|
+
available[abox][process_symbol] += 1
|
|
169
|
+
if available[abox][process_symbol] == 1:
|
|
170
|
+
card[abox] -= 1
|
|
171
|
+
if card[abox] == 0:
|
|
172
|
+
feasible = False
|
|
173
|
+
if card[abox] == 1:
|
|
174
|
+
count += 1
|
|
175
|
+
fixed[level][count] = abox
|
|
176
|
+
asymbol = 0
|
|
177
|
+
while (available[abox][asymbol] != 0):
|
|
178
|
+
asymbol += 1
|
|
179
|
+
fixed_symbol[level][count] = asymbol
|
|
180
|
+
nfixed[level] = process+1
|
|
181
|
+
if feasible:
|
|
182
|
+
if level == nboxes - 1:
|
|
183
|
+
# Have a solution to save, stay at this bottom-most level
|
|
184
|
+
# Once Cython implements closures, a yield can go here
|
|
185
|
+
solutions.append([box[i]+1 for i in range(nboxes)])
|
|
186
|
+
else:
|
|
187
|
+
level = level + 1
|
|
188
|
+
box[level] = -1
|
|
189
|
+
return solutions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat
|
|
3
|
+
"""
|
|
4
|
+
Indexed Free Groups
|
|
5
|
+
|
|
6
|
+
Free groups and free abelian groups implemented using an indexed set of
|
|
7
|
+
generators.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Travis Scrimshaw (2013-10-16): Initial version
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
##############################################################################
|
|
15
|
+
# Copyright (C) 2013 Travis Scrimshaw <tscrim at ucdavis.edu>
|
|
16
|
+
#
|
|
17
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
18
|
+
#
|
|
19
|
+
# The full text of the GPL is available at:
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
##############################################################################
|
|
23
|
+
|
|
24
|
+
from sage.categories.groups import Groups
|
|
25
|
+
from sage.categories.poor_man_map import PoorManMap
|
|
26
|
+
from sage.groups.group import Group, AbelianGroup
|
|
27
|
+
from sage.monoids.indexed_free_monoid import (IndexedMonoid,
|
|
28
|
+
IndexedFreeMonoidElement,
|
|
29
|
+
IndexedFreeAbelianMonoidElement)
|
|
30
|
+
from sage.misc.cachefunc import cached_method
|
|
31
|
+
import sage.data_structures.blas_dict as blas
|
|
32
|
+
from sage.rings.integer import Integer
|
|
33
|
+
from sage.rings.infinity import infinity
|
|
34
|
+
from sage.sets.family import Family
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class IndexedGroup(IndexedMonoid):
|
|
38
|
+
"""
|
|
39
|
+
Base class for free (abelian) groups whose generators are indexed
|
|
40
|
+
by a set.
|
|
41
|
+
|
|
42
|
+
TESTS:
|
|
43
|
+
|
|
44
|
+
We check finite properties::
|
|
45
|
+
|
|
46
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
47
|
+
sage: G.is_finite()
|
|
48
|
+
False
|
|
49
|
+
sage: G = Groups().free(index_set='abc')
|
|
50
|
+
sage: G.is_finite()
|
|
51
|
+
False
|
|
52
|
+
sage: G = Groups().free(index_set=[])
|
|
53
|
+
sage: G.is_finite()
|
|
54
|
+
True
|
|
55
|
+
|
|
56
|
+
::
|
|
57
|
+
|
|
58
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
59
|
+
sage: G.is_finite()
|
|
60
|
+
False
|
|
61
|
+
sage: G = Groups().Commutative().free(index_set='abc')
|
|
62
|
+
sage: G.is_finite()
|
|
63
|
+
False
|
|
64
|
+
sage: G = Groups().Commutative().free(index_set=[])
|
|
65
|
+
sage: G.is_finite()
|
|
66
|
+
True
|
|
67
|
+
"""
|
|
68
|
+
def order(self):
|
|
69
|
+
r"""
|
|
70
|
+
Return the number of elements of ``self``, which is `\infty` unless
|
|
71
|
+
this is the trivial group.
|
|
72
|
+
|
|
73
|
+
EXAMPLES::
|
|
74
|
+
|
|
75
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
76
|
+
sage: G.order()
|
|
77
|
+
+Infinity
|
|
78
|
+
sage: G = Groups().Commutative().free(index_set='abc')
|
|
79
|
+
sage: G.order()
|
|
80
|
+
+Infinity
|
|
81
|
+
sage: G = Groups().Commutative().free(index_set=[])
|
|
82
|
+
sage: G.order()
|
|
83
|
+
1
|
|
84
|
+
"""
|
|
85
|
+
return self.cardinality()
|
|
86
|
+
|
|
87
|
+
def rank(self):
|
|
88
|
+
"""
|
|
89
|
+
Return the rank of ``self``.
|
|
90
|
+
|
|
91
|
+
This is the number of generators of ``self``.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
96
|
+
sage: G.rank()
|
|
97
|
+
+Infinity
|
|
98
|
+
sage: G = Groups().free(index_set='abc')
|
|
99
|
+
sage: G.rank()
|
|
100
|
+
3
|
|
101
|
+
sage: G = Groups().free(index_set=[])
|
|
102
|
+
sage: G.rank()
|
|
103
|
+
0
|
|
104
|
+
|
|
105
|
+
::
|
|
106
|
+
|
|
107
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
108
|
+
sage: G.rank()
|
|
109
|
+
+Infinity
|
|
110
|
+
sage: G = Groups().Commutative().free(index_set='abc')
|
|
111
|
+
sage: G.rank()
|
|
112
|
+
3
|
|
113
|
+
sage: G = Groups().Commutative().free(index_set=[])
|
|
114
|
+
sage: G.rank()
|
|
115
|
+
0
|
|
116
|
+
"""
|
|
117
|
+
return self.group_generators().cardinality()
|
|
118
|
+
|
|
119
|
+
@cached_method
|
|
120
|
+
def group_generators(self):
|
|
121
|
+
"""
|
|
122
|
+
Return the group generators of ``self``.
|
|
123
|
+
|
|
124
|
+
EXAMPLES::
|
|
125
|
+
|
|
126
|
+
sage: G = Groups.free(index_set=ZZ)
|
|
127
|
+
sage: G.group_generators()
|
|
128
|
+
Lazy family (Generator map from Integer Ring to
|
|
129
|
+
Free group indexed by Integer Ring(i))_{i in Integer Ring}
|
|
130
|
+
sage: G = Groups().free(index_set='abcde')
|
|
131
|
+
sage: sorted(G.group_generators())
|
|
132
|
+
[F['a'], F['b'], F['c'], F['d'], F['e']]
|
|
133
|
+
"""
|
|
134
|
+
if self._indices.cardinality() == infinity:
|
|
135
|
+
gen = PoorManMap(self.gen, domain=self._indices, codomain=self, name="Generator map")
|
|
136
|
+
return Family(self._indices, gen)
|
|
137
|
+
return Family(self._indices, self.gen)
|
|
138
|
+
|
|
139
|
+
gens = group_generators
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class IndexedFreeGroup(IndexedGroup, Group):
|
|
143
|
+
"""
|
|
144
|
+
An indexed free group.
|
|
145
|
+
|
|
146
|
+
EXAMPLES::
|
|
147
|
+
|
|
148
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
149
|
+
sage: G
|
|
150
|
+
Free group indexed by Integer Ring
|
|
151
|
+
sage: G = Groups().free(index_set='abcde')
|
|
152
|
+
sage: G
|
|
153
|
+
Free group indexed by {'a', 'b', 'c', 'd', 'e'}
|
|
154
|
+
"""
|
|
155
|
+
def __init__(self, indices, prefix, category=None, **kwds):
|
|
156
|
+
"""
|
|
157
|
+
Initialize ``self``.
|
|
158
|
+
|
|
159
|
+
TESTS::
|
|
160
|
+
|
|
161
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
162
|
+
sage: TestSuite(G).run()
|
|
163
|
+
sage: G = Groups().free(index_set='abc')
|
|
164
|
+
sage: TestSuite(G).run()
|
|
165
|
+
"""
|
|
166
|
+
category = Groups().or_subcategory(category)
|
|
167
|
+
IndexedGroup.__init__(self, indices, prefix, category, **kwds)
|
|
168
|
+
|
|
169
|
+
def _repr_(self):
|
|
170
|
+
"""
|
|
171
|
+
Return a string representation of ``self``.
|
|
172
|
+
|
|
173
|
+
TESTS::
|
|
174
|
+
|
|
175
|
+
sage: Groups().free(index_set=ZZ) # indirect doctest
|
|
176
|
+
Free group indexed by Integer Ring
|
|
177
|
+
"""
|
|
178
|
+
return 'Free group indexed by {}'.format(self._indices)
|
|
179
|
+
|
|
180
|
+
@cached_method
|
|
181
|
+
def one(self):
|
|
182
|
+
"""
|
|
183
|
+
Return the identity element of ``self``.
|
|
184
|
+
|
|
185
|
+
EXAMPLES::
|
|
186
|
+
|
|
187
|
+
sage: G = Groups().free(ZZ)
|
|
188
|
+
sage: G.one()
|
|
189
|
+
1
|
|
190
|
+
"""
|
|
191
|
+
return self.element_class(self, ())
|
|
192
|
+
|
|
193
|
+
def gen(self, x):
|
|
194
|
+
"""
|
|
195
|
+
The generator indexed by ``x`` of ``self``.
|
|
196
|
+
|
|
197
|
+
EXAMPLES::
|
|
198
|
+
|
|
199
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
200
|
+
sage: G.gen(0)
|
|
201
|
+
F[0]
|
|
202
|
+
sage: G.gen(2)
|
|
203
|
+
F[2]
|
|
204
|
+
"""
|
|
205
|
+
if x not in self._indices:
|
|
206
|
+
raise IndexError("{} is not in the index set".format(x))
|
|
207
|
+
try:
|
|
208
|
+
return self.element_class(self, ((self._indices(x),1),))
|
|
209
|
+
except TypeError: # Backup (if it is a string)
|
|
210
|
+
return self.element_class(self, ((x,1),))
|
|
211
|
+
|
|
212
|
+
class Element(IndexedFreeMonoidElement):
|
|
213
|
+
def __len__(self):
|
|
214
|
+
"""
|
|
215
|
+
Return the length of ``self``.
|
|
216
|
+
|
|
217
|
+
EXAMPLES::
|
|
218
|
+
|
|
219
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
220
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
221
|
+
sage: elt = a*c^-3*b^-2*a
|
|
222
|
+
sage: elt.length()
|
|
223
|
+
7
|
|
224
|
+
sage: len(elt)
|
|
225
|
+
7
|
|
226
|
+
|
|
227
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
228
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
229
|
+
sage: elt = a*c^-3*b^-2*a
|
|
230
|
+
sage: elt.length()
|
|
231
|
+
7
|
|
232
|
+
sage: len(elt)
|
|
233
|
+
7
|
|
234
|
+
"""
|
|
235
|
+
return sum(abs(exp) for gen,exp in self._monomial)
|
|
236
|
+
|
|
237
|
+
length = __len__
|
|
238
|
+
|
|
239
|
+
def _mul_(self, other):
|
|
240
|
+
"""
|
|
241
|
+
Multiply ``self`` by ``other``.
|
|
242
|
+
|
|
243
|
+
EXAMPLES::
|
|
244
|
+
|
|
245
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
246
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
247
|
+
sage: a*b^2*e*d
|
|
248
|
+
F[0]*F[1]^2*F[4]*F[3]
|
|
249
|
+
sage: (a*b^2*d^2) * (d^-4*b*e)
|
|
250
|
+
F[0]*F[1]^2*F[3]^-2*F[1]*F[4]
|
|
251
|
+
sage: (a*b^-2*d^2) * (d^-2*b^2*a^-1)
|
|
252
|
+
1
|
|
253
|
+
"""
|
|
254
|
+
if not self._monomial:
|
|
255
|
+
return other
|
|
256
|
+
if not other._monomial:
|
|
257
|
+
return self
|
|
258
|
+
|
|
259
|
+
ret = list(self._monomial)
|
|
260
|
+
rhs = list(other._monomial)
|
|
261
|
+
while ret and rhs and ret[-1][0] == rhs[0][0]:
|
|
262
|
+
rhs[0] = (rhs[0][0], rhs[0][1] + ret.pop()[1])
|
|
263
|
+
if rhs[0][1] == 0:
|
|
264
|
+
rhs.pop(0)
|
|
265
|
+
ret += rhs
|
|
266
|
+
return self.__class__(self.parent(), tuple(ret))
|
|
267
|
+
|
|
268
|
+
def __invert__(self):
|
|
269
|
+
"""
|
|
270
|
+
Return the inverse of ``self``.
|
|
271
|
+
|
|
272
|
+
EXAMPLES::
|
|
273
|
+
|
|
274
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
275
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
276
|
+
sage: x = a*b^2*e^-1*d; ~x
|
|
277
|
+
F[3]^-1*F[4]*F[1]^-2*F[0]^-1
|
|
278
|
+
sage: x * ~x
|
|
279
|
+
1
|
|
280
|
+
"""
|
|
281
|
+
return self.__class__(self.parent(),
|
|
282
|
+
tuple((x[0], -x[1]) for x in reversed(self._monomial)))
|
|
283
|
+
|
|
284
|
+
def to_word_list(self):
|
|
285
|
+
"""
|
|
286
|
+
Return ``self`` as a word represented as a list whose entries
|
|
287
|
+
are the pairs ``(i, s)`` where ``i`` is the index and ``s`` is
|
|
288
|
+
the sign.
|
|
289
|
+
|
|
290
|
+
EXAMPLES::
|
|
291
|
+
|
|
292
|
+
sage: G = Groups().free(index_set=ZZ)
|
|
293
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
294
|
+
sage: x = a*b^2*e*a^-1
|
|
295
|
+
sage: x.to_word_list()
|
|
296
|
+
[(0, 1), (1, 1), (1, 1), (4, 1), (0, -1)]
|
|
297
|
+
"""
|
|
298
|
+
sign = lambda x: 1 if x > 0 else -1 # It is never 0
|
|
299
|
+
return [ (k, sign(e)) for k,e in self._sorted_items()
|
|
300
|
+
for dummy in range(abs(e))]
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class IndexedFreeAbelianGroup(IndexedGroup, AbelianGroup):
|
|
304
|
+
"""
|
|
305
|
+
An indexed free abelian group.
|
|
306
|
+
|
|
307
|
+
EXAMPLES::
|
|
308
|
+
|
|
309
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
310
|
+
sage: G
|
|
311
|
+
Free abelian group indexed by Integer Ring
|
|
312
|
+
sage: G = Groups().Commutative().free(index_set='abcde')
|
|
313
|
+
sage: G
|
|
314
|
+
Free abelian group indexed by {'a', 'b', 'c', 'd', 'e'}
|
|
315
|
+
"""
|
|
316
|
+
def __init__(self, indices, prefix, category=None, **kwds):
|
|
317
|
+
"""
|
|
318
|
+
Initialize ``self``.
|
|
319
|
+
|
|
320
|
+
TESTS::
|
|
321
|
+
|
|
322
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
323
|
+
sage: TestSuite(G).run()
|
|
324
|
+
sage: G = Groups().Commutative().free(index_set='abc')
|
|
325
|
+
sage: TestSuite(G).run()
|
|
326
|
+
"""
|
|
327
|
+
category = Groups().or_subcategory(category)
|
|
328
|
+
IndexedGroup.__init__(self, indices, prefix, category, **kwds)
|
|
329
|
+
|
|
330
|
+
def _repr_(self):
|
|
331
|
+
"""
|
|
332
|
+
TESTS::
|
|
333
|
+
|
|
334
|
+
sage: Groups.Commutative().free(index_set=ZZ)
|
|
335
|
+
Free abelian group indexed by Integer Ring
|
|
336
|
+
"""
|
|
337
|
+
return 'Free abelian group indexed by {}'.format(self._indices)
|
|
338
|
+
|
|
339
|
+
def _element_constructor_(self, x=None):
|
|
340
|
+
"""
|
|
341
|
+
Create an element of ``self`` from ``x``.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
346
|
+
sage: G(G.gen(2))
|
|
347
|
+
F[2]
|
|
348
|
+
sage: G([[1, 3], [-2, 12]])
|
|
349
|
+
F[-2]^12*F[1]^3
|
|
350
|
+
sage: G({1: 3, -2: 12})
|
|
351
|
+
F[-2]^12*F[1]^3
|
|
352
|
+
sage: G(-5)
|
|
353
|
+
F[-5]
|
|
354
|
+
|
|
355
|
+
TESTS::
|
|
356
|
+
|
|
357
|
+
sage: G([(1, 3), (1, -5)])
|
|
358
|
+
F[1]^-2
|
|
359
|
+
|
|
360
|
+
sage: G([(42, 0)])
|
|
361
|
+
1
|
|
362
|
+
sage: G([(42, 3), (42, -3)])
|
|
363
|
+
1
|
|
364
|
+
sage: G({42: 0})
|
|
365
|
+
1
|
|
366
|
+
"""
|
|
367
|
+
if isinstance(x, (list, tuple)):
|
|
368
|
+
d = {}
|
|
369
|
+
for k, v in x:
|
|
370
|
+
if k in d:
|
|
371
|
+
d[k] += v
|
|
372
|
+
else:
|
|
373
|
+
d[k] = v
|
|
374
|
+
x = d
|
|
375
|
+
if isinstance(x, dict):
|
|
376
|
+
x = {k: v for k, v in x.items() if v != 0}
|
|
377
|
+
return IndexedGroup._element_constructor_(self, x)
|
|
378
|
+
|
|
379
|
+
@cached_method
|
|
380
|
+
def one(self):
|
|
381
|
+
"""
|
|
382
|
+
Return the identity element of ``self``.
|
|
383
|
+
|
|
384
|
+
EXAMPLES::
|
|
385
|
+
|
|
386
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
387
|
+
sage: G.one()
|
|
388
|
+
1
|
|
389
|
+
"""
|
|
390
|
+
return self.element_class(self, {})
|
|
391
|
+
|
|
392
|
+
def gen(self, x):
|
|
393
|
+
"""
|
|
394
|
+
The generator indexed by ``x`` of ``self``.
|
|
395
|
+
|
|
396
|
+
EXAMPLES::
|
|
397
|
+
|
|
398
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
399
|
+
sage: G.gen(0)
|
|
400
|
+
F[0]
|
|
401
|
+
sage: G.gen(2)
|
|
402
|
+
F[2]
|
|
403
|
+
"""
|
|
404
|
+
if x not in self._indices:
|
|
405
|
+
raise IndexError("{} is not in the index set".format(x))
|
|
406
|
+
try:
|
|
407
|
+
return self.element_class(self, {self._indices(x):1})
|
|
408
|
+
except TypeError: # Backup (if it is a string)
|
|
409
|
+
return self.element_class(self, {x:1})
|
|
410
|
+
|
|
411
|
+
class Element(IndexedFreeAbelianMonoidElement, IndexedFreeGroup.Element):
|
|
412
|
+
def _mul_(self, other):
|
|
413
|
+
"""
|
|
414
|
+
Multiply ``self`` by ``other``.
|
|
415
|
+
|
|
416
|
+
EXAMPLES::
|
|
417
|
+
|
|
418
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
419
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
420
|
+
sage: a*b^2*e^-1*d
|
|
421
|
+
F[0]*F[1]^2*F[3]*F[4]^-1
|
|
422
|
+
sage: (a*b^2*d^2) * (d^-4*b^-2*e)
|
|
423
|
+
F[0]*F[3]^-2*F[4]
|
|
424
|
+
sage: (a*b^-2*d^2) * (d^-2*b^2*a^-1)
|
|
425
|
+
1
|
|
426
|
+
"""
|
|
427
|
+
return self.__class__(self.parent(),
|
|
428
|
+
blas.add(self._monomial, other._monomial))
|
|
429
|
+
|
|
430
|
+
def __invert__(self):
|
|
431
|
+
"""
|
|
432
|
+
Return the inverse of ``self``.
|
|
433
|
+
|
|
434
|
+
EXAMPLES::
|
|
435
|
+
|
|
436
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
437
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
438
|
+
sage: x = a*b^2*e^-1*d; ~x
|
|
439
|
+
F[0]^-1*F[1]^-2*F[3]^-1*F[4]
|
|
440
|
+
sage: x * ~x
|
|
441
|
+
1
|
|
442
|
+
"""
|
|
443
|
+
return self ** -1
|
|
444
|
+
|
|
445
|
+
def __floordiv__(self, a):
|
|
446
|
+
"""
|
|
447
|
+
Return the division of ``self`` by ``a``.
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
452
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
453
|
+
sage: elt = a*b*c^3*d^2; elt
|
|
454
|
+
F[0]*F[1]*F[2]^3*F[3]^2
|
|
455
|
+
sage: elt // a
|
|
456
|
+
F[1]*F[2]^3*F[3]^2
|
|
457
|
+
sage: elt // c
|
|
458
|
+
F[0]*F[1]*F[2]^2*F[3]^2
|
|
459
|
+
sage: elt // (a*b*d^2)
|
|
460
|
+
F[2]^3
|
|
461
|
+
sage: elt // a^4
|
|
462
|
+
F[0]^-3*F[1]*F[2]^3*F[3]^2
|
|
463
|
+
"""
|
|
464
|
+
return self * ~a
|
|
465
|
+
|
|
466
|
+
def __pow__(self, n):
|
|
467
|
+
"""
|
|
468
|
+
Raise ``self`` to the power of ``n``.
|
|
469
|
+
|
|
470
|
+
EXAMPLES::
|
|
471
|
+
|
|
472
|
+
sage: G = Groups().Commutative().free(index_set=ZZ)
|
|
473
|
+
sage: a,b,c,d,e = [G.gen(i) for i in range(5)]
|
|
474
|
+
sage: x = a*b^2*e^-1*d; x
|
|
475
|
+
F[0]*F[1]^2*F[3]*F[4]^-1
|
|
476
|
+
sage: x^3
|
|
477
|
+
F[0]^3*F[1]^6*F[3]^3*F[4]^-3
|
|
478
|
+
sage: x^0
|
|
479
|
+
1
|
|
480
|
+
sage: x^-3
|
|
481
|
+
F[0]^-3*F[1]^-6*F[3]^-3*F[4]^3
|
|
482
|
+
"""
|
|
483
|
+
if not isinstance(n, (int, Integer)):
|
|
484
|
+
raise TypeError("Argument n (= {}) must be an integer".format(n))
|
|
485
|
+
if n == 1:
|
|
486
|
+
return self
|
|
487
|
+
if n == 0:
|
|
488
|
+
return self.parent().one()
|
|
489
|
+
return self.__class__(self.parent(), {k:v*n for k,v in self._monomial.items()})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|