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.
Files changed (401) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
  3. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  4. passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
  5. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  6. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  7. passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
  8. passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
  9. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  10. sage/algebras/all.py +24 -0
  11. sage/algebras/all__sagemath_combinat.py +35 -0
  12. sage/algebras/askey_wilson.py +935 -0
  13. sage/algebras/associated_graded.py +345 -0
  14. sage/algebras/cellular_basis.py +350 -0
  15. sage/algebras/cluster_algebra.py +2766 -0
  16. sage/algebras/down_up_algebra.py +860 -0
  17. sage/algebras/free_algebra.py +1698 -0
  18. sage/algebras/free_algebra_element.py +345 -0
  19. sage/algebras/free_algebra_quotient.py +405 -0
  20. sage/algebras/free_algebra_quotient_element.py +295 -0
  21. sage/algebras/free_zinbiel_algebra.py +885 -0
  22. sage/algebras/hall_algebra.py +783 -0
  23. sage/algebras/hecke_algebras/all.py +4 -0
  24. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  25. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  28. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  29. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  30. sage/algebras/jordan_algebra.py +1773 -0
  31. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  32. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  33. sage/algebras/lie_conformal_algebras/all.py +18 -0
  34. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  35. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  36. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  37. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  38. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  39. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  40. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  41. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  45. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  46. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  47. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  48. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  49. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  50. sage/algebras/nil_coxeter_algebra.py +191 -0
  51. sage/algebras/q_commuting_polynomials.py +673 -0
  52. sage/algebras/q_system.py +608 -0
  53. sage/algebras/quantum_clifford.py +959 -0
  54. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  55. sage/algebras/quantum_groups/all.py +9 -0
  56. sage/algebras/quantum_groups/fock_space.py +2219 -0
  57. sage/algebras/quantum_groups/q_numbers.py +207 -0
  58. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  59. sage/algebras/quantum_groups/representations.py +591 -0
  60. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  61. sage/algebras/quantum_oscillator.py +623 -0
  62. sage/algebras/quaternion_algebra.py +20 -0
  63. sage/algebras/quaternion_algebra_element.py +55 -0
  64. sage/algebras/rational_cherednik_algebra.py +525 -0
  65. sage/algebras/schur_algebra.py +670 -0
  66. sage/algebras/shuffle_algebra.py +1011 -0
  67. sage/algebras/splitting_algebra.py +779 -0
  68. sage/algebras/tensor_algebra.py +709 -0
  69. sage/algebras/yangian.py +1082 -0
  70. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  71. sage/all__sagemath_combinat.py +44 -0
  72. sage/combinat/SJT.py +255 -0
  73. sage/combinat/affine_permutation.py +2405 -0
  74. sage/combinat/algebraic_combinatorics.py +55 -0
  75. sage/combinat/all.py +53 -0
  76. sage/combinat/all__sagemath_combinat.py +195 -0
  77. sage/combinat/alternating_sign_matrix.py +2063 -0
  78. sage/combinat/baxter_permutations.py +346 -0
  79. sage/combinat/bijectionist.py +3220 -0
  80. sage/combinat/binary_recurrence_sequences.py +1180 -0
  81. sage/combinat/blob_algebra.py +685 -0
  82. sage/combinat/catalog_partitions.py +27 -0
  83. sage/combinat/chas/all.py +23 -0
  84. sage/combinat/chas/fsym.py +1180 -0
  85. sage/combinat/chas/wqsym.py +2601 -0
  86. sage/combinat/cluster_complex.py +326 -0
  87. sage/combinat/colored_permutations.py +2039 -0
  88. sage/combinat/colored_permutations_representations.py +964 -0
  89. sage/combinat/composition_signed.py +142 -0
  90. sage/combinat/composition_tableau.py +855 -0
  91. sage/combinat/constellation.py +1729 -0
  92. sage/combinat/core.py +751 -0
  93. sage/combinat/counting.py +12 -0
  94. sage/combinat/crystals/affine.py +742 -0
  95. sage/combinat/crystals/affine_factorization.py +518 -0
  96. sage/combinat/crystals/affinization.py +331 -0
  97. sage/combinat/crystals/alcove_path.py +2013 -0
  98. sage/combinat/crystals/all.py +22 -0
  99. sage/combinat/crystals/bkk_crystals.py +141 -0
  100. sage/combinat/crystals/catalog.py +115 -0
  101. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  102. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  103. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  104. sage/combinat/crystals/crystals.py +257 -0
  105. sage/combinat/crystals/direct_sum.py +260 -0
  106. sage/combinat/crystals/elementary_crystals.py +1251 -0
  107. sage/combinat/crystals/fast_crystals.py +441 -0
  108. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  109. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  110. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  111. sage/combinat/crystals/induced_structure.py +695 -0
  112. sage/combinat/crystals/infinity_crystals.py +730 -0
  113. sage/combinat/crystals/kac_modules.py +863 -0
  114. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  115. sage/combinat/crystals/kyoto_path_model.py +497 -0
  116. sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
  117. sage/combinat/crystals/letters.pxd +79 -0
  118. sage/combinat/crystals/letters.pyx +3056 -0
  119. sage/combinat/crystals/littelmann_path.py +1518 -0
  120. sage/combinat/crystals/monomial_crystals.py +1262 -0
  121. sage/combinat/crystals/multisegments.py +462 -0
  122. sage/combinat/crystals/mv_polytopes.py +467 -0
  123. sage/combinat/crystals/pbw_crystal.py +511 -0
  124. sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
  125. sage/combinat/crystals/pbw_datum.pxd +4 -0
  126. sage/combinat/crystals/pbw_datum.pyx +487 -0
  127. sage/combinat/crystals/polyhedral_realization.py +372 -0
  128. sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
  129. sage/combinat/crystals/spins.pxd +21 -0
  130. sage/combinat/crystals/spins.pyx +756 -0
  131. sage/combinat/crystals/star_crystal.py +290 -0
  132. sage/combinat/crystals/subcrystal.py +464 -0
  133. sage/combinat/crystals/tensor_product.py +1177 -0
  134. sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
  135. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  136. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  137. sage/combinat/crystals/virtual_crystal.py +420 -0
  138. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  139. sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
  140. sage/combinat/debruijn_sequence.pyx +355 -0
  141. sage/combinat/decorated_permutation.py +270 -0
  142. sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
  143. sage/combinat/degree_sequences.pyx +588 -0
  144. sage/combinat/derangements.py +527 -0
  145. sage/combinat/descent_algebra.py +1008 -0
  146. sage/combinat/diagram.py +1551 -0
  147. sage/combinat/diagram_algebras.py +5886 -0
  148. sage/combinat/dyck_word.py +4349 -0
  149. sage/combinat/e_one_star.py +1623 -0
  150. sage/combinat/enumerated_sets.py +123 -0
  151. sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
  152. sage/combinat/expnums.pyx +148 -0
  153. sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
  154. sage/combinat/fast_vector_partitions.pyx +346 -0
  155. sage/combinat/fqsym.py +1977 -0
  156. sage/combinat/free_dendriform_algebra.py +954 -0
  157. sage/combinat/free_prelie_algebra.py +1141 -0
  158. sage/combinat/fully_commutative_elements.py +1077 -0
  159. sage/combinat/fully_packed_loop.py +1523 -0
  160. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  161. sage/combinat/gray_codes.py +311 -0
  162. sage/combinat/grossman_larson_algebras.py +667 -0
  163. sage/combinat/growth.py +4352 -0
  164. sage/combinat/hall_polynomial.py +188 -0
  165. sage/combinat/hillman_grassl.py +866 -0
  166. sage/combinat/integer_matrices.py +329 -0
  167. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  168. sage/combinat/k_tableau.py +4564 -0
  169. sage/combinat/kazhdan_lusztig.py +215 -0
  170. sage/combinat/key_polynomial.py +885 -0
  171. sage/combinat/knutson_tao_puzzles.py +2286 -0
  172. sage/combinat/lr_tableau.py +311 -0
  173. sage/combinat/matrices/all.py +24 -0
  174. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  175. sage/combinat/matrices/latin.py +2912 -0
  176. sage/combinat/misc.py +401 -0
  177. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  178. sage/combinat/ncsf_qsym/all.py +21 -0
  179. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  180. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  181. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  182. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  183. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  184. sage/combinat/ncsym/all.py +21 -0
  185. sage/combinat/ncsym/bases.py +855 -0
  186. sage/combinat/ncsym/dual.py +593 -0
  187. sage/combinat/ncsym/ncsym.py +2076 -0
  188. sage/combinat/necklace.py +551 -0
  189. sage/combinat/non_decreasing_parking_function.py +634 -0
  190. sage/combinat/nu_dyck_word.py +1474 -0
  191. sage/combinat/output.py +861 -0
  192. sage/combinat/parallelogram_polyomino.py +4326 -0
  193. sage/combinat/parking_functions.py +1602 -0
  194. sage/combinat/partition_algebra.py +1998 -0
  195. sage/combinat/partition_kleshchev.py +1982 -0
  196. sage/combinat/partition_shifting_algebras.py +584 -0
  197. sage/combinat/partition_tuple.py +3114 -0
  198. sage/combinat/path_tableaux/all.py +13 -0
  199. sage/combinat/path_tableaux/catalog.py +29 -0
  200. sage/combinat/path_tableaux/dyck_path.py +380 -0
  201. sage/combinat/path_tableaux/frieze.py +476 -0
  202. sage/combinat/path_tableaux/path_tableau.py +728 -0
  203. sage/combinat/path_tableaux/semistandard.py +510 -0
  204. sage/combinat/perfect_matching.py +779 -0
  205. sage/combinat/plane_partition.py +3300 -0
  206. sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
  207. sage/combinat/q_bernoulli.pyx +128 -0
  208. sage/combinat/quickref.py +81 -0
  209. sage/combinat/recognizable_series.py +2051 -0
  210. sage/combinat/regular_sequence.py +4316 -0
  211. sage/combinat/regular_sequence_bounded.py +543 -0
  212. sage/combinat/restricted_growth.py +81 -0
  213. sage/combinat/ribbon.py +20 -0
  214. sage/combinat/ribbon_shaped_tableau.py +489 -0
  215. sage/combinat/ribbon_tableau.py +1180 -0
  216. sage/combinat/rigged_configurations/all.py +46 -0
  217. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  218. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  219. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  222. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  223. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  224. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  225. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  226. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  227. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  228. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  229. sage/combinat/rigged_configurations/bijection.py +143 -0
  230. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  231. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  232. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  233. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  234. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  235. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  236. sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  238. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  240. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  241. sage/combinat/rsk.py +3438 -0
  242. sage/combinat/schubert_polynomial.py +508 -0
  243. sage/combinat/set_partition.py +3318 -0
  244. sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
  245. sage/combinat/set_partition_iterator.pyx +136 -0
  246. sage/combinat/set_partition_ordered.py +1590 -0
  247. sage/combinat/sf/abreu_nigro.py +346 -0
  248. sage/combinat/sf/all.py +52 -0
  249. sage/combinat/sf/character.py +576 -0
  250. sage/combinat/sf/classical.py +319 -0
  251. sage/combinat/sf/dual.py +996 -0
  252. sage/combinat/sf/elementary.py +549 -0
  253. sage/combinat/sf/hall_littlewood.py +1028 -0
  254. sage/combinat/sf/hecke.py +336 -0
  255. sage/combinat/sf/homogeneous.py +464 -0
  256. sage/combinat/sf/jack.py +1428 -0
  257. sage/combinat/sf/k_dual.py +1458 -0
  258. sage/combinat/sf/kfpoly.py +447 -0
  259. sage/combinat/sf/llt.py +789 -0
  260. sage/combinat/sf/macdonald.py +2019 -0
  261. sage/combinat/sf/monomial.py +525 -0
  262. sage/combinat/sf/multiplicative.py +113 -0
  263. sage/combinat/sf/new_kschur.py +1786 -0
  264. sage/combinat/sf/ns_macdonald.py +964 -0
  265. sage/combinat/sf/orthogonal.py +246 -0
  266. sage/combinat/sf/orthotriang.py +355 -0
  267. sage/combinat/sf/powersum.py +963 -0
  268. sage/combinat/sf/schur.py +880 -0
  269. sage/combinat/sf/sf.py +1653 -0
  270. sage/combinat/sf/sfa.py +7053 -0
  271. sage/combinat/sf/symplectic.py +253 -0
  272. sage/combinat/sf/witt.py +721 -0
  273. sage/combinat/shifted_primed_tableau.py +2735 -0
  274. sage/combinat/shuffle.py +830 -0
  275. sage/combinat/sidon_sets.py +146 -0
  276. sage/combinat/similarity_class_type.py +1721 -0
  277. sage/combinat/sine_gordon.py +618 -0
  278. sage/combinat/six_vertex_model.py +784 -0
  279. sage/combinat/skew_partition.py +2053 -0
  280. sage/combinat/skew_tableau.py +2989 -0
  281. sage/combinat/sloane_functions.py +8935 -0
  282. sage/combinat/specht_module.py +1403 -0
  283. sage/combinat/species/all.py +48 -0
  284. sage/combinat/species/characteristic_species.py +321 -0
  285. sage/combinat/species/composition_species.py +273 -0
  286. sage/combinat/species/cycle_species.py +284 -0
  287. sage/combinat/species/empty_species.py +155 -0
  288. sage/combinat/species/functorial_composition_species.py +148 -0
  289. sage/combinat/species/generating_series.py +673 -0
  290. sage/combinat/species/library.py +148 -0
  291. sage/combinat/species/linear_order_species.py +169 -0
  292. sage/combinat/species/misc.py +83 -0
  293. sage/combinat/species/partition_species.py +290 -0
  294. sage/combinat/species/permutation_species.py +268 -0
  295. sage/combinat/species/product_species.py +423 -0
  296. sage/combinat/species/recursive_species.py +476 -0
  297. sage/combinat/species/set_species.py +192 -0
  298. sage/combinat/species/species.py +820 -0
  299. sage/combinat/species/structure.py +539 -0
  300. sage/combinat/species/subset_species.py +243 -0
  301. sage/combinat/species/sum_species.py +225 -0
  302. sage/combinat/subword.py +564 -0
  303. sage/combinat/subword_complex.py +2122 -0
  304. sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
  305. sage/combinat/subword_complex_c.pyx +119 -0
  306. sage/combinat/super_tableau.py +821 -0
  307. sage/combinat/superpartition.py +1154 -0
  308. sage/combinat/symmetric_group_algebra.py +3774 -0
  309. sage/combinat/symmetric_group_representations.py +1830 -0
  310. sage/combinat/t_sequences.py +877 -0
  311. sage/combinat/tableau.py +9506 -0
  312. sage/combinat/tableau_residues.py +860 -0
  313. sage/combinat/tableau_tuple.py +5353 -0
  314. sage/combinat/tiling.py +2432 -0
  315. sage/combinat/triangles_FHM.py +777 -0
  316. sage/combinat/tutorial.py +1857 -0
  317. sage/combinat/vector_partition.py +337 -0
  318. sage/combinat/words/abstract_word.py +1722 -0
  319. sage/combinat/words/all.py +59 -0
  320. sage/combinat/words/alphabet.py +268 -0
  321. sage/combinat/words/finite_word.py +7201 -0
  322. sage/combinat/words/infinite_word.py +113 -0
  323. sage/combinat/words/lyndon_word.py +652 -0
  324. sage/combinat/words/morphic.py +351 -0
  325. sage/combinat/words/morphism.py +3878 -0
  326. sage/combinat/words/paths.py +2932 -0
  327. sage/combinat/words/shuffle_product.py +278 -0
  328. sage/combinat/words/suffix_trees.py +1873 -0
  329. sage/combinat/words/word.py +769 -0
  330. sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
  331. sage/combinat/words/word_char.pyx +847 -0
  332. sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
  333. sage/combinat/words/word_datatypes.pxd +4 -0
  334. sage/combinat/words/word_datatypes.pyx +1067 -0
  335. sage/combinat/words/word_generators.py +2026 -0
  336. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  337. sage/combinat/words/word_options.py +99 -0
  338. sage/combinat/words/words.py +2396 -0
  339. sage/data_structures/all__sagemath_combinat.py +1 -0
  340. sage/databases/all__sagemath_combinat.py +13 -0
  341. sage/databases/findstat.py +4897 -0
  342. sage/databases/oeis.py +2058 -0
  343. sage/databases/sloane.py +393 -0
  344. sage/dynamics/all__sagemath_combinat.py +14 -0
  345. sage/dynamics/cellular_automata/all.py +7 -0
  346. sage/dynamics/cellular_automata/catalog.py +34 -0
  347. sage/dynamics/cellular_automata/elementary.py +612 -0
  348. sage/dynamics/cellular_automata/glca.py +477 -0
  349. sage/dynamics/cellular_automata/solitons.py +1463 -0
  350. sage/dynamics/finite_dynamical_system.py +1249 -0
  351. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  352. sage/games/all.py +7 -0
  353. sage/games/hexad.py +704 -0
  354. sage/games/quantumino.py +591 -0
  355. sage/games/sudoku.py +889 -0
  356. sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
  357. sage/games/sudoku_backtrack.pyx +189 -0
  358. sage/groups/all__sagemath_combinat.py +1 -0
  359. sage/groups/indexed_free_group.py +489 -0
  360. sage/libs/all__sagemath_combinat.py +6 -0
  361. sage/libs/lrcalc/__init__.py +1 -0
  362. sage/libs/lrcalc/lrcalc.py +525 -0
  363. sage/libs/symmetrica/__init__.py +7 -0
  364. sage/libs/symmetrica/all.py +101 -0
  365. sage/libs/symmetrica/kostka.pxi +168 -0
  366. sage/libs/symmetrica/part.pxi +193 -0
  367. sage/libs/symmetrica/plet.pxi +42 -0
  368. sage/libs/symmetrica/sab.pxi +196 -0
  369. sage/libs/symmetrica/sb.pxi +332 -0
  370. sage/libs/symmetrica/sc.pxi +192 -0
  371. sage/libs/symmetrica/schur.pxi +956 -0
  372. sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
  373. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  374. sage/libs/symmetrica/symmetrica.pyx +39 -0
  375. sage/monoids/all.py +13 -0
  376. sage/monoids/automatic_semigroup.py +1054 -0
  377. sage/monoids/free_abelian_monoid.py +315 -0
  378. sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
  379. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  380. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  381. sage/monoids/free_monoid.py +335 -0
  382. sage/monoids/free_monoid_element.py +431 -0
  383. sage/monoids/hecke_monoid.py +65 -0
  384. sage/monoids/string_monoid.py +817 -0
  385. sage/monoids/string_monoid_element.py +547 -0
  386. sage/monoids/string_ops.py +143 -0
  387. sage/monoids/trace_monoid.py +972 -0
  388. sage/rings/all__sagemath_combinat.py +2 -0
  389. sage/sat/all.py +4 -0
  390. sage/sat/boolean_polynomials.py +405 -0
  391. sage/sat/converters/__init__.py +6 -0
  392. sage/sat/converters/anf2cnf.py +14 -0
  393. sage/sat/converters/polybori.py +611 -0
  394. sage/sat/solvers/__init__.py +5 -0
  395. sage/sat/solvers/cryptominisat.py +287 -0
  396. sage/sat/solvers/dimacs.py +783 -0
  397. sage/sat/solvers/picosat.py +228 -0
  398. sage/sat/solvers/sat_lp.py +156 -0
  399. sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
  400. sage/sat/solvers/satsolver.pxd +3 -0
  401. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,1238 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.groups
