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,547 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
"""
|
|
3
|
+
String Monoid Elements
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- David Kohel <kohel@maths.usyd.edu.au>, 2007-01
|
|
8
|
+
|
|
9
|
+
Elements of free string monoids, internal representation subject to change.
|
|
10
|
+
|
|
11
|
+
These are special classes of free monoid elements with distinct printing.
|
|
12
|
+
|
|
13
|
+
The internal representation of elements does not use the exponential
|
|
14
|
+
compression of FreeMonoid elements (a feature), and could be packed into words.
|
|
15
|
+
"""
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
# Copyright (C) 2007 David Kohel <kohel@maths.usyd.edu.au>
|
|
18
|
+
#
|
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ****************************************************************************
|
|
23
|
+
|
|
24
|
+
from sage.misc.lazy_import import lazy_import
|
|
25
|
+
from sage.rings.integer import Integer
|
|
26
|
+
from sage.structure.richcmp import richcmp
|
|
27
|
+
|
|
28
|
+
lazy_import('sage.rings.real_mpfr', 'RealField')
|
|
29
|
+
|
|
30
|
+
from .free_monoid_element import FreeMonoidElement
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def is_StringMonoidElement(x):
|
|
34
|
+
from sage.misc.superseded import deprecation
|
|
35
|
+
deprecation(38280,
|
|
36
|
+
"The function is_StringMonoidElement is deprecated; "
|
|
37
|
+
"use 'isinstance(..., StringMonoidElement)' instead.")
|
|
38
|
+
return isinstance(x, StringMonoidElement)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def is_AlphabeticStringMonoidElement(x):
|
|
42
|
+
from sage.misc.superseded import deprecation
|
|
43
|
+
deprecation(38280,
|
|
44
|
+
"The function is_AlphabeticStringMonoidElement is deprecated; "
|
|
45
|
+
"use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), AlphabeticStringMonoid)' instead.")
|
|
46
|
+
from .string_monoid import AlphabeticStringMonoid
|
|
47
|
+
return isinstance(x, StringMonoidElement) and \
|
|
48
|
+
isinstance(x.parent(), AlphabeticStringMonoid)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def is_BinaryStringMonoidElement(x):
|
|
52
|
+
from sage.misc.superseded import deprecation
|
|
53
|
+
deprecation(38280,
|
|
54
|
+
"The function is_BinaryStringMonoidElement is deprecated; "
|
|
55
|
+
"use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), BinaryStringMonoid)' instead.")
|
|
56
|
+
from .string_monoid import BinaryStringMonoid
|
|
57
|
+
return isinstance(x, StringMonoidElement) and \
|
|
58
|
+
isinstance(x.parent(), BinaryStringMonoid)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def is_OctalStringMonoidElement(x):
|
|
62
|
+
from sage.misc.superseded import deprecation
|
|
63
|
+
deprecation(38280,
|
|
64
|
+
"The function is_OctalStringMonoidElement is deprecated; "
|
|
65
|
+
"use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), OctalStringMonoid)' instead.")
|
|
66
|
+
from .string_monoid import OctalStringMonoid
|
|
67
|
+
return isinstance(x, StringMonoidElement) and \
|
|
68
|
+
isinstance(x.parent(), OctalStringMonoid)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def is_HexadecimalStringMonoidElement(x):
|
|
72
|
+
from sage.misc.superseded import deprecation
|
|
73
|
+
deprecation(38280,
|
|
74
|
+
"The function is_HexadecimalStringMonoidElement is deprecated; "
|
|
75
|
+
"use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), HexadecimalStringMonoid)' instead.")
|
|
76
|
+
from .string_monoid import HexadecimalStringMonoid
|
|
77
|
+
return isinstance(x, StringMonoidElement) and \
|
|
78
|
+
isinstance(x.parent(), HexadecimalStringMonoid)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def is_Radix64StringMonoidElement(x):
|
|
82
|
+
from sage.misc.superseded import deprecation
|
|
83
|
+
deprecation(38280,
|
|
84
|
+
"The function is_Radix64StringMonoidElement is deprecated; "
|
|
85
|
+
"use 'isinstance(..., StringMonoidElement) and isinstance(x.parent(), Radix64StringMonoid)' instead.")
|
|
86
|
+
from .string_monoid import Radix64StringMonoid
|
|
87
|
+
return isinstance(x, StringMonoidElement) and \
|
|
88
|
+
isinstance(x.parent(), Radix64StringMonoid)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class StringMonoidElement(FreeMonoidElement):
|
|
92
|
+
"""
|
|
93
|
+
Element of a free string monoid.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
def __init__(self, S, x, check=True):
|
|
97
|
+
"""
|
|
98
|
+
Create the element ``x`` of the StringMonoid ``S``.
|
|
99
|
+
|
|
100
|
+
This should typically be called by a StringMonoid.
|
|
101
|
+
"""
|
|
102
|
+
FreeMonoidElement.__init__(self, S, [])
|
|
103
|
+
if isinstance(x, list):
|
|
104
|
+
if check:
|
|
105
|
+
for b in x:
|
|
106
|
+
if not isinstance(b, (int, Integer)):
|
|
107
|
+
raise TypeError(
|
|
108
|
+
"x (= %s) must be a list of integers." % x)
|
|
109
|
+
self._element_list = list(x) # make copy
|
|
110
|
+
elif isinstance(x, str):
|
|
111
|
+
alphabet = list(self.parent().alphabet())
|
|
112
|
+
self._element_list = []
|
|
113
|
+
for i in range(len(x)):
|
|
114
|
+
try:
|
|
115
|
+
b = alphabet.index(x[i])
|
|
116
|
+
except ValueError:
|
|
117
|
+
raise TypeError(
|
|
118
|
+
"Argument x (= %s) is not a valid string." % x)
|
|
119
|
+
self._element_list += [b]
|
|
120
|
+
else:
|
|
121
|
+
raise TypeError("Argument x (= %s) is of the wrong type." % x)
|
|
122
|
+
|
|
123
|
+
def _richcmp_(self, other, op):
|
|
124
|
+
"""
|
|
125
|
+
Compare two free monoid elements with the same parents.
|
|
126
|
+
|
|
127
|
+
The ordering is the one on the underlying sorted list of
|
|
128
|
+
(monomial, coefficients) pairs.
|
|
129
|
+
|
|
130
|
+
EXAMPLES::
|
|
131
|
+
|
|
132
|
+
sage: S = BinaryStrings()
|
|
133
|
+
sage: (x,y) = S.gens()
|
|
134
|
+
sage: x * y < y * x
|
|
135
|
+
True
|
|
136
|
+
sage: S("01") < S("10")
|
|
137
|
+
True
|
|
138
|
+
"""
|
|
139
|
+
return richcmp(self._element_list, other._element_list, op)
|
|
140
|
+
|
|
141
|
+
def _repr_(self):
|
|
142
|
+
"""
|
|
143
|
+
The self-representation of a string monoid element. Unlike Python
|
|
144
|
+
strings we print without the enclosing quotes.
|
|
145
|
+
"""
|
|
146
|
+
S = self.parent()
|
|
147
|
+
alphabet = S.alphabet()
|
|
148
|
+
s = ''
|
|
149
|
+
for b in self._element_list:
|
|
150
|
+
c = alphabet[b]
|
|
151
|
+
s += c
|
|
152
|
+
return s
|
|
153
|
+
|
|
154
|
+
def _latex_(self):
|
|
155
|
+
"""
|
|
156
|
+
Return latex representation of ``self``.
|
|
157
|
+
|
|
158
|
+
EXAMPLES::
|
|
159
|
+
|
|
160
|
+
sage: S = BinaryStrings()
|
|
161
|
+
sage: s = S('101111000')
|
|
162
|
+
sage: latex(s)
|
|
163
|
+
101111000
|
|
164
|
+
"""
|
|
165
|
+
return self._repr_()
|
|
166
|
+
|
|
167
|
+
def __mul__(self, y):
|
|
168
|
+
"""
|
|
169
|
+
Multiply 2 free string monoid elements.
|
|
170
|
+
|
|
171
|
+
EXAMPLES::
|
|
172
|
+
|
|
173
|
+
sage: S = BinaryStrings()
|
|
174
|
+
sage: (x,y) = S.gens()
|
|
175
|
+
sage: x*y
|
|
176
|
+
01
|
|
177
|
+
"""
|
|
178
|
+
if not isinstance(y, StringMonoidElement):
|
|
179
|
+
raise TypeError("Argument y (= %s) is of wrong type." % y)
|
|
180
|
+
S = self.parent()
|
|
181
|
+
x_elt = self._element_list
|
|
182
|
+
y_elt = y._element_list
|
|
183
|
+
z = S('')
|
|
184
|
+
z._element_list = x_elt + y_elt
|
|
185
|
+
return z
|
|
186
|
+
|
|
187
|
+
def __pow__(self, n):
|
|
188
|
+
"""
|
|
189
|
+
Return the `n`-th power of the string element.
|
|
190
|
+
|
|
191
|
+
EXAMPLES::
|
|
192
|
+
|
|
193
|
+
sage: (x,y) = BinaryStrings().gens()
|
|
194
|
+
sage: x**3 * y**5 * x**7
|
|
195
|
+
000111110000000
|
|
196
|
+
sage: x**0
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
Note that raising to a negative power is *not* a constructor
|
|
200
|
+
for an element of the corresponding free group (yet).
|
|
201
|
+
|
|
202
|
+
::
|
|
203
|
+
|
|
204
|
+
sage: x**(-1)
|
|
205
|
+
Traceback (most recent call last):
|
|
206
|
+
...
|
|
207
|
+
IndexError: Argument n (= -1) must be nonnegative.
|
|
208
|
+
"""
|
|
209
|
+
if not isinstance(n, (int, Integer)):
|
|
210
|
+
raise TypeError("Argument n (= %s) must be an integer." % n)
|
|
211
|
+
if n < 0:
|
|
212
|
+
raise IndexError("Argument n (= %s) must be nonnegative." % n)
|
|
213
|
+
elif n == 0:
|
|
214
|
+
return self.parent()('')
|
|
215
|
+
elif n == 1:
|
|
216
|
+
return self
|
|
217
|
+
z = self.parent()('')
|
|
218
|
+
z._element_list = self._element_list * n
|
|
219
|
+
return z
|
|
220
|
+
|
|
221
|
+
def __len__(self):
|
|
222
|
+
"""
|
|
223
|
+
Return the number of products that occur in this monoid element.
|
|
224
|
+
For example, the length of the identity is 0, and the length
|
|
225
|
+
of the monoid `x_0^2x_1` is three.
|
|
226
|
+
|
|
227
|
+
EXAMPLES::
|
|
228
|
+
|
|
229
|
+
sage: S = BinaryStrings()
|
|
230
|
+
sage: z = S('')
|
|
231
|
+
sage: len(z)
|
|
232
|
+
0
|
|
233
|
+
sage: (x,y) = S.gens()
|
|
234
|
+
sage: len(x**2 * y**3)
|
|
235
|
+
5
|
|
236
|
+
"""
|
|
237
|
+
return len(self._element_list)
|
|
238
|
+
|
|
239
|
+
def __iter__(self):
|
|
240
|
+
"""
|
|
241
|
+
Return an iterator over this element as a string.
|
|
242
|
+
|
|
243
|
+
EXAMPLES::
|
|
244
|
+
|
|
245
|
+
sage: # needs sage.rings.real_mpfr
|
|
246
|
+
sage: t = AlphabeticStrings()('SHRUBBERY')
|
|
247
|
+
sage: next(t.__iter__())
|
|
248
|
+
S
|
|
249
|
+
sage: list(t)
|
|
250
|
+
[S, H, R, U, B, B, E, R, Y]
|
|
251
|
+
"""
|
|
252
|
+
l = len(self._element_list)
|
|
253
|
+
i = 0
|
|
254
|
+
while i < l:
|
|
255
|
+
yield self[i]
|
|
256
|
+
i += 1
|
|
257
|
+
|
|
258
|
+
def __getitem__(self, n):
|
|
259
|
+
"""
|
|
260
|
+
Return the n-th string character.
|
|
261
|
+
|
|
262
|
+
EXAMPLES::
|
|
263
|
+
|
|
264
|
+
sage: # needs sage.rings.real_mpfr
|
|
265
|
+
sage: t = AlphabeticStrings()('SHRUBBERY')
|
|
266
|
+
sage: t[0]
|
|
267
|
+
S
|
|
268
|
+
sage: t[3]
|
|
269
|
+
U
|
|
270
|
+
sage: t[-1]
|
|
271
|
+
Y
|
|
272
|
+
"""
|
|
273
|
+
try:
|
|
274
|
+
c = self._element_list[n]
|
|
275
|
+
except Exception:
|
|
276
|
+
raise IndexError("Argument n (= %s) is not a valid index." % n)
|
|
277
|
+
if not isinstance(c, list):
|
|
278
|
+
c = [c]
|
|
279
|
+
return self.parent()(c)
|
|
280
|
+
|
|
281
|
+
def decoding(self, padic=False):
|
|
282
|
+
r"""
|
|
283
|
+
The byte string associated to a binary or hexadecimal string
|
|
284
|
+
monoid element.
|
|
285
|
+
|
|
286
|
+
EXAMPLES::
|
|
287
|
+
|
|
288
|
+
sage: S = HexadecimalStrings()
|
|
289
|
+
sage: s = S.encoding("A..Za..z"); s
|
|
290
|
+
412e2e5a612e2e7a
|
|
291
|
+
sage: s.decoding()
|
|
292
|
+
'A..Za..z'
|
|
293
|
+
sage: s = S.encoding("A..Za..z",padic=True); s
|
|
294
|
+
14e2e2a516e2e2a7
|
|
295
|
+
sage: s.decoding()
|
|
296
|
+
'\x14\xe2\xe2\xa5\x16\xe2\xe2\xa7'
|
|
297
|
+
sage: s.decoding(padic=True)
|
|
298
|
+
'A..Za..z'
|
|
299
|
+
sage: S = BinaryStrings()
|
|
300
|
+
sage: s = S.encoding("A..Za..z"); s
|
|
301
|
+
0100000100101110001011100101101001100001001011100010111001111010
|
|
302
|
+
sage: s.decoding()
|
|
303
|
+
'A..Za..z'
|
|
304
|
+
sage: s = S.encoding("A..Za..z",padic=True); s
|
|
305
|
+
1000001001110100011101000101101010000110011101000111010001011110
|
|
306
|
+
sage: s.decoding()
|
|
307
|
+
'\x82ttZ\x86tt^'
|
|
308
|
+
sage: s.decoding(padic=True)
|
|
309
|
+
'A..Za..z'
|
|
310
|
+
"""
|
|
311
|
+
S = self.parent()
|
|
312
|
+
from .string_monoid import (AlphabeticStringMonoid,
|
|
313
|
+
BinaryStringMonoid,
|
|
314
|
+
HexadecimalStringMonoid)
|
|
315
|
+
if isinstance(S, AlphabeticStringMonoid):
|
|
316
|
+
return ''.join(chr(65 + i) for i in self._element_list)
|
|
317
|
+
n = len(self)
|
|
318
|
+
if isinstance(S, HexadecimalStringMonoid):
|
|
319
|
+
if n % 2:
|
|
320
|
+
"String %s must have even length to determine a byte character string." % str(self)
|
|
321
|
+
s = []
|
|
322
|
+
x = self._element_list
|
|
323
|
+
for k in range(n//2):
|
|
324
|
+
m = 2*k
|
|
325
|
+
if padic:
|
|
326
|
+
c = chr(x[m]+16*x[m+1])
|
|
327
|
+
else:
|
|
328
|
+
c = chr(16*x[m]+x[m+1])
|
|
329
|
+
s.append(c)
|
|
330
|
+
return ''.join(s)
|
|
331
|
+
if isinstance(S, BinaryStringMonoid):
|
|
332
|
+
if not n % 8 == 0:
|
|
333
|
+
"String %s must have even length 0 mod 8 to determine a byte character string." % str(self)
|
|
334
|
+
pows = [2**i for i in range(8)]
|
|
335
|
+
s = []
|
|
336
|
+
x = self._element_list
|
|
337
|
+
for k in range(n//8):
|
|
338
|
+
m = 8*k
|
|
339
|
+
if padic:
|
|
340
|
+
c = chr(sum([x[m+i] * pows[i] for i in range(8)]))
|
|
341
|
+
else:
|
|
342
|
+
c = chr(sum([x[m+7-i] * pows[i] for i in range(8)]))
|
|
343
|
+
s.append(c)
|
|
344
|
+
return ''.join(s)
|
|
345
|
+
raise TypeError(
|
|
346
|
+
"Argument %s must be an alphabetic, binary, or hexadecimal string." % str(self))
|
|
347
|
+
|
|
348
|
+
def coincidence_index(self, prec=0):
|
|
349
|
+
"""
|
|
350
|
+
Return the probability of two randomly chosen characters being equal.
|
|
351
|
+
"""
|
|
352
|
+
if prec == 0:
|
|
353
|
+
RR = RealField()
|
|
354
|
+
else:
|
|
355
|
+
RR = RealField(prec)
|
|
356
|
+
char_dict = {}
|
|
357
|
+
for i in self._element_list:
|
|
358
|
+
if i in char_dict:
|
|
359
|
+
char_dict[i] += 1
|
|
360
|
+
else:
|
|
361
|
+
char_dict[i] = 1
|
|
362
|
+
nn = 0
|
|
363
|
+
ci_num = 0
|
|
364
|
+
for ni in char_dict.values():
|
|
365
|
+
nn += ni
|
|
366
|
+
ci_num += ni * (ni - 1)
|
|
367
|
+
ci_den = nn * (nn - 1)
|
|
368
|
+
return RR(ci_num) / ci_den
|
|
369
|
+
|
|
370
|
+
def character_count(self):
|
|
371
|
+
r"""
|
|
372
|
+
Return the count of each unique character.
|
|
373
|
+
|
|
374
|
+
EXAMPLES:
|
|
375
|
+
|
|
376
|
+
Count the character frequency in an object comprised of capital
|
|
377
|
+
letters of the English alphabet::
|
|
378
|
+
|
|
379
|
+
sage: # needs sage.rings.real_mpfr
|
|
380
|
+
sage: M = AlphabeticStrings().encoding("abcabf")
|
|
381
|
+
sage: sorted(M.character_count().items())
|
|
382
|
+
[(A, 2), (B, 2), (C, 1), (F, 1)]
|
|
383
|
+
|
|
384
|
+
In an object comprised of binary numbers::
|
|
385
|
+
|
|
386
|
+
sage: M = BinaryStrings().encoding("abcabf")
|
|
387
|
+
sage: sorted(M.character_count().items())
|
|
388
|
+
[(0, 28), (1, 20)]
|
|
389
|
+
|
|
390
|
+
In an object comprised of octal numbers::
|
|
391
|
+
|
|
392
|
+
sage: A = OctalStrings()
|
|
393
|
+
sage: M = A([1, 2, 3, 2, 5, 3])
|
|
394
|
+
sage: sorted(M.character_count().items())
|
|
395
|
+
[(1, 1), (2, 2), (3, 2), (5, 1)]
|
|
396
|
+
|
|
397
|
+
In an object comprised of hexadecimal numbers::
|
|
398
|
+
|
|
399
|
+
sage: A = HexadecimalStrings()
|
|
400
|
+
sage: M = A([1, 2, 4, 6, 2, 4, 15])
|
|
401
|
+
sage: sorted(M.character_count().items())
|
|
402
|
+
[(1, 1), (2, 2), (4, 2), (6, 1), (f, 1)]
|
|
403
|
+
|
|
404
|
+
In an object comprised of radix-64 characters::
|
|
405
|
+
|
|
406
|
+
sage: A = Radix64Strings()
|
|
407
|
+
sage: M = A([1, 2, 63, 45, 45, 10]); M
|
|
408
|
+
BC/ttK
|
|
409
|
+
sage: sorted(M.character_count().items())
|
|
410
|
+
[(B, 1), (C, 1), (K, 1), (t, 2), (/, 1)]
|
|
411
|
+
|
|
412
|
+
TESTS:
|
|
413
|
+
|
|
414
|
+
Empty strings return no counts of character frequency::
|
|
415
|
+
|
|
416
|
+
sage: M = AlphabeticStrings().encoding("") # needs sage.rings.real_mpfr
|
|
417
|
+
sage: M.character_count() # needs sage.rings.real_mpfr
|
|
418
|
+
{}
|
|
419
|
+
sage: M = BinaryStrings().encoding("")
|
|
420
|
+
sage: M.character_count()
|
|
421
|
+
{}
|
|
422
|
+
sage: A = OctalStrings()
|
|
423
|
+
sage: M = A([])
|
|
424
|
+
sage: M.character_count()
|
|
425
|
+
{}
|
|
426
|
+
sage: A = HexadecimalStrings()
|
|
427
|
+
sage: M = A([])
|
|
428
|
+
sage: M.character_count()
|
|
429
|
+
{}
|
|
430
|
+
sage: A = Radix64Strings()
|
|
431
|
+
sage: M = A([])
|
|
432
|
+
sage: M.character_count()
|
|
433
|
+
{}
|
|
434
|
+
"""
|
|
435
|
+
# the character frequency, i.e. the character count
|
|
436
|
+
CF = {}
|
|
437
|
+
for e in self:
|
|
438
|
+
if e in CF:
|
|
439
|
+
CF[e] += 1
|
|
440
|
+
else:
|
|
441
|
+
CF.setdefault(e, 1)
|
|
442
|
+
return CF
|
|
443
|
+
|
|
444
|
+
def frequency_distribution(self, length=1, prec=0):
|
|
445
|
+
"""
|
|
446
|
+
Return the probability space of character frequencies.
|
|
447
|
+
|
|
448
|
+
The output of this method is different from that of the method
|
|
449
|
+
:func:`characteristic_frequency()
|
|
450
|
+
<sage.monoids.string_monoid.AlphabeticStringMonoid.characteristic_frequency>`.
|
|
451
|
+
|
|
452
|
+
One can think of the characteristic frequency probability of an
|
|
453
|
+
element in an alphabet `A` as the expected probability of that element
|
|
454
|
+
occurring. Let `S` be a string encoded using elements of `A`. The
|
|
455
|
+
frequency probability distribution corresponding to `S` provides us
|
|
456
|
+
with the frequency probability of each element of `A` as observed
|
|
457
|
+
occurring in `S`. Thus one distribution provides expected
|
|
458
|
+
probabilities, while the other provides observed probabilities.
|
|
459
|
+
|
|
460
|
+
INPUT:
|
|
461
|
+
|
|
462
|
+
- ``length`` -- (default: ``1``) if ``length=1`` then consider the
|
|
463
|
+
probability space of monogram frequency, i.e. probability
|
|
464
|
+
distribution of single characters. If ``length=2`` then consider
|
|
465
|
+
the probability space of digram frequency, i.e. probability
|
|
466
|
+
distribution of pairs of characters. This method currently
|
|
467
|
+
supports the generation of probability spaces for monogram
|
|
468
|
+
frequency (``length=1``) and digram frequency (``length=2``).
|
|
469
|
+
|
|
470
|
+
- ``prec`` -- (default: ``0``) a nonnegative integer representing
|
|
471
|
+
the precision (in number of bits) of a floating-point number. The
|
|
472
|
+
default value ``prec=0`` means that we use 53 bits to represent
|
|
473
|
+
the mantissa of a floating-point number. For more information on
|
|
474
|
+
the precision of floating-point numbers, see the function
|
|
475
|
+
:func:`RealField() <sage.rings.real_mpfr.RealField>` or refer to the module
|
|
476
|
+
:mod:`real_mpfr <sage.rings.real_mpfr>`.
|
|
477
|
+
|
|
478
|
+
EXAMPLES:
|
|
479
|
+
|
|
480
|
+
Capital letters of the English alphabet::
|
|
481
|
+
|
|
482
|
+
sage: # needs sage.modules sage.rings.real_mpfr
|
|
483
|
+
sage: M = AlphabeticStrings().encoding("abcd")
|
|
484
|
+
sage: L = M.frequency_distribution().function()
|
|
485
|
+
sage: sorted(L.items())
|
|
486
|
+
<BLANKLINE>
|
|
487
|
+
[(A, 0.250000000000000),
|
|
488
|
+
(B, 0.250000000000000),
|
|
489
|
+
(C, 0.250000000000000),
|
|
490
|
+
(D, 0.250000000000000)]
|
|
491
|
+
|
|
492
|
+
The binary number system::
|
|
493
|
+
|
|
494
|
+
sage: # needs sage.modules
|
|
495
|
+
sage: M = BinaryStrings().encoding("abcd")
|
|
496
|
+
sage: L = M.frequency_distribution().function()
|
|
497
|
+
sage: sorted(L.items())
|
|
498
|
+
[(0, 0.593750000000000), (1, 0.406250000000000)]
|
|
499
|
+
|
|
500
|
+
The hexadecimal number system::
|
|
501
|
+
|
|
502
|
+
sage: # needs sage.modules
|
|
503
|
+
sage: M = HexadecimalStrings().encoding("abcd")
|
|
504
|
+
sage: L = M.frequency_distribution().function()
|
|
505
|
+
sage: sorted(L.items())
|
|
506
|
+
<BLANKLINE>
|
|
507
|
+
[(1, 0.125000000000000),
|
|
508
|
+
(2, 0.125000000000000),
|
|
509
|
+
(3, 0.125000000000000),
|
|
510
|
+
(4, 0.125000000000000),
|
|
511
|
+
(6, 0.500000000000000)]
|
|
512
|
+
|
|
513
|
+
Get the observed frequency probability distribution of digrams in the
|
|
514
|
+
string "ABCD". This string consists of the following digrams: "AB",
|
|
515
|
+
"BC", and "CD". Now find out the frequency probability of each of
|
|
516
|
+
these digrams as they occur in the string "ABCD"::
|
|
517
|
+
|
|
518
|
+
sage: # needs sage.modules sage.rings.real_mpfr
|
|
519
|
+
sage: M = AlphabeticStrings().encoding("abcd")
|
|
520
|
+
sage: D = M.frequency_distribution(length=2).function()
|
|
521
|
+
sage: sorted(D.items())
|
|
522
|
+
[(AB, 0.333333333333333), (BC, 0.333333333333333), (CD, 0.333333333333333)]
|
|
523
|
+
"""
|
|
524
|
+
from sage.probability.random_variable import DiscreteProbabilitySpace
|
|
525
|
+
if length not in (1, 2):
|
|
526
|
+
raise NotImplementedError("Not implemented")
|
|
527
|
+
if prec == 0:
|
|
528
|
+
RR = RealField()
|
|
529
|
+
else:
|
|
530
|
+
RR = RealField(prec)
|
|
531
|
+
S = self.parent()
|
|
532
|
+
if length == 1:
|
|
533
|
+
Alph = S.gens()
|
|
534
|
+
else:
|
|
535
|
+
Alph = tuple(x * y for x in S.gens() for y in S.gens())
|
|
536
|
+
X = {}
|
|
537
|
+
N = len(self) - length + 1
|
|
538
|
+
eps = RR(Integer(1) / N)
|
|
539
|
+
for i in range(N):
|
|
540
|
+
c = self[i:i+length]
|
|
541
|
+
if c in X:
|
|
542
|
+
X[c] += eps
|
|
543
|
+
else:
|
|
544
|
+
X[c] = eps
|
|
545
|
+
# Return a dictionary of probability distribution. This should
|
|
546
|
+
# allow for easier parsing of the dictionary.
|
|
547
|
+
return DiscreteProbabilitySpace(Alph, X, RR)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
"Utility functions on strings"
|
|
3
|
+
|
|
4
|
+
# ****************************************************************************
|
|
5
|
+
# Copyright (C) 2007 David Kohel <kohel@maths.usyd.edu.au>
|
|
6
|
+
#
|
|
7
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
8
|
+
#
|
|
9
|
+
# https://www.gnu.org/licenses/
|
|
10
|
+
# ****************************************************************************
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from sage.misc.lazy_import import lazy_import
|
|
14
|
+
from .string_monoid_element import StringMonoidElement
|
|
15
|
+
|
|
16
|
+
lazy_import('sage.rings.real_mpfr', 'RealField')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def strip_encoding(S) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Return the upper case string of S stripped of all non-alphabetic characters.
|
|
22
|
+
|
|
23
|
+
EXAMPLES::
|
|
24
|
+
|
|
25
|
+
sage: S = "The cat in the hat."
|
|
26
|
+
sage: strip_encoding(S)
|
|
27
|
+
'THECATINTHEHAT'
|
|
28
|
+
|
|
29
|
+
TESTS::
|
|
30
|
+
|
|
31
|
+
sage: strip_encoding(44)
|
|
32
|
+
Traceback (most recent call last):
|
|
33
|
+
...
|
|
34
|
+
TypeError: argument S (= 44) must be a string
|
|
35
|
+
"""
|
|
36
|
+
if not isinstance(S, str):
|
|
37
|
+
raise TypeError(f"argument S (= {S}) must be a string")
|
|
38
|
+
return ''.join(letter.upper() for letter in S if letter.isalpha())
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def frequency_distribution(S, n=1, field=None):
|
|
42
|
+
"""
|
|
43
|
+
The probability space of frequencies of n-character substrings of S.
|
|
44
|
+
|
|
45
|
+
EXAMPLES::
|
|
46
|
+
|
|
47
|
+
sage: frequency_distribution('banana not a nana nor ananas', 2) # needs sage.modules
|
|
48
|
+
Discrete probability space defined by {' a': 0.0740740740740741,
|
|
49
|
+
' n': 0.111111111111111,
|
|
50
|
+
'a ': 0.111111111111111,
|
|
51
|
+
'an': 0.185185185185185,
|
|
52
|
+
'as': 0.0370370370370370,
|
|
53
|
+
'ba': 0.0370370370370370,
|
|
54
|
+
'na': 0.222222222222222,
|
|
55
|
+
'no': 0.0740740740740741,
|
|
56
|
+
'or': 0.0370370370370370,
|
|
57
|
+
'ot': 0.0370370370370370,
|
|
58
|
+
'r ': 0.0370370370370370,
|
|
59
|
+
't ': 0.0370370370370370}
|
|
60
|
+
"""
|
|
61
|
+
from sage.probability.random_variable import DiscreteProbabilitySpace
|
|
62
|
+
if isinstance(S, tuple):
|
|
63
|
+
S = list(S)
|
|
64
|
+
elif isinstance(S, (str, StringMonoidElement)):
|
|
65
|
+
S = [S[i:i+n] for i in range(len(S)-n+1)]
|
|
66
|
+
if field is None:
|
|
67
|
+
field = RealField()
|
|
68
|
+
if isinstance(S, list):
|
|
69
|
+
P: dict[str, Any] = {}
|
|
70
|
+
N = len(S)
|
|
71
|
+
eps = field.one() / N
|
|
72
|
+
for i in range(N):
|
|
73
|
+
c = S[i]
|
|
74
|
+
if c in P:
|
|
75
|
+
P[c] += eps
|
|
76
|
+
else:
|
|
77
|
+
P[c] = eps
|
|
78
|
+
return DiscreteProbabilitySpace(S, P, field)
|
|
79
|
+
raise TypeError("Argument S (= %s) must be a string, list, or tuple.")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def coincidence_index(S, n=1):
|
|
83
|
+
"""
|
|
84
|
+
Return the coincidence index of the string ``S``.
|
|
85
|
+
|
|
86
|
+
EXAMPLES::
|
|
87
|
+
|
|
88
|
+
sage: S = strip_encoding("The cat in the hat.")
|
|
89
|
+
sage: coincidence_index(S) # needs sage.rings.real_mpfr
|
|
90
|
+
0.120879120879121
|
|
91
|
+
"""
|
|
92
|
+
if not isinstance(S, str):
|
|
93
|
+
try:
|
|
94
|
+
S.coincidence_index(n)
|
|
95
|
+
except AttributeError:
|
|
96
|
+
raise TypeError("Argument S (= %s) must be a string.")
|
|
97
|
+
S = strip_encoding(S)
|
|
98
|
+
N = len(S)-n+1
|
|
99
|
+
X: dict[str, int] = {}
|
|
100
|
+
for i in range(N):
|
|
101
|
+
c = S[i:i+n]
|
|
102
|
+
if c in X:
|
|
103
|
+
X[c] += 1
|
|
104
|
+
else:
|
|
105
|
+
X[c] = 1
|
|
106
|
+
RR = RealField()
|
|
107
|
+
return RR(sum([m*(m-1) for m in X.values()]))/RR(N*(N-1))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def coincidence_discriminant(S, n=2):
|
|
111
|
+
"""
|
|
112
|
+
INPUT:
|
|
113
|
+
|
|
114
|
+
- ``S`` --tuple of strings; e.g. produced as decimation of transposition
|
|
115
|
+
ciphertext, or a sample plaintext
|
|
116
|
+
|
|
117
|
+
OUTPUT:
|
|
118
|
+
|
|
119
|
+
A measure of the difference of probability of association of
|
|
120
|
+
character pairs, relative to their independent one-character probabilities.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: S = strip_encoding("The cat in the hat.")
|
|
125
|
+
sage: coincidence_discriminant([ S[i:i+2] for i in range(len(S)-1) ]) # needs sage.modules
|
|
126
|
+
0.0827001855677322
|
|
127
|
+
"""
|
|
128
|
+
if not isinstance(S, (list, tuple)):
|
|
129
|
+
raise TypeError("Argument S (= %s) must be a list or tuple" % S)
|
|
130
|
+
if n != 2:
|
|
131
|
+
raise ValueError("Argument n (= %s) is only implemented for n = 2" % n)
|
|
132
|
+
if not all(isinstance(c, (str, StringMonoidElement)) for c in S):
|
|
133
|
+
raise TypeError("Argument S (= %s) must be a list of strings.")
|
|
134
|
+
if not all(len(c) == n for c in S):
|
|
135
|
+
raise ValueError("Argument S (= %s) must be a list of strings of length 2" % S)
|
|
136
|
+
X1 = [frequency_distribution([s[i] for s in S]) for i in range(2)]
|
|
137
|
+
XX = frequency_distribution(S)
|
|
138
|
+
if isinstance(S[0], StringMonoidElement):
|
|
139
|
+
M = S[0].parent()
|
|
140
|
+
n = M.ngens()
|
|
141
|
+
return sum([(XX(M([i, j]))-X1[0](M([i]))*X1[1](M([j])))**2 for i in range(n) for j in range(n)])
|
|
142
|
+
AZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
143
|
+
return sum([(XX(AZ[i]+AZ[j])-X1[0](AZ[i])*X1[1](AZ[j]))**2 for i in range(26) for j in range(26)])
|