passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.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/DELVEWHEEL +2 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +401 -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-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
- passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +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 +44 -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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
sage/sat/all.py
ADDED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: optional - pycryptosat, needs sage.modules sage.rings.polynomial.pbori
|
|
3
|
+
"""
|
|
4
|
+
SAT Functions for Boolean Polynomials
|
|
5
|
+
|
|
6
|
+
These highlevel functions support solving and learning from Boolean polynomial systems. In this
|
|
7
|
+
context, "learning" means the construction of new polynomials in the ideal spanned by the original
|
|
8
|
+
polynomials.
|
|
9
|
+
|
|
10
|
+
AUTHOR:
|
|
11
|
+
|
|
12
|
+
- Martin Albrecht (2012): initial version
|
|
13
|
+
|
|
14
|
+
Functions
|
|
15
|
+
^^^^^^^^^
|
|
16
|
+
"""
|
|
17
|
+
# ###########################################################################
|
|
18
|
+
# Copyright (C) 2012 Martin Albrecht <martinralbrecht@googlemail.com>
|
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
20
|
+
# The full text of the GPL is available at:
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ###########################################################################
|
|
23
|
+
from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
|
|
24
|
+
from sage.sat.converters import ANF2CNFConverter
|
|
25
|
+
from sage.sat.solvers import SatSolver
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds):
|
|
29
|
+
"""
|
|
30
|
+
Solve system of Boolean polynomials ``F`` by solving the
|
|
31
|
+
SAT-problem -- produced by ``converter`` -- using ``solver``.
|
|
32
|
+
|
|
33
|
+
INPUT:
|
|
34
|
+
|
|
35
|
+
- ``F`` -- a sequence of Boolean polynomials
|
|
36
|
+
|
|
37
|
+
- ``n`` -- number of solutions to return. If ``n`` is +infinity
|
|
38
|
+
then all solutions are returned. If ``n <infinity`` then ``n``
|
|
39
|
+
solutions are returned if ``F`` has at least ``n``
|
|
40
|
+
solutions. Otherwise, all solutions of ``F`` are
|
|
41
|
+
returned. (default: ``1``)
|
|
42
|
+
|
|
43
|
+
- ``converter`` -- an ANF to CNF converter class or object. If
|
|
44
|
+
``converter`` is ``None`` then
|
|
45
|
+
:class:`sage.sat.converters.polybori.CNFEncoder` is used to
|
|
46
|
+
construct a new converter. (default: ``None``)
|
|
47
|
+
|
|
48
|
+
- ``solver`` -- a SAT-solver class or object. If ``solver`` is
|
|
49
|
+
``None`` then :class:`sage.sat.solvers.cryptominisat.CryptoMiniSat`
|
|
50
|
+
is used to construct a new converter. (default: ``None``)
|
|
51
|
+
|
|
52
|
+
- ``target_variables`` -- list of variables. The elements of the list are
|
|
53
|
+
used to exclude a particular combination of variable assignments of a
|
|
54
|
+
solution from any further solution. Furthermore ``target_variables``
|
|
55
|
+
denotes which variable-value pairs appear in the solutions. If
|
|
56
|
+
``target_variables`` is ``None`` all variables appearing in the
|
|
57
|
+
polynomials of ``F`` are used to construct exclusion clauses.
|
|
58
|
+
(default: ``None``)
|
|
59
|
+
|
|
60
|
+
- ``**kwds`` -- parameters can be passed to the converter and the
|
|
61
|
+
solver by prefixing them with ``c_`` and ``s_`` respectively. For
|
|
62
|
+
example, to increase CryptoMiniSat's verbosity level, pass
|
|
63
|
+
``s_verbosity=1``.
|
|
64
|
+
|
|
65
|
+
OUTPUT:
|
|
66
|
+
|
|
67
|
+
A list of dictionaries, each of which contains a variable assignment
|
|
68
|
+
solving ``F``.
|
|
69
|
+
|
|
70
|
+
EXAMPLES:
|
|
71
|
+
|
|
72
|
+
We construct a very small-scale AES system of equations::
|
|
73
|
+
|
|
74
|
+
sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True)
|
|
75
|
+
sage: while True: # workaround (see :issue:`31891`)
|
|
76
|
+
....: try:
|
|
77
|
+
....: F, s = sr.polynomial_system()
|
|
78
|
+
....: break
|
|
79
|
+
....: except ZeroDivisionError:
|
|
80
|
+
....: pass
|
|
81
|
+
|
|
82
|
+
and pass it to a SAT solver::
|
|
83
|
+
|
|
84
|
+
sage: from sage.sat.boolean_polynomials import solve as solve_sat
|
|
85
|
+
sage: s = solve_sat(F)
|
|
86
|
+
sage: F.subs(s[0])
|
|
87
|
+
Polynomial Sequence with 36 Polynomials in 0 Variables
|
|
88
|
+
|
|
89
|
+
This time we pass a few options through to the converter and the solver::
|
|
90
|
+
|
|
91
|
+
sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8)
|
|
92
|
+
sage: F.subs(s[0])
|
|
93
|
+
Polynomial Sequence with 36 Polynomials in 0 Variables
|
|
94
|
+
|
|
95
|
+
We construct a very simple system with three solutions
|
|
96
|
+
and ask for a specific number of solutions::
|
|
97
|
+
|
|
98
|
+
sage: B.<a,b> = BooleanPolynomialRing()
|
|
99
|
+
sage: f = a*b
|
|
100
|
+
sage: l = solve_sat([f],n=1)
|
|
101
|
+
sage: len(l) == 1, f.subs(l[0])
|
|
102
|
+
(True, 0)
|
|
103
|
+
|
|
104
|
+
sage: l = solve_sat([a*b],n=2)
|
|
105
|
+
sage: len(l) == 2, f.subs(l[0]), f.subs(l[1])
|
|
106
|
+
(True, 0, 0)
|
|
107
|
+
|
|
108
|
+
sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3))
|
|
109
|
+
[(0, 0), (0, 1), (1, 0)]
|
|
110
|
+
sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4))
|
|
111
|
+
[(0, 0), (0, 1), (1, 0)]
|
|
112
|
+
sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity))
|
|
113
|
+
[(0, 0), (0, 1), (1, 0)]
|
|
114
|
+
|
|
115
|
+
In the next example we see how the ``target_variables`` parameter works::
|
|
116
|
+
|
|
117
|
+
sage: from sage.sat.boolean_polynomials import solve as solve_sat
|
|
118
|
+
sage: R.<a,b,c,d> = BooleanPolynomialRing()
|
|
119
|
+
sage: F = [a + b, a + c + d]
|
|
120
|
+
|
|
121
|
+
First the normal use case::
|
|
122
|
+
|
|
123
|
+
sage: sorted((D[a], D[b], D[c], D[d])
|
|
124
|
+
....: for D in solve_sat(F, n=infinity))
|
|
125
|
+
[(0, 0, 0, 0), (0, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)]
|
|
126
|
+
|
|
127
|
+
Now we are only interested in the solutions of the variables a and b::
|
|
128
|
+
|
|
129
|
+
sage: solve_sat(F, n=infinity, target_variables=[a,b])
|
|
130
|
+
[{b: 0, a: 0}, {b: 1, a: 1}]
|
|
131
|
+
|
|
132
|
+
Here, we generate and solve the cubic equations of the AES SBox (see :issue:`26676`)::
|
|
133
|
+
|
|
134
|
+
sage: # long time
|
|
135
|
+
sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
|
|
136
|
+
sage: from sage.sat.boolean_polynomials import solve as solve_sat
|
|
137
|
+
sage: sr = sage.crypto.mq.SR(1, 4, 4, 8,
|
|
138
|
+
....: allow_zero_inversions=True)
|
|
139
|
+
sage: sb = sr.sbox()
|
|
140
|
+
sage: eqs = sb.polynomials(degree=3)
|
|
141
|
+
sage: eqs = PolynomialSequence(eqs)
|
|
142
|
+
sage: variables = map(str, eqs.variables())
|
|
143
|
+
sage: variables = ",".join(variables)
|
|
144
|
+
sage: R = BooleanPolynomialRing(16, variables)
|
|
145
|
+
sage: eqs = [R(eq) for eq in eqs]
|
|
146
|
+
sage: sls_aes = solve_sat(eqs, n=infinity)
|
|
147
|
+
sage: len(sls_aes)
|
|
148
|
+
256
|
|
149
|
+
|
|
150
|
+
TESTS:
|
|
151
|
+
|
|
152
|
+
Test that :issue:`26676` is fixed::
|
|
153
|
+
|
|
154
|
+
sage: varl = ['k{0}'.format(p) for p in range(29)]
|
|
155
|
+
sage: B = BooleanPolynomialRing(names=varl)
|
|
156
|
+
sage: B.inject_variables(verbose=False)
|
|
157
|
+
sage: keqs = [
|
|
158
|
+
....: k0 + k6 + 1,
|
|
159
|
+
....: k3 + k9 + 1,
|
|
160
|
+
....: k5*k18 + k6*k18 + k7*k16 + k7*k10,
|
|
161
|
+
....: k9*k17 + k8*k24 + k11*k17,
|
|
162
|
+
....: k1*k13 + k1*k15 + k2*k12 + k3*k15 + k4*k14,
|
|
163
|
+
....: k5*k18 + k6*k16 + k7*k18,
|
|
164
|
+
....: k3 + k26,
|
|
165
|
+
....: k0 + k19,
|
|
166
|
+
....: k9 + k28,
|
|
167
|
+
....: k11 + k20]
|
|
168
|
+
sage: from sage.sat.boolean_polynomials import solve as solve_sat
|
|
169
|
+
sage: solve_sat(keqs, n=1, solver=SAT('cryptominisat'))
|
|
170
|
+
[{k28: 0,
|
|
171
|
+
k26: 1,
|
|
172
|
+
k24: 0,
|
|
173
|
+
k20: 0,
|
|
174
|
+
k19: 0,
|
|
175
|
+
k18: 0,
|
|
176
|
+
k17: 0,
|
|
177
|
+
k16: 0,
|
|
178
|
+
k15: 0,
|
|
179
|
+
k14: 0,
|
|
180
|
+
k13: 0,
|
|
181
|
+
k12: 0,
|
|
182
|
+
k11: 0,
|
|
183
|
+
k10: 0,
|
|
184
|
+
k9: 0,
|
|
185
|
+
k8: 0,
|
|
186
|
+
k7: 0,
|
|
187
|
+
k6: 1,
|
|
188
|
+
k5: 0,
|
|
189
|
+
k4: 0,
|
|
190
|
+
k3: 1,
|
|
191
|
+
k2: 0,
|
|
192
|
+
k1: 0,
|
|
193
|
+
k0: 0}]
|
|
194
|
+
sage: solve_sat(keqs, n=1, solver=SAT('picosat')) # optional - pycosat
|
|
195
|
+
[{k28: 0,
|
|
196
|
+
k26: 1,
|
|
197
|
+
k24: 0,
|
|
198
|
+
k20: 0,
|
|
199
|
+
k19: 0,
|
|
200
|
+
k18: 0,
|
|
201
|
+
k17: 0,
|
|
202
|
+
k16: 0,
|
|
203
|
+
k15: 0,
|
|
204
|
+
k14: 0,
|
|
205
|
+
k13: 1,
|
|
206
|
+
k12: 1,
|
|
207
|
+
k11: 0,
|
|
208
|
+
k10: 0,
|
|
209
|
+
k9: 0,
|
|
210
|
+
k8: 0,
|
|
211
|
+
k7: 0,
|
|
212
|
+
k6: 1,
|
|
213
|
+
k5: 0,
|
|
214
|
+
k4: 1,
|
|
215
|
+
k3: 1,
|
|
216
|
+
k2: 1,
|
|
217
|
+
k1: 1,
|
|
218
|
+
k0: 0}]
|
|
219
|
+
|
|
220
|
+
.. NOTE::
|
|
221
|
+
|
|
222
|
+
Although supported, passing converter and solver objects
|
|
223
|
+
instead of classes is discouraged because these objects are
|
|
224
|
+
stateful.
|
|
225
|
+
"""
|
|
226
|
+
assert n > 0
|
|
227
|
+
|
|
228
|
+
try:
|
|
229
|
+
len(F)
|
|
230
|
+
except AttributeError:
|
|
231
|
+
F = F.gens()
|
|
232
|
+
len(F)
|
|
233
|
+
|
|
234
|
+
P = next(iter(F)).parent()
|
|
235
|
+
K = P.base_ring()
|
|
236
|
+
|
|
237
|
+
if target_variables is None:
|
|
238
|
+
target_variables = PolynomialSequence(F).variables()
|
|
239
|
+
else:
|
|
240
|
+
target_variables = PolynomialSequence(target_variables).variables()
|
|
241
|
+
assert set(target_variables).issubset(set(P.gens()))
|
|
242
|
+
|
|
243
|
+
# instantiate the SAT solver
|
|
244
|
+
|
|
245
|
+
if solver is None:
|
|
246
|
+
from sage.sat.solvers import CryptoMiniSat as solver
|
|
247
|
+
|
|
248
|
+
if not isinstance(solver, SatSolver):
|
|
249
|
+
solver_kwds = {k[2:]: v for k, v in kwds.items()
|
|
250
|
+
if k.startswith("s_")}
|
|
251
|
+
|
|
252
|
+
solver = solver(**solver_kwds)
|
|
253
|
+
|
|
254
|
+
# instantiate the ANF to CNF converter
|
|
255
|
+
|
|
256
|
+
if converter is None:
|
|
257
|
+
from sage.sat.converters.polybori import CNFEncoder as converter
|
|
258
|
+
|
|
259
|
+
if not isinstance(converter, ANF2CNFConverter):
|
|
260
|
+
converter_kwds = {k[2:]: v for k, v in kwds.items()
|
|
261
|
+
if k.startswith("c_")}
|
|
262
|
+
|
|
263
|
+
converter = converter(solver, P, **converter_kwds)
|
|
264
|
+
|
|
265
|
+
phi = converter(F)
|
|
266
|
+
rho = {phi[i]: i for i in range(len(phi))}
|
|
267
|
+
|
|
268
|
+
S = []
|
|
269
|
+
|
|
270
|
+
while True:
|
|
271
|
+
s = solver()
|
|
272
|
+
|
|
273
|
+
if s:
|
|
274
|
+
S.append({x: K(s[rho[x]]) for x in target_variables})
|
|
275
|
+
|
|
276
|
+
if n is not None and len(S) == n:
|
|
277
|
+
break
|
|
278
|
+
|
|
279
|
+
exclude_solution = tuple(-rho[x] if s[rho[x]] else rho[x] for x in target_variables)
|
|
280
|
+
solver.add_clause(exclude_solution)
|
|
281
|
+
|
|
282
|
+
else:
|
|
283
|
+
try:
|
|
284
|
+
learnt = solver.learnt_clauses(unitary_only=True)
|
|
285
|
+
if learnt:
|
|
286
|
+
S.append({phi[abs(i) - 1]: K(i < 0) for i in learnt})
|
|
287
|
+
else:
|
|
288
|
+
S.append(s)
|
|
289
|
+
break
|
|
290
|
+
except (AttributeError, NotImplementedError):
|
|
291
|
+
# solver does not support recovering learnt clauses
|
|
292
|
+
S.append(s)
|
|
293
|
+
break
|
|
294
|
+
|
|
295
|
+
if len(S) == 1:
|
|
296
|
+
if S[0] is False:
|
|
297
|
+
return False
|
|
298
|
+
if S[0] is None:
|
|
299
|
+
return None
|
|
300
|
+
elif S[-1] is False:
|
|
301
|
+
return S[0:-1]
|
|
302
|
+
return S
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=False, **kwds):
|
|
306
|
+
"""
|
|
307
|
+
Learn new polynomials by running SAT-solver ``solver`` on
|
|
308
|
+
SAT-instance produced by ``converter`` from ``F``.
|
|
309
|
+
|
|
310
|
+
INPUT:
|
|
311
|
+
|
|
312
|
+
- ``F`` -- a sequence of Boolean polynomials
|
|
313
|
+
|
|
314
|
+
- ``converter`` -- an ANF to CNF converter class or object. If ``converter`` is ``None`` then
|
|
315
|
+
:class:`sage.sat.converters.polybori.CNFEncoder` is used to construct a new
|
|
316
|
+
converter. (default: ``None``)
|
|
317
|
+
|
|
318
|
+
- ``solver`` -- a SAT-solver class or object. If ``solver`` is ``None`` then
|
|
319
|
+
:class:`sage.sat.solvers.cryptominisat.CryptoMiniSat` is used to construct a new converter.
|
|
320
|
+
(default: ``None``)
|
|
321
|
+
|
|
322
|
+
- ``max_learnt_length`` -- only clauses of length <= ``max_length_learnt`` are considered and
|
|
323
|
+
converted to polynomials. (default: ``3``)
|
|
324
|
+
|
|
325
|
+
- ``interreduction`` -- inter-reduce the resulting polynomials (default: ``False``)
|
|
326
|
+
|
|
327
|
+
.. NOTE::
|
|
328
|
+
|
|
329
|
+
More parameters can be passed to the converter and the solver by prefixing them with ``c_`` and
|
|
330
|
+
``s_`` respectively. For example, to increase CryptoMiniSat's verbosity level, pass
|
|
331
|
+
``s_verbosity=1``.
|
|
332
|
+
|
|
333
|
+
OUTPUT: a sequence of Boolean polynomials
|
|
334
|
+
|
|
335
|
+
EXAMPLES::
|
|
336
|
+
|
|
337
|
+
sage: from sage.sat.boolean_polynomials import learn as learn_sat
|
|
338
|
+
|
|
339
|
+
We construct a simple system and solve it::
|
|
340
|
+
|
|
341
|
+
sage: set_random_seed(2300)
|
|
342
|
+
sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True)
|
|
343
|
+
sage: F,s = sr.polynomial_system()
|
|
344
|
+
sage: H = learn_sat(F)
|
|
345
|
+
sage: H[-1]
|
|
346
|
+
k033 + 1
|
|
347
|
+
"""
|
|
348
|
+
try:
|
|
349
|
+
len(F)
|
|
350
|
+
except AttributeError:
|
|
351
|
+
F = F.gens()
|
|
352
|
+
len(F)
|
|
353
|
+
|
|
354
|
+
P = next(iter(F)).parent()
|
|
355
|
+
K = P.base_ring()
|
|
356
|
+
|
|
357
|
+
# instantiate the SAT solver
|
|
358
|
+
|
|
359
|
+
if solver is None:
|
|
360
|
+
from sage.sat.solvers.cryptominisat import CryptoMiniSat as solver
|
|
361
|
+
|
|
362
|
+
solver_kwds = {k[2:]: v for k, v in kwds.items()
|
|
363
|
+
if k.startswith("s_")}
|
|
364
|
+
|
|
365
|
+
solver = solver(**solver_kwds)
|
|
366
|
+
|
|
367
|
+
# instantiate the ANF to CNF converter
|
|
368
|
+
|
|
369
|
+
if converter is None:
|
|
370
|
+
from sage.sat.converters.polybori import CNFEncoder as converter
|
|
371
|
+
|
|
372
|
+
converter_kwds = {k[2:]: v for k, v in kwds.items()
|
|
373
|
+
if k.startswith("c_")}
|
|
374
|
+
|
|
375
|
+
converter = converter(solver, P, **converter_kwds)
|
|
376
|
+
|
|
377
|
+
phi = converter(F)
|
|
378
|
+
rho = {phi[i]: i for i in range(len(phi))}
|
|
379
|
+
|
|
380
|
+
s = solver()
|
|
381
|
+
|
|
382
|
+
if s:
|
|
383
|
+
learnt = [x + K(s[rho[x]]) for x in P.gens()]
|
|
384
|
+
else:
|
|
385
|
+
learnt = []
|
|
386
|
+
try:
|
|
387
|
+
lc = solver.learnt_clauses()
|
|
388
|
+
except (AttributeError, NotImplementedError):
|
|
389
|
+
# solver does not support recovering learnt clauses
|
|
390
|
+
lc = []
|
|
391
|
+
for c in lc:
|
|
392
|
+
if len(c) <= max_learnt_length:
|
|
393
|
+
try:
|
|
394
|
+
learnt.append(converter.to_polynomial(c))
|
|
395
|
+
except (ValueError, NotImplementedError, AttributeError):
|
|
396
|
+
# the solver might have learnt clauses that contain CNF
|
|
397
|
+
# variables which have no correspondence to variables in our
|
|
398
|
+
# polynomial ring (XOR chaining variables for example)
|
|
399
|
+
pass
|
|
400
|
+
|
|
401
|
+
learnt = PolynomialSequence(P, learnt)
|
|
402
|
+
|
|
403
|
+
if interreduction:
|
|
404
|
+
learnt = learnt.ideal().interreduced_basis()
|
|
405
|
+
return learnt
|