3
+ r"""
4
+ Integer vectors modulo the action of a permutation group
5
+
6
+ AUTHORS:
7
+
8
+ * Nicolas Borie (2010-2012) - original module
9
+ * Jukka Kohonen (2023) - fast cardinality method, :issue:`36787`, :issue:`36681`
10
+ """
11
+ # ****************************************************************************
12
+ # Copyright (C) 2010-12 Nicolas Borie <nicolas.borie at math dot u-psud.fr>
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ #
16
+ # The full text of the GPL is available at:
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ from sage.structure.unique_representation import UniqueRepresentation
21
+ from sage.rings.semirings.non_negative_integer_semiring import NN
22
+
23
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
24
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
25
+
26
+ from sage.structure.list_clone import ClonableIntArray
27
+ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest
28
+
29
+ from sage.combinat.enumeration_mod_permgroup import is_canonical, orbit, canonical_children, canonical_representative_of_orbit_of
30
+
31
+ from sage.combinat.integer_vector import IntegerVectors
32
+
33
+ from sage.rings.power_series_ring import PowerSeriesRing
34
+ from sage.rings.rational_field import QQ
35
+ from sage.rings.integer import Integer
36
+ from sage.misc.misc_c import prod
37
+ from sage.arith.misc import binomial
38
+
39
+
40
+ class IntegerVectorsModPermutationGroup(UniqueRepresentation):
41
+ r"""
42
+ Return an enumerated set containing integer vectors which are
43
+ maximal in their orbit under the action of the permutation group
44
+ ``G`` for the lexicographic order.
45
+
46
+ In Sage, a permutation group `G` is viewed as a subgroup of the
47
+ symmetric group `S_n` of degree `n` and `n` is said to be the degree
48
+ of `G`. Any integer vector `v` is said to be canonical if it
49
+ is maximal in its orbit under the action of `G`. `v` is
50
+ canonical if and only if
51
+
52
+ .. MATH::
53
+
54
+ v = \max_{\text{lex order}} \{g \cdot v | g \in G \}
55
+
56
+ The action of `G` is on position. This means for example that the
57
+ simple transposition `s_1 = (1, 2)` swaps the first and the second
58
+ entries of any integer vector `v = [a_1, a_2, a_3, \dots , a_n]`
59
+
60
+ .. MATH::
61
+
62
+ s_1 \cdot v = [a_2, a_1, a_3, \dots , a_n]
63
+
64
+ This function returns a parent which contains, from each orbit
65
+ orbit under the action of the permutation group `G`, a single
66
+ canonical vector. The canonical vector is the one that is maximal
67
+ within the orbit according to lexicographic order.
68
+
69
+ INPUT:
70
+
71
+ - ``G`` -- a permutation group
72
+ - ``sum`` -- (default: ``None``) - a nonnegative integer
73
+ - ``max_part`` -- (default: ``None``) - a nonnegative integer setting the
74
+ maximum value for every element
75
+ - ``sgs`` -- (default: ``None``) - a strong generating system of the
76
+ group `G`. If you do not provide it, it will be calculated at the
77
+ creation of the parent
78
+
79
+ OUTPUT:
80
+
81
+ - If ``sum`` and ``max_part`` are None, it returns the infinite
82
+ enumerated set of all integer vectors (lists of integers) maximal
83
+ in their orbit for the lexicographic order. Exceptionally, if
84
+ the domain of ``G`` is empty, the result is a finite enumerated
85
+ set that contains one element, namely the empty vector.
86
+
87
+ - If ``sum`` is an integer, it returns a finite enumerated set
88
+ containing all integer vectors maximal in their orbit for the
89
+ lexicographic order and whose entries sum to ``sum``.
90
+
91
+ EXAMPLES:
92
+
93
+ Here is the set enumerating integer vectors modulo the action of the cyclic
94
+ group of `3` elements::
95
+
96
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]))
97
+ sage: I.category()
98
+ Category of infinite enumerated quotients of sets
99
+ sage: I.cardinality()
100
+ +Infinity
101
+ sage: I.list()
102
+ Traceback (most recent call last):
103
+ ...
104
+ NotImplementedError: cannot list an infinite set
105
+ sage: p = iter(I)
106
+ sage: for i in range(10): next(p)
107
+ [0, 0, 0]
108
+ [1, 0, 0]
109
+ [2, 0, 0]
110
+ [1, 1, 0]
111
+ [3, 0, 0]
112
+ [2, 1, 0]
113
+ [2, 0, 1]
114
+ [1, 1, 1]
115
+ [4, 0, 0]
116
+ [3, 1, 0]
117
+
118
+ The method
119
+ :meth:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup_All.is_canonical`
120
+ tests if an integer vector is maximal in its orbit. This method
121
+ is also used in the containment test::
122
+
123
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
124
+ sage: I.is_canonical([5,2,0,4])
125
+ True
126
+ sage: I.is_canonical([5,0,6,4])
127
+ False
128
+ sage: I.is_canonical([1,1,1,1])
129
+ True
130
+ sage: [2,3,1,0] in I
131
+ False
132
+ sage: [5,0,5,0] in I
133
+ True
134
+ sage: 'Bla' in I
135
+ False
136
+ sage: I.is_canonical('bla')
137
+ Traceback (most recent call last):
138
+ ...
139
+ AssertionError: bla should be a list or an integer vector
140
+
141
+ If you give a value to the extra argument ``sum``, the set returned
142
+ will be a finite set containing only canonical vectors whose entries
143
+ sum to ``sum``.::
144
+
145
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), sum=6)
146
+ sage: I.cardinality()
147
+ 10
148
+ sage: I.list()
149
+ [[6, 0, 0], [5, 1, 0], [5, 0, 1], [4, 2, 0], [4, 1, 1],
150
+ [4, 0, 2], [3, 3, 0], [3, 2, 1], [3, 1, 2], [2, 2, 2]]
151
+ sage: I.category()
152
+ Join of Category of finite enumerated sets
153
+ and Category of subquotients of finite sets
154
+ and Category of quotients of sets
155
+
156
+ To get the orbit of any integer vector `v` under the action of the group,
157
+ use the method :meth:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup_All.orbit`;
158
+ we convert the returned set of vectors into a list in increasing lexicographic order,
159
+ to get a reproducible test::
160
+
161
+ sage: sorted(I.orbit([6,0,0]))
162
+ [[0, 0, 6], [0, 6, 0], [6, 0, 0]]
163
+ sage: sorted(I.orbit([5,1,0]))
164
+ [[0, 5, 1], [1, 0, 5], [5, 1, 0]]
165
+ sage: I.orbit([2,2,2])
166
+ {[2, 2, 2]}
167
+
168
+ Even without constraints, for an empty domain the result is
169
+ a singleton set::
170
+
171
+ sage: G = PermutationGroup([], domain=[])
172
+ sage: sgs = tuple(tuple(s) for s in G.strong_generating_system())
173
+ sage: list(IntegerVectorsModPermutationGroup(G, sgs=sgs))
174
+ [[]]
175
+
176
+
177
+ .. WARNING::
178
+
179
+ Because of :issue:`36527`, permutation groups that have
180
+ different domains but similar generators can be erroneously
181
+ treated as the same group. This will silently produce
182
+ erroneous results. To avoid this issue, compute a strong
183
+ generating system for the group as::
184
+
185
+ sgs = tuple(tuple(s) for s in G.strong_generating_system())
186
+
187
+ and provide it as the optional ``sgs`` argument to the
188
+ constructor.
189
+
190
+ TESTS:
191
+
192
+ Let us check that canonical integer vectors of the symmetric group
193
+ are just nonincreasing lists of integers::
194
+
195
+ sage: I = IntegerVectorsModPermutationGroup(SymmetricGroup(5)) # long time
196
+ sage: p = iter(I) # long time
197
+ sage: for i in range(100): # long time
198
+ ....: v = list(next(p))
199
+ ....: assert sorted(v, reverse=True) == v
200
+
201
+ We now check that there are as many canonical vectors under the
202
+ symmetric group `S_n` whose entries sum to `d` as there are
203
+ partitions of `d` of at most `n` parts::
204
+
205
+ sage: I = IntegerVectorsModPermutationGroup(SymmetricGroup(5)) # long time
206
+ sage: for i in range(10): # long time
207
+ ....: d1 = I.subset(i).cardinality()
208
+ ....: d2 = Partitions(i, max_length=5).cardinality()
209
+ ....: print(d1)
210
+ ....: assert d1 == d2
211
+ 1
212
+ 1
213
+ 2
214
+ 3
215
+ 5
216
+ 7
217
+ 10
218
+ 13
219
+ 18
220
+ 23
221
+
222
+ Another corner case is trivial groups. For the trivial group ``G``
223
+ acting on a list of length `n`, all integer vectors of length `n`
224
+ are canonical::
225
+
226
+ sage: # long time
227
+ sage: G = PermutationGroup([[(6,)]])
228
+ sage: G.cardinality()
229
+ 1
230
+ sage: sgs = tuple(tuple(s) for s in G.strong_generating_system())
231
+ sage: I = IntegerVectorsModPermutationGroup(G, sgs=sgs)
232
+ sage: for i in range(10):
233
+ ....: d1 = I.subset(i).cardinality()
234
+ ....: d2 = IntegerVectors(i,6).cardinality()
235
+ ....: print(d1)
236
+ ....: assert d1 == d2
237
+ 1
238
+ 6
239
+ 21
240
+ 56
241
+ 126
242
+ 252
243
+ 462
244
+ 792
245
+ 1287
246
+ 2002
247
+ """
248
+ @staticmethod
249
+ def __classcall__(cls, G, sum=None, max_part=None, sgs=None):
250
+ r"""
251
+ TESTS::
252
+
253
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]))
254
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), None)
255
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), 2)
256
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), -2)
257
+ Traceback (most recent call last):
258
+ ...
259
+ ValueError: Value -2 in not in Non negative integer semiring.
260
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), 8, max_part=5)
261
+ """
262
+ if sum is None and max_part is None:
263
+ # No constraints.
264
+ if G.domain():
265
+ # Nonempty domain, infinite set.
266
+ return IntegerVectorsModPermutationGroup_All(G, sgs=sgs)
267
+ else:
268
+ # Empty domain, singleton set.
269
+ return IntegerVectorsModPermutationGroup_with_constraints(
270
+ G, 0, max_part=-1, sgs=sgs)
271
+ else:
272
+ # Some constraints, either sum or max_part or both.
273
+ if sum is not None:
274
+ assert sum == NN(sum)
275
+ if max_part is not None:
276
+ assert max_part == NN(max_part)
277
+ return IntegerVectorsModPermutationGroup_with_constraints(
278
+ G, sum, max_part, sgs=sgs)
279
+
280
+
281
+ class IntegerVectorsModPermutationGroup_All(UniqueRepresentation, RecursivelyEnumeratedSet_forest):
282
+ r"""
283
+ A class for integer vectors enumerated up to the action of a
284
+ permutation group.
285
+
286
+ A Sage permutation group is viewed as a subgroup of the symmetric
287
+ group `S_n` for a certain `n`. This group has a natural action by
288
+ position on vectors of length `n`. This class implements a set
289
+ which keeps a single vector for each orbit. We say that a vector
290
+ is canonical if it is the maximum in its orbit under the action of
291
+ the permutation group for the lexicographic order.
292
+
293
+ EXAMPLES::
294
+
295
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]])); I
296
+ Integer vectors of length 4 enumerated up to the action of
297
+ Permutation Group with generators [(1,2,3,4)]
298
+ sage: I.cardinality()
299
+ +Infinity
300
+ sage: TestSuite(I).run()
301
+ sage: it = iter(I)
302
+ sage: [next(it), next(it), next(it), next(it), next(it)]
303
+ [[0, 0, 0, 0],
304
+ [1, 0, 0, 0],
305
+ [2, 0, 0, 0],
306
+ [1, 1, 0, 0],
307
+ [1, 0, 1, 0]]
308
+ sage: x = next(it); x
309
+ [3, 0, 0, 0]
310
+ sage: I.first()
311
+ [0, 0, 0, 0]
312
+
313
+ TESTS::
314
+
315
+ sage: TestSuite(I).run()
316
+ """
317
+
318
+ def __init__(self, G, sgs=None):
319
+ """
320
+ TESTS::
321
+
322
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
323
+ sage: I
324
+ Integer vectors of length 4 enumerated up to the action of
325
+ Permutation Group with generators [(1,2,3,4)]
326
+ sage: I.category()
327
+ Category of infinite enumerated quotients of sets
328
+ sage: TestSuite(I).run()
329
+ """
330
+ RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=InfiniteEnumeratedSets().Quotients())
331
+ self._permgroup = G
332
+ self.n = G.degree()
333
+
334
+ # self.sgs: strong_generating_system
335
+ if sgs is None:
336
+ self._sgs = G.strong_generating_system()
337
+ else:
338
+ self._sgs = [list(x) for x in list(sgs)]
339
+
340
+ def _repr_(self):
341
+ """
342
+ TESTS::
343
+
344
+ sage: IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]))
345
+ Integer vectors of length 3 enumerated up to the action of Permutation Group with generators [(1,2,3)]
346
+ """
347
+ return "Integer vectors of length %s enumerated up to the action of %r" % (self.n, self._permgroup)
348
+
349
+ def ambient(self):
350
+ r"""
351
+ Return the ambient space from which ``self`` is a quotient.
352
+
353
+ EXAMPLES::
354
+
355
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
356
+ sage: S.ambient()
357
+ Integer vectors of length 4
358
+ """
359
+ return IntegerVectors(length=self.n)
360
+
361
+ def lift(self, elt):
362
+ r"""
363
+ Lift the element ``elt`` inside the ambient space from which ``self`` is a quotient.
364
+
365
+ EXAMPLES::
366
+
367
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
368
+ sage: v = S.lift(S([4,3,0,1])); v
369
+ [4, 3, 0, 1]
370
+ sage: type(v)
371
+ <class 'list'>
372
+ """
373
+ # TODO: For now, Sage integer vectors are just python list.
374
+ # Once Integer vectors will have an element class, update this
375
+ # code properly
376
+ return list(elt)
377
+
378
+ def retract(self, elt):
379
+ r"""
380
+ Return the canonical representative of the orbit of the
381
+ integer ``elt`` under the action of the permutation group
382
+ defining ``self``.
383
+
384
+ If the element ``elt`` is already maximal in its orbit for
385
+ the lexicographic order, ``elt`` is thus the good
386
+ representative for its orbit.
387
+
388
+ EXAMPLES::
389
+
390
+ sage: [0,0,0,0] in IntegerVectors(0,4)
391
+ True
392
+ sage: [1,0,0,0] in IntegerVectors(1,4)
393
+ True
394
+ sage: [0,1,0,0] in IntegerVectors(1,4)
395
+ True
396
+ sage: [1,0,1,0] in IntegerVectors(2,4)
397
+ True
398
+ sage: [0,1,0,1] in IntegerVectors(2,4)
399
+ True
400
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
401
+ sage: S.retract([0,0,0,0])
402
+ [0, 0, 0, 0]
403
+ sage: S.retract([1,0,0,0])
404
+ [1, 0, 0, 0]
405
+ sage: S.retract([0,1,0,0])
406
+ [1, 0, 0, 0]
407
+ sage: S.retract([1,0,1,0])
408
+ [1, 0, 1, 0]
409
+ sage: S.retract([0,1,0,1])
410
+ [1, 0, 1, 0]
411
+ """
412
+ # TODO: Once Sage integer vector will have a data structure
413
+ # based on ClonableIntArray, remove the conversion intarray
414
+ assert len(elt) == self.n, "%s is a quotient set of %s" % (self, self.ambient())
415
+ intarray = self.element_class(self, elt, check=False)
416
+ return self.element_class(self, canonical_representative_of_orbit_of(self._sgs, intarray), check=False)
417
+
418
+ def roots(self):
419
+ r"""
420
+ Return the root of generation of ``self``. This method is
421
+ required to build the tree structure of ``self`` which
422
+ inherits from the class :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`.
423
+
424
+ EXAMPLES::
425
+
426
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
427
+ sage: I.roots()
428
+ [[0, 0, 0, 0]]
429
+ """
430
+ return [self.element_class(self, self.n*[0,], check=False)]
431
+
432
+ def children(self, x):
433
+ r"""
434
+ Return the list of children of the element ``x``. This method
435
+ is required to build the tree structure of ``self`` which
436
+ inherits from the class :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`.
437
+
438
+ EXAMPLES::
439
+
440
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
441
+ sage: I.children(I([2,1,0,0], check=False))
442
+ [[2, 2, 0, 0], [2, 1, 1, 0], [2, 1, 0, 1]]
443
+ """
444
+ return canonical_children(self._sgs, x, -1)
445
+
446
+ def permutation_group(self):
447
+ r"""
448
+ Return the permutation group given to define ``self``.
449
+
450
+ EXAMPLES::
451
+
452
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
453
+ sage: I.permutation_group()
454
+ Permutation Group with generators [(1,2,3,4)]
455
+ """
456
+ return self._permgroup
457
+
458
+ def is_canonical(self, v, check=True):
459
+ r"""
460
+ Return ``True`` if the integer list ``v`` is maximal in its
461
+ orbit under the action of the permutation group given to
462
+ define ``self``. Such integer vectors are said to be
463
+ canonical. A vector `v` is canonical if and only if
464
+
465
+ .. MATH::
466
+
467
+ v = \max_{\text{lex order}} \{g \cdot v | g \in G \}
468
+
469
+ EXAMPLES::
470
+
471
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
472
+ sage: I.is_canonical([4,3,2,1])
473
+ True
474
+ sage: I.is_canonical([4,0,0,1])
475
+ True
476
+ sage: I.is_canonical([4,0,3,3])
477
+ True
478
+ sage: I.is_canonical([4,0,4,4])
479
+ False
480
+ """
481
+ if check:
482
+ assert isinstance(v, (ClonableIntArray, list)), '%s should be a list or an integer vector' % v
483
+ assert (self.n == len(v)), '%s should be of length %s' % (v, self.n)
484
+ for p in v:
485
+ assert (p == NN(p)), 'Elements of %s should be integers' % v
486
+ return is_canonical(self._sgs, self.element_class(self, list(v), check=False))
487
+
488
+ def __contains__(self, v):
489
+ """
490
+ EXAMPLES::
491
+
492
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
493
+ sage: [2,2,0,0] in I
494
+ True
495
+ sage: [2,0,1,0] in I
496
+ True
497
+ sage: [2,0,0,1] in I
498
+ True
499
+ sage: [2,0,0,2] in I
500
+ False
501
+ sage: [2,0,0,2,12] in I
502
+ False
503
+ """
504
+ try:
505
+ return self.is_canonical(self.element_class(self, list(v), check=False), check=False)
506
+ except Exception:
507
+ return False
508
+
509
+ def __call__(self, v, check=True):
510
+ r"""
511
+ Return an element of ``self`` constructed from ``v`` if
512
+ possible.
513
+
514
+ TESTS::
515
+
516
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
517
+ sage: I([3,2,1,0])
518
+ [3, 2, 1, 0]
519
+ """
520
+ try:
521
+ if v.parent() is self:
522
+ return v
523
+ else:
524
+ raise ValueError('%s should be a Python list of integer' % (v))
525
+ except Exception:
526
+ return self.element_class(self, list(v), check=check)
527
+
528
+ def orbit(self, v):
529
+ r"""
530
+ Return the orbit of the integer vector ``v`` under the action of the
531
+ permutation group defining ``self``. The result is a set.
532
+
533
+ EXAMPLES:
534
+
535
+ In order to get reproducible doctests, we convert the returned sets
536
+ into lists in increasing lexicographic order::
537
+
538
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
539
+ sage: sorted(I.orbit([2,2,0,0]))
540
+ [[0, 0, 2, 2], [0, 2, 2, 0], [2, 0, 0, 2], [2, 2, 0, 0]]
541
+ sage: sorted(I.orbit([2,1,0,0]))
542
+ [[0, 0, 2, 1], [0, 2, 1, 0], [1, 0, 0, 2], [2, 1, 0, 0]]
543
+ sage: sorted(I.orbit([2,0,1,0]))
544
+ [[0, 1, 0, 2], [0, 2, 0, 1], [1, 0, 2, 0], [2, 0, 1, 0]]
545
+ sage: sorted(I.orbit([2,0,2,0]))
546
+ [[0, 2, 0, 2], [2, 0, 2, 0]]
547
+ sage: I.orbit([1,1,1,1])
548
+ {[1, 1, 1, 1]}
549
+ """
550
+ assert isinstance(v, (list, ClonableIntArray)), '%s should be a Python list or an element of %s' % (v, self)
551
+ try:
552
+ if v.parent() is self:
553
+ return orbit(self._sgs, v)
554
+ raise TypeError
555
+ except Exception:
556
+ return orbit(self._sgs, self.element_class(self, v, check=False))
557
+
558
+ def subset(self, sum=None, max_part=None):
559
+ r"""
560
+ Return the subset of ``self`` containing integer vectors
561
+ whose entries sum to ``sum``.
562
+
563
+ EXAMPLES::
564
+
565
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
566
+ sage: S.subset(4)
567
+ Integer vectors of length 4 and of sum 4 enumerated up to
568
+ the action of Permutation Group with generators
569
+ [(1,2,3,4)]
570
+ """
571
+ return IntegerVectorsModPermutationGroup_with_constraints(self.permutation_group(), sum, max_part)
572
+
573
+ class Element(ClonableIntArray):
574
+ r"""
575
+ Element class for the set of integer vectors of given sum enumerated modulo
576
+ the action of a permutation group. These vectors are clonable lists of integers
577
+ which must satisfy conditions coming from the parent appearing in the method
578
+ :meth:`~sage.structure.list_clone.ClonableIntArray.check`.
579
+
580
+ TESTS::
581
+
582
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
583
+ sage: v = I.element_class(I, [4,3,2,1]); v
584
+ [4, 3, 2, 1]
585
+ sage: TestSuite(v).run()
586
+ sage: I.element_class(I, [4,3,2,5])
587
+ Traceback (most recent call last):
588
+ ...
589
+ AssertionError
590
+ """
591
+
592
+ def check(self):
593
+ r"""
594
+ Check that ``self`` verify the invariants needed for
595
+ living in ``self.parent()``.
596
+
597
+ EXAMPLES::
598
+
599
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
600
+ sage: v = I.an_element()
601
+ sage: v.check()
602
+ sage: w = I([0,4,0,0], check=False); w
603
+ [0, 4, 0, 0]
604
+ sage: w.check()
605
+ Traceback (most recent call last):
606
+ ...
607
+ AssertionError
608
+ """
609
+ assert self.parent().is_canonical(self)
610
+
611
+
612
+ class IntegerVectorsModPermutationGroup_with_constraints(UniqueRepresentation, RecursivelyEnumeratedSet_forest):
613
+ r"""
614
+ This class models finite enumerated sets of integer vectors with
615
+ constraint enumerated up to the action of a permutation group.
616
+ Integer vectors are enumerated modulo the action of the
617
+ permutation group. To implement that, we keep a single integer
618
+ vector by orbit under the action of the permutation
619
+ group. Elements chosen are vectors maximal in their orbit for the
620
+ lexicographic order.
621
+
622
+ For more information see :class:`IntegerVectorsModPermutationGroup`.
623
+
624
+ EXAMPLES::
625
+
626
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
627
+ ....: max_part=1)
628
+ sage: I.list()
629
+ [[0, 0, 0, 0], [1, 0, 0, 0], [1, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 0],
630
+ [1, 1, 1, 1]]
631
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
632
+ ....: sum=6, max_part=4)
633
+ sage: I.list()
634
+ [[4, 2, 0, 0], [4, 1, 1, 0], [4, 1, 0, 1], [4, 0, 2, 0], [4, 0, 1, 1],
635
+ [4, 0, 0, 2], [3, 3, 0, 0], [3, 2, 1, 0], [3, 2, 0, 1], [3, 1, 2, 0],
636
+ [3, 1, 1, 1], [3, 1, 0, 2], [3, 0, 3, 0], [3, 0, 2, 1], [3, 0, 1, 2],
637
+ [2, 2, 2, 0], [2, 2, 1, 1], [2, 1, 2, 1]]
638
+
639
+ Here is the enumeration of unlabeled graphs over 5 vertices::
640
+
641
+ sage: G = IntegerVectorsModPermutationGroup(TransitiveGroup(10,12), max_part=1)
642
+ sage: G.cardinality()
643
+ 34
644
+
645
+ TESTS::
646
+
647
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),4)
648
+ sage: TestSuite(I).run()
649
+ """
650
+
651
+ def __init__(self, G, d, max_part, sgs=None):
652
+ r"""
653
+ TESTS::
654
+
655
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6, max_part=4)
656
+ """
657
+ RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=(FiniteEnumeratedSets(), FiniteEnumeratedSets().Quotients()))
658
+ self._permgroup = G
659
+ self.n = G.degree()
660
+ self._sum = d
661
+ if max_part is None:
662
+ self._max_part = -1
663
+ else:
664
+ self._max_part = max_part
665
+
666
+ # self.sgs: strong_generating_system
667
+ if sgs is None:
668
+ self._sgs = G.strong_generating_system()
669
+ else:
670
+ self._sgs = [list(x) for x in list(sgs)]
671
+
672
+ def _repr_(self):
673
+ r"""
674
+ TESTS::
675
+
676
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]])); S
677
+ Integer vectors of length 4 enumerated up to the action of Permutation Group with generators [(1,2,3,4)]
678
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6); S
679
+ Integer vectors of length 4 and of sum 6 enumerated up to the action of Permutation Group with generators [(1,2,3,4)]
680
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6, max_part=4); S
681
+ Vectors of length 4 and of sum 6 whose entries are in {0, ..., 4} enumerated up to the action of Permutation Group with generators [(1,2,3,4)]
682
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), max_part=4); S
683
+ Integer vectors of length 4 whose entries are in {0, ..., 4} enumerated up to the action of Permutation Group with generators [(1,2,3,4)]
684
+ """
685
+ if self._sum is not None:
686
+ if self._max_part >= 0:
687
+ return ("Vectors of length %s and of sum %s"
688
+ " whose entries are in {0, ..., %s}"
689
+ " enumerated up to the action of %s"
690
+ % (self.n, self._sum, self._max_part,
691
+ self.permutation_group()))
692
+ else:
693
+ return ("Integer vectors of length %s"
694
+ " and of sum %s"
695
+ " enumerated up to the action of %s"
696
+ % (self.n, self._sum, self.permutation_group()))
697
+ else:
698
+ return ("Integer vectors of length %s"
699
+ " whose entries are in {0, ..., %s}"
700
+ " enumerated up to the action of %s"
701
+ % (self.n, self._max_part, self.permutation_group()))
702
+
703
+ def roots(self):
704
+ r"""
705
+ Return the root of generation of ``self``.
706
+
707
+ This method is
708
+ required to build the tree structure of ``self`` which
709
+ inherits from the class
710
+ :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`.
711
+
712
+ EXAMPLES::
713
+
714
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
715
+ sage: I.roots()
716
+ [[0, 0, 0, 0]]
717
+ """
718
+ return [self.element_class(self, self.n*[0,], check=False)]
719
+
720
+ def children(self, x):
721
+ r"""
722
+ Return the list of children of the element ``x``.
723
+
724
+ This method
725
+ is required to build the tree structure of ``self`` which
726
+ inherits from the class
727
+ :class:`~sage.sets.recursively_enumerated_set.RecursivelyEnumeratedSet_forest`.
728
+
729
+ EXAMPLES::
730
+
731
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]))
732
+ sage: I.children(I([2,1,0,0], check=False))
733
+ [[2, 2, 0, 0], [2, 1, 1, 0], [2, 1, 0, 1]]
734
+ """
735
+ return canonical_children(self._sgs, x, -1)
736
+
737
+ def permutation_group(self):
738
+ r"""
739
+ Return the permutation group given to define ``self``.
740
+
741
+ EXAMPLES::
742
+
743
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]]), 5)
744
+ sage: I.permutation_group()
745
+ Permutation Group with generators [(1,2,3)]
746
+ """
747
+ return self._permgroup
748
+
749
+ def __contains__(self, v):
750
+ r"""
751
+ TESTS::
752
+
753
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),6)
754
+ sage: [6,0,0,0] in I
755
+ True
756
+ sage: [5,0,1,0] in I
757
+ True
758
+ sage: [0,5,1,0] in I
759
+ False
760
+ sage: [3,0,1,3] in I
761
+ False
762
+ sage: [3,3,1,0] in I
763
+ False
764
+ """
765
+ try:
766
+ return (self(v)).parent() is self
767
+ except Exception:
768
+ return False
769
+
770
+ def __call__(self, v, check=True):
771
+ r"""
772
+ Make `v` an element living in ``self``.
773
+
774
+ TESTS::
775
+
776
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 4)
777
+ sage: v = I([2,1,0,1]); v
778
+ [2, 1, 0, 1]
779
+ sage: v.parent()
780
+ Integer vectors of length 4 and of sum 4 enumerated up to
781
+ the action of Permutation Group with generators
782
+ [(1,2,3,4)]
783
+ """
784
+ try:
785
+ if v.parent() is self:
786
+ return v
787
+ else:
788
+ raise ValueError('%s should be a Python list of integer' % (v))
789
+ except Exception:
790
+ return self.element_class(self, list(v), check=check)
791
+
792
+ def __iter__(self):
793
+ r"""
794
+ TESTS::
795
+
796
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),4)
797
+ sage: for i in I: i
798
+ [4, 0, 0, 0]
799
+ [3, 1, 0, 0]
800
+ [3, 0, 1, 0]
801
+ [3, 0, 0, 1]
802
+ [2, 2, 0, 0]
803
+ [2, 1, 1, 0]
804
+ [2, 1, 0, 1]
805
+ [2, 0, 2, 0]
806
+ [2, 0, 1, 1]
807
+ [1, 1, 1, 1]
808
+
809
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), sum=7, max_part=3)
810
+ sage: for i in I: i
811
+ [3, 3, 1, 0]
812
+ [3, 3, 0, 1]
813
+ [3, 2, 2, 0]
814
+ [3, 2, 1, 1]
815
+ [3, 2, 0, 2]
816
+ [3, 1, 3, 0]
817
+ [3, 1, 2, 1]
818
+ [3, 1, 1, 2]
819
+ [3, 0, 2, 2]
820
+ [2, 2, 2, 1]
821
+
822
+ Check that :issue:`36681` is fixed::
823
+
824
+ sage: G = PermutationGroup([], domain=[])
825
+ sage: I = IntegerVectorsModPermutationGroup(G, sum=0)
826
+ sage: list(iter(I))
827
+ [[]]
828
+
829
+ Check that :issue:`36681` is fixed::
830
+
831
+ sage: G = PermutationGroup([], domain=[])
832
+ sage: I = IntegerVectorsModPermutationGroup(G, sum=3)
833
+ sage: list(iter(I))
834
+ []
835
+ """
836
+ # Special cases when domain is empty.
837
+ if self.n == 0:
838
+ if self._sum is not None and self._sum > 0:
839
+ # No empty vector can have positive sum.
840
+ return iter(())
841
+ else:
842
+ # Sum is allowed to be zero. It does not matter what
843
+ # the maxpart is, the empty vector is a solution.
844
+ return iter([self([])])
845
+
846
+ # General case, nonempty domain.
847
+ if self._max_part < 0:
848
+ return self.elements_of_depth_iterator(self._sum)
849
+ else:
850
+ SF = RecursivelyEnumeratedSet_forest(
851
+ (self([0]*(self.n), check=False),),
852
+ lambda x: [self(y, check=False)
853
+ for y in canonical_children(
854
+ self._sgs, x, self._max_part)],
855
+ algorithm='breadth')
856
+ if self._sum is None:
857
+ return iter(SF)
858
+ else:
859
+ return SF.elements_of_depth_iterator(self._sum)
860
+
861
+ def cardinality(self):
862
+ r"""
863
+ Return the number of integer vectors in the set.
864
+
865
+ The algorithm utilises :wikipedia:`Cycle Index Theorem <Cycle_index>`, allowing
866
+ for a faster than a plain enumeration computation.
867
+
868
+ EXAMPLES:
869
+
870
+ With a trivial group all vectors are canonical::
871
+
872
+ sage: G = PermutationGroup([], domain=[1,2,3])
873
+ sage: IntegerVectorsModPermutationGroup(G, 5).cardinality()
874
+ 21
875
+ sage: IntegerVectors(5, 3).cardinality()
876
+ 21
877
+
878
+ With two interchangeable elements, the smaller one
879
+ ranges from zero to ``sum//2``::
880
+
881
+ sage: G = PermutationGroup([(1,2)])
882
+ sage: IntegerVectorsModPermutationGroup(G, 1000).cardinality()
883
+ 501
884
+
885
+ Binary vectors up to full symmetry are first some ones and
886
+ then some zeros::
887
+
888
+ sage: G = SymmetricGroup(10)
889
+ sage: I = IntegerVectorsModPermutationGroup(G, max_part=1)
890
+ sage: I.cardinality()
891
+ 11
892
+
893
+ Binary vectors of constant weight, up to PGL(2,17), which
894
+ is 3-transitive, but not 4-transitive::
895
+
896
+ sage: G=PGL(2,17)
897
+ sage: I = IntegerVectorsModPermutationGroup(G, sum=3, max_part=1)
898
+ sage: I.cardinality()
899
+ 1
900
+ sage: I = IntegerVectorsModPermutationGroup(G, sum=4, max_part=1)
901
+ sage: I.cardinality()
902
+ 3
903
+
904
+ TESTS:
905
+
906
+ Check that :issue:`36681` is fixed::
907
+
908
+ sage: G = PermutationGroup([], domain=[])
909
+ sage: sgs = tuple(tuple(t) for t in G.strong_generating_system())
910
+ sage: V = IntegerVectorsModPermutationGroup(G, sum=1, sgs=sgs)
911
+ sage: V.cardinality()
912
+ 0
913
+
914
+ The case when both ``sum`` and ``max_part`` are specified::
915
+
916
+ sage: G = PermutationGroup([(1,2,3)])
917
+ sage: I = IntegerVectorsModPermutationGroup(G, sum=10, max_part=5)
918
+ sage: I.cardinality()
919
+ 7
920
+
921
+ All permutation groups of degree 4::
922
+
923
+ sage: for G in SymmetricGroup(4).subgroups():
924
+ ....: sgs = tuple(tuple(t) for t in G.strong_generating_system())
925
+ ....: I1 = IntegerVectorsModPermutationGroup(G, sum=10, sgs=sgs)
926
+ ....: assert I1.cardinality() == len(list(I1))
927
+ ....: I2 = IntegerVectorsModPermutationGroup(G, max_part=3, sgs=sgs)
928
+ ....: assert I2.cardinality() == len(list(I2))
929
+ ....: I3 = IntegerVectorsModPermutationGroup(G, sum=10, max_part=3, sgs=sgs)
930
+ ....: assert I3.cardinality() == len(list(I3))
931
+
932
+ Symmetric group with sums 0 and 1::
933
+
934
+ sage: S10 = SymmetricGroup(10)
935
+ sage: IntegerVectorsModPermutationGroup(S10, 0).cardinality()
936
+ 1
937
+ sage: IntegerVectorsModPermutationGroup(S10, 1).cardinality()
938
+ 1
939
+
940
+ Trivial group with sums 1 and 100::
941
+
942
+ sage: T10 = PermutationGroup([], domain=range(1, 11))
943
+ sage: IntegerVectorsModPermutationGroup(T10, 1).cardinality()
944
+ 10
945
+ sage: IntegerVectorsModPermutationGroup(T10, 100).cardinality()
946
+ 4263421511271
947
+ """
948
+ G = self._permgroup
949
+ k = G.degree() # Vector length
950
+ d = self._sum # Required sum
951
+ m = self._max_part # Max of one entry, -1 for no limit
952
+ if m == -1:
953
+ m = d # Any entry cannot exceed total
954
+
955
+ # Some easy special cases.
956
+ if k == 0:
957
+ # Empty vectors. There is only one, and it has zero sum.
958
+ # Here _max_part does not matter because any _max_part
959
+ # condition is vacuously true (with no parts).
960
+ if d == 0 or d is None:
961
+ return Integer(1)
962
+ else:
963
+ return Integer(0)
964
+ if d == 0 or m == 0:
965
+ # All-zero vectors. There is only one of them.
966
+ return Integer(1)
967
+ if d == 1:
968
+ # Vectors with one 1 and all other elements zero.
969
+ # The 1 can be placed in any orbit, and by symmetry
970
+ # it will be on the first element of the orbit.
971
+ return Integer(len(G.orbits()))
972
+ if d is not None and m >= d and G.is_trivial():
973
+ # Simple calculation with stars and bars.
974
+ return Integer(binomial(d + k - 1, k - 1))
975
+
976
+ # General case.
977
+ #
978
+ # Cardinality is computed using the Cycle Index Theorem. We
979
+ # have two cases. With a fixed sum d we work with power
980
+ # series and extract the x^d coefficient. Without a fixed sum
981
+ # we can do with integer arithmetic.
982
+ Z = G.cycle_index()
983
+
984
+ if d is None:
985
+ # Case 1. Without a fixed sum, the sum can be up to k*m.
986
+ result = sum(coeff * (m+1)**len(cycle_type)
987
+ for cycle_type, coeff in Z)
988
+ # Computed as Rational, but should have an integer value
989
+ # by now.
990
+ return Integer(result)
991
+
992
+ # Case 2. Fixed sum d. Work with power series with enough
993
+ # precision that x^d is valid.
994
+ R = PowerSeriesRing(QQ, 'x', default_prec=d+1)
995
+ x = R.gen()
996
+
997
+ # The figure-counting series, for max_part==m, is (1-t**(m+1))
998
+ # / (1-t) = 1+t+...+t**m. For the function-counting series,
999
+ # we substitute x**cycle_length for t.
1000
+ #
1001
+ funcount = sum(
1002
+ coeff * prod((1 - x**((m+1)*cycle_len)) / (1 - x**cycle_len)
1003
+ for cycle_len in cycle_type)
1004
+ for cycle_type, coeff in Z)
1005
+
1006
+ # Extract the d'th degree coefficient. Computed as Rational,
1007
+ # but should have an integer value by now.
1008
+ return Integer(funcount[d])
1009
+
1010
+ def is_canonical(self, v, check=True):
1011
+ r"""
1012
+ Return ``True`` if the integer list ``v`` is maximal in its
1013
+ orbit under the action of the permutation group given to
1014
+ define ``self``. Such integer vectors are said to be
1015
+ canonical. A vector `v` is canonical if and only if
1016
+
1017
+ .. MATH::
1018
+
1019
+ v = \max_{\text{lex order}} \{g \cdot v | g \in G \}
1020
+
1021
+ EXAMPLES::
1022
+
1023
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1024
+ ....: max_part=3)
1025
+ sage: I.is_canonical([3,0,0,0])
1026
+ True
1027
+ sage: I.is_canonical([1,0,2,0])
1028
+ False
1029
+ sage: I.is_canonical([2,0,1,0])
1030
+ True
1031
+ """
1032
+ if check:
1033
+ assert isinstance(v, (ClonableIntArray, list)), '%s should be a list or an integer vector' % v
1034
+ assert (self.n == len(v)), '%s should be of length %s' % (v, self.n)
1035
+ for p in v:
1036
+ assert (p == NN(p)), 'Elements of %s should be integers' % v
1037
+ return is_canonical(self._sgs, self.element_class(self, list(v), check=False))
1038
+
1039
+ def ambient(self):
1040
+ r"""
1041
+ Return the ambient space from which ``self`` is a quotient.
1042
+
1043
+ EXAMPLES::
1044
+
1045
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6)
1046
+ sage: S.ambient()
1047
+ Integer vectors that sum to 6
1048
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1049
+ ....: 6, max_part=12)
1050
+ sage: S.ambient()
1051
+ Integer vectors that sum to 6 with constraints: max_part=12
1052
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1053
+ ....: max_part=12)
1054
+ sage: S.ambient()
1055
+ Integer vectors with constraints: max_part=12
1056
+ """
1057
+ if self._sum is not None:
1058
+ if self._max_part <= -1:
1059
+ return IntegerVectors(n=self._sum)
1060
+ else:
1061
+ return IntegerVectors(n=self._sum, max_part=self._max_part)
1062
+ else:
1063
+ return IntegerVectors(max_part=self._max_part)
1064
+
1065
+ def lift(self, elt):
1066
+ r"""
1067
+ Lift the element ``elt`` inside the ambient space from which ``self`` is a quotient.
1068
+
1069
+ EXAMPLES::
1070
+
1071
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1072
+ ....: max_part=1)
1073
+ sage: v = S.lift([1,0,1,0]); v
1074
+ [1, 0, 1, 0]
1075
+ sage: v in IntegerVectors(2,4,max_part=1)
1076
+ True
1077
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1078
+ ....: sum=6)
1079
+ sage: v = S.lift(S.list()[5]); v
1080
+ [4, 1, 1, 0]
1081
+ sage: v in IntegerVectors(n=6)
1082
+ True
1083
+ """
1084
+ # TODO: For now, Sage integer vectors are just python list.
1085
+ # Once Integer vectors will have an element class, update this
1086
+ # code properly
1087
+ return list(elt)
1088
+
1089
+ def retract(self, elt):
1090
+ r"""
1091
+ Return the canonical representative of the orbit of the
1092
+ integer ``elt`` under the action of the permutation group
1093
+ defining ``self``.
1094
+
1095
+ If the element ``elt`` is already maximal in its orbits for
1096
+ the lexicographic order, ``elt`` is thus the good
1097
+ representative for its orbit.
1098
+
1099
+ EXAMPLES::
1100
+
1101
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1102
+ ....: sum=2, max_part=1)
1103
+ sage: S.retract([1,1,0,0])
1104
+ [1, 1, 0, 0]
1105
+ sage: S.retract([1,0,1,0])
1106
+ [1, 0, 1, 0]
1107
+ sage: S.retract([1,0,0,1])
1108
+ [1, 1, 0, 0]
1109
+ sage: S.retract([0,1,1,0])
1110
+ [1, 1, 0, 0]
1111
+ sage: S.retract([0,1,0,1])
1112
+ [1, 0, 1, 0]
1113
+ sage: S.retract([0,0,1,1])
1114
+ [1, 1, 0, 0]
1115
+ """
1116
+ # TODO: Once Sage integer vector will have a data structure
1117
+ # based on ClonableIntArray, remove the conversion intarray
1118
+ assert len(elt) == self.n, "%s is a quotient set of %s" % (self, self.ambient())
1119
+ if self._sum is not None:
1120
+ assert sum(elt) == self._sum, "%s is a quotient set of %s" % (self, self.ambient())
1121
+ if self._max_part >= 0:
1122
+ assert max(elt) <= self._max_part, "%s is a quotient set of %s" % (self, self.ambient())
1123
+ intarray = self.element_class(self, elt, check=False)
1124
+ return self.element_class(self, canonical_representative_of_orbit_of(self._sgs, intarray), check=False)
1125
+
1126
+ def _an_element_(self):
1127
+ r"""
1128
+ Return an element of ``self``.
1129
+
1130
+ This raises an :exc:`EmptySetError` when ``self`` is empty.
1131
+
1132
+ EXAMPLES::
1133
+
1134
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1135
+ ....: sum=0, max_part=1)
1136
+ sage: S.an_element()
1137
+ [0, 0, 0, 0]
1138
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1139
+ ....: sum=1, max_part=1)
1140
+ sage: S.an_element()
1141
+ [1, 0, 0, 0]
1142
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1143
+ ....: sum=2, max_part=1)
1144
+ sage: S.an_element()
1145
+ [1, 1, 0, 0]
1146
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1147
+ ....: sum=3, max_part=1)
1148
+ sage: S.an_element()
1149
+ [1, 1, 1, 0]
1150
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1151
+ ....: sum=4, max_part=1)
1152
+ sage: S.an_element()
1153
+ [1, 1, 1, 1]
1154
+ sage: S = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),
1155
+ ....: sum=5, max_part=1)
1156
+ sage: S.an_element()
1157
+ Traceback (most recent call last):
1158
+ ...
1159
+ EmptySetError
1160
+ """
1161
+ if self._max_part < 0:
1162
+ return self([self._sum]+(self.n-1)*[0], check=False)
1163
+ else:
1164
+ try:
1165
+ v = iter(self)
1166
+ return next(v)
1167
+ except StopIteration:
1168
+ from sage.categories.sets_cat import EmptySetError
1169
+ raise EmptySetError
1170
+
1171
+ def orbit(self, v):
1172
+ r"""
1173
+ Return the orbit of the vector ``v`` under the action of the
1174
+ permutation group defining ``self``. The result is a set.
1175
+
1176
+ INPUT:
1177
+
1178
+ - ``v`` -- an element of ``self`` or any list of length the
1179
+ degree of the permutation group
1180
+
1181
+ EXAMPLES:
1182
+
1183
+ We convert the result in a list in increasing lexicographic
1184
+ order, to get a reproducible doctest::
1185
+
1186
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 4)
1187
+ sage: I.orbit([1,1,1,1])
1188
+ {[1, 1, 1, 1]}
1189
+ sage: sorted(I.orbit([3,0,0,1]))
1190
+ [[0, 0, 1, 3], [0, 1, 3, 0], [1, 3, 0, 0], [3, 0, 0, 1]]
1191
+ """
1192
+ assert isinstance(v, (list, ClonableIntArray)), '%s should be a Python list or an element of %s' % (v, self)
1193
+ try:
1194
+ if v.parent() is self:
1195
+ return orbit(self._sgs, v)
1196
+ except Exception:
1197
+ return orbit(self._sgs, self.element_class(self, v, check=False))
1198
+
1199
+ class Element(ClonableIntArray):
1200
+ r"""
1201
+ Element class for the set of integer vectors with constraints enumerated
1202
+ modulo the action of a permutation group. These vectors are clonable lists
1203
+ of integers which must satisfy conditions coming from the parent as in
1204
+ the method :meth:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup_with_constraints.Element.check`.
1205
+
1206
+ TESTS::
1207
+
1208
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 4)
1209
+ sage: v = I.element_class(I, [3,1,0,0]); v
1210
+ [3, 1, 0, 0]
1211
+ sage: TestSuite(v).run()
1212
+ sage: v = I.element_class(I, [3,2,0,0])
1213
+ Traceback (most recent call last):
1214
+ ...
1215
+ AssertionError: [3, 2, 0, 0] should be an integer vector of sum 4
1216
+ """
1217
+
1218
+ def check(self):
1219
+ r"""
1220
+ Check that ``self`` meets the constraints of being an element of ``self.parent()``.
1221
+
1222
+ EXAMPLES::
1223
+
1224
+ sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 4)
1225
+ sage: v = I.an_element()
1226
+ sage: v.check()
1227
+ sage: w = I([0,4,0,0], check=False); w
1228
+ [0, 4, 0, 0]
1229
+ sage: w.check()
1230
+ Traceback (most recent call last):
1231
+ ...
1232
+ AssertionError
1233
+ """
1234
+ if self.parent()._sum is not None:
1235
+ assert sum(self) == self.parent()._sum, '%s should be an integer vector of sum %s' % (self, self.parent()._sum)
1236
+ if self.parent()._max_part >= 0:
1237
+ assert max(self) <= self.parent()._max_part, 'Entries of %s must be inferior to %s' % (self, self.parent()._max_part)
1238
+ assert self.parent().is_canonical(self)