passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.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 (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,1159 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ # distutils: language = c++
3
+ """
4
+ Dancing Links internal pyx code
5
+
6
+ EXAMPLES::
7
+
8
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
9
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
10
+ sage: x = dlx_solver(rows)
11
+ sage: x
12
+ Dancing links solver for 6 columns and 6 rows
13
+
14
+ The number of solutions::
15
+
16
+ sage: x.number_of_solutions()
17
+ 3
18
+
19
+ Iterate over the solutions::
20
+
21
+ sage: sorted(map(sorted, x.solutions_iterator()))
22
+ [[0, 1], [2, 3], [4, 5]]
23
+
24
+ All solutions (computed in parallel)::
25
+
26
+ sage: sorted(map(sorted, x.all_solutions()))
27
+ [[0, 1], [2, 3], [4, 5]]
28
+
29
+ Return the first solution found when the computation is done in parallel::
30
+
31
+ sage: sorted(x.one_solution(ncpus=2)) # random
32
+ [0, 1]
33
+
34
+ Find all solutions using some specific rows::
35
+
36
+ sage: x_using_row_2 = x.restrict([2])
37
+ sage: x_using_row_2
38
+ Dancing links solver for 7 columns and 6 rows
39
+ sage: sorted(map(sorted, x_using_row_2.solutions_iterator()))
40
+ [[2, 3]]
41
+
42
+ The two basic methods that are wrapped in this class are ``search`` which
43
+ returns ``1`` if a solution is found or ``0`` otherwise and ``get_solution``
44
+ which return the current solution::
45
+
46
+ sage: x = dlx_solver(rows)
47
+ sage: x.search()
48
+ 1
49
+ sage: x.get_solution()
50
+ [0, 1]
51
+ sage: x.search()
52
+ 1
53
+ sage: x.get_solution()
54
+ [2, 3]
55
+ sage: x.search()
56
+ 1
57
+ sage: x.get_solution()
58
+ [4, 5]
59
+ sage: x.search()
60
+ 0
61
+
62
+ There is also a method ``reinitialize`` to reinitialize the algorithm::
63
+
64
+ sage: x.reinitialize()
65
+ sage: x.search()
66
+ 1
67
+ sage: x.get_solution()
68
+ [0, 1]
69
+ """
70
+ # ****************************************************************************
71
+ # Copyright (C) 2008 Carlo Hamalainen <carlo.hamalainen@gmail.com>
72
+ # Copyright (C) 2015-2018 Sébastien Labbé <slabqc@gmail.com>
73
+ #
74
+ # This program is free software: you can redistribute it and/or modify
75
+ # it under the terms of the GNU General Public License as published by
76
+ # the Free Software Foundation, either version 2 of the License, or
77
+ # (at your option) any later version.
78
+ # https://www.gnu.org/licenses/
79
+ # ****************************************************************************
80
+
81
+ from cpython.object cimport PyObject_RichCompare
82
+ from libcpp.vector cimport vector
83
+ from cysignals.signals cimport sig_on, sig_off
84
+
85
+ cdef extern from "dancing_links_c.h":
86
+ cdef cppclass dancing_links:
87
+ dancing_links()
88
+ vector[int] solution
89
+ int number_of_columns()
90
+ void add_rows(vector[vector[int]] rows)
91
+ int search_is_started()
92
+ int search()
93
+
94
+ from sage.misc.cachefunc import cached_method
95
+
96
+ cdef class dancing_linksWrapper:
97
+ r"""
98
+ A simple class that implements dancing links.
99
+
100
+ The main methods to list the solutions are :meth:`search` and
101
+ :meth:`get_solution`. You can also use :meth:`number_of_solutions` to count
102
+ them.
103
+
104
+ This class simply wraps a C++ implementation of Carlo Hamalainen.
105
+ """
106
+ cdef dancing_links _x
107
+ cdef list _rows
108
+
109
+ def __init__(self, rows):
110
+ """
111
+ Initialize our wrapper (self._x) as an actual C++ object.
112
+
113
+ We must pass a list of rows at start up.
114
+
115
+ EXAMPLES::
116
+
117
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
118
+ sage: rows = [[0,1,2]]
119
+ sage: rows+= [[0,2]]
120
+ sage: rows+= [[1]]
121
+ sage: rows+= [[3]]
122
+ sage: x = dlx_solver(rows)
123
+ sage: x
124
+ Dancing links solver for 4 columns and 4 rows
125
+ sage: x.search()
126
+ 1
127
+ sage: x.get_solution()
128
+ [3, 0]
129
+
130
+ ::
131
+
132
+ sage: rows = [[0,1,2], [1, 2]]
133
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
134
+ sage: x = dlx_solver(rows)
135
+ sage: x
136
+ Dancing links solver for 3 columns and 2 rows
137
+ sage: type(x)
138
+ <class 'sage.combinat.matrices.dancing_links.dancing_linksWrapper'>
139
+
140
+ TESTS:
141
+
142
+ The following example would crash in Sage's debug version
143
+ from :issue:`13864` prior to the fix from :issue:`13882`::
144
+
145
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
146
+ sage: x = dlx_solver([])
147
+ sage: x.get_solution()
148
+ []
149
+ """
150
+ self._rows = [row for row in rows]
151
+ self._initialize()
152
+
153
+ def _initialize(self):
154
+ r"""
155
+ Initialization of the search algorithm.
156
+
157
+ This adds the rows to the instance of dancing_links. This method is
158
+ used by ``__init__`` and ``reinitialize`` methods and should not be
159
+ used directly.
160
+
161
+ EXAMPLES::
162
+
163
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
164
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
165
+ sage: x = dlx_solver(rows) # indirect doctest
166
+ sage: x.get_solution() if x.search() else None
167
+ [0, 1]
168
+ sage: x.get_solution() if x.search() else None
169
+ [2, 3]
170
+
171
+ Reinitialization of the algorithm::
172
+
173
+ sage: x.reinitialize() # indirect doctest
174
+ sage: x.get_solution() if x.search() else None
175
+ [0, 1]
176
+ """
177
+ cdef vector[int] v
178
+ cdef vector[vector[int]] vv
179
+
180
+ for row in self._rows:
181
+ v.clear()
182
+ for x in row:
183
+ v.push_back(x)
184
+ vv.push_back(v)
185
+
186
+ sig_on()
187
+ self._x.add_rows(vv)
188
+ sig_off()
189
+
190
+ def reinitialize(self):
191
+ r"""
192
+ Reinitialization of the search algorithm.
193
+
194
+ This recreates an empty ``dancing_links`` object and adds the rows to
195
+ the instance of ``dancing_links.``
196
+
197
+ EXAMPLES::
198
+
199
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
200
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
201
+ sage: x = dlx_solver(rows)
202
+ sage: x.get_solution() if x.search() else None
203
+ [0, 1]
204
+ sage: x.get_solution() if x.search() else None
205
+ [2, 3]
206
+
207
+ Reinitialization of the algorithm::
208
+
209
+ sage: x.reinitialize()
210
+ sage: x.get_solution() if x.search() else None
211
+ [0, 1]
212
+ sage: x.get_solution() if x.search() else None
213
+ [2, 3]
214
+ sage: x.get_solution() if x.search() else None
215
+ [4, 5]
216
+ sage: x.get_solution() if x.search() else None
217
+
218
+ Reinitialization works after solutions are exhausted::
219
+
220
+ sage: x.reinitialize()
221
+ sage: x.get_solution() if x.search() else None
222
+ [0, 1]
223
+ sage: x.get_solution() if x.search() else None
224
+ [2, 3]
225
+ sage: x.get_solution() if x.search() else None
226
+ [4, 5]
227
+ sage: x.get_solution() if x.search() else None
228
+ """
229
+ sig_on()
230
+ self._x = dancing_links()
231
+ sig_off()
232
+
233
+ self._initialize()
234
+
235
+ def __repr__(self):
236
+ """
237
+ The string representation of this wrapper is just the list of
238
+ rows as supplied at startup.
239
+
240
+ TESTS::
241
+
242
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
243
+ sage: rows = [[0,1,2], [1,2], [0]]
244
+ sage: dlx_solver(rows)
245
+ Dancing links solver for 3 columns and 3 rows
246
+ """
247
+ return "Dancing links solver for {} columns and {} rows".format(
248
+ self.ncols(), self.nrows())
249
+
250
+ def rows(self):
251
+ r"""
252
+ Return the list of rows.
253
+
254
+ EXAMPLES::
255
+
256
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
257
+ sage: rows = [[0,1,2], [1,2], [0]]
258
+ sage: x = dlx_solver(rows)
259
+ sage: x.rows()
260
+ [[0, 1, 2], [1, 2], [0]]
261
+ """
262
+ return self._rows
263
+
264
+ def ncols(self):
265
+ """
266
+ Return the number of columns.
267
+
268
+ EXAMPLES::
269
+
270
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
271
+ sage: rows = [[0,1,2], [1,2], [0], [3,4,5]]
272
+ sage: dlx = dlx_solver(rows)
273
+ sage: dlx.ncols()
274
+ 6
275
+ """
276
+ return self._x.number_of_columns()
277
+
278
+ def nrows(self):
279
+ """
280
+ Return the number of rows.
281
+
282
+ EXAMPLES::
283
+
284
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
285
+ sage: rows = [[0,1,2], [1,2], [0], [3,4,5]]
286
+ sage: dlx = dlx_solver(rows)
287
+ sage: dlx.nrows()
288
+ 4
289
+ """
290
+ return len(self._rows)
291
+
292
+ def __reduce__(self):
293
+ """
294
+ This is used when pickling.
295
+
296
+ TESTS::
297
+
298
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
299
+ sage: rows = [[0,1,2]]
300
+ sage: X = dlx_solver(rows)
301
+ sage: X == loads(dumps(X))
302
+ 1
303
+ sage: rows += [[2]]
304
+ sage: Y = dlx_solver(rows)
305
+ sage: Y == loads(dumps(X))
306
+ 0
307
+ """
308
+ return type(self), (self._rows,)
309
+
310
+ def __richcmp__(dancing_linksWrapper left, dancing_linksWrapper right, int op):
311
+ """
312
+ Two dancing_linksWrapper objects are equal if they were
313
+ initialised using the same row list.
314
+
315
+ TESTS::
316
+
317
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
318
+ sage: rows = [[0,1,2]]
319
+ sage: X = dlx_solver(rows)
320
+ sage: Z = dlx_solver(rows)
321
+ sage: rows += [[2]]
322
+ sage: Y = dlx_solver(rows)
323
+ sage: X == Z
324
+ 1
325
+ sage: X == Y
326
+ 0
327
+ """
328
+ return PyObject_RichCompare(left._rows, right._rows, op)
329
+
330
+ def get_solution(self):
331
+ """
332
+ Return the current solution.
333
+
334
+ After a new solution is found using the method :meth:`search` this
335
+ method return the rows that make up the current solution.
336
+
337
+ TESTS::
338
+
339
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
340
+ sage: rows = [[0,1,2]]
341
+ sage: rows+= [[0,2]]
342
+ sage: rows+= [[1]]
343
+ sage: rows+= [[3]]
344
+ sage: x = dlx_solver(rows)
345
+ sage: print(x.search())
346
+ 1
347
+ sage: print(x.get_solution())
348
+ [3, 0]
349
+ """
350
+ cdef size_t i
351
+ cdef list s = []
352
+ for i in range(self._x.solution.size()):
353
+ s.append(self._x.solution.at(i))
354
+
355
+ return s
356
+
357
+ def search(self):
358
+ """
359
+ Search for a new solution.
360
+
361
+ Return ``1`` if a new solution is found and ``0`` otherwise. To recover
362
+ the solution, use the method :meth:`get_solution`.
363
+
364
+ EXAMPLES::
365
+
366
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
367
+ sage: rows = [[0,1,2]]
368
+ sage: rows+= [[0,2]]
369
+ sage: rows+= [[1]]
370
+ sage: rows+= [[3]]
371
+ sage: x = dlx_solver(rows)
372
+ sage: print(x.search())
373
+ 1
374
+ sage: print(x.get_solution())
375
+ [3, 0]
376
+
377
+ TESTS:
378
+
379
+ Test that :issue:`11814` is fixed::
380
+
381
+ sage: dlx_solver([]).search()
382
+ 0
383
+ sage: dlx_solver([[]]).search()
384
+ 0
385
+
386
+ If search is called once too often, it keeps returning 0::
387
+
388
+ sage: x = dlx_solver([[0]])
389
+ sage: x.search()
390
+ 1
391
+ sage: x.search()
392
+ 0
393
+ sage: x.search()
394
+ 0
395
+ """
396
+ sig_on()
397
+ x = self._x.search()
398
+ sig_off()
399
+ return x
400
+
401
+ def restrict(self, indices):
402
+ r"""
403
+ Return a dancing links solver solving the subcase which uses some
404
+ given rows.
405
+
406
+ For every row that is wanted in the solution, we add a new column
407
+ to the row to make sure it is in the solution.
408
+
409
+ INPUT:
410
+
411
+ - ``indices`` -- list; row indices to be found in the solution
412
+
413
+ OUTPUT: dancing links solver
414
+
415
+ EXAMPLES::
416
+
417
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
418
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
419
+ sage: d = dlx_solver(rows)
420
+ sage: d
421
+ Dancing links solver for 6 columns and 6 rows
422
+ sage: sorted(map(sorted, d.solutions_iterator()))
423
+ [[0, 1], [2, 3], [4, 5]]
424
+
425
+ To impose that the `0`-th row is part of the solution, the rows of the new
426
+ problem are::
427
+
428
+ sage: d_using_0 = d.restrict([0])
429
+ sage: d_using_0
430
+ Dancing links solver for 7 columns and 6 rows
431
+ sage: d_using_0.rows()
432
+ [[0, 1, 2, 6], [3, 4, 5], [0, 1], [2, 3, 4, 5], [0], [1, 2, 3, 4, 5]]
433
+
434
+ After restriction the subproblem has one more columns and the same
435
+ number of rows as the original one::
436
+
437
+ sage: d.restrict([1]).rows()
438
+ [[0, 1, 2], [3, 4, 5, 6], [0, 1], [2, 3, 4, 5], [0], [1, 2, 3, 4, 5]]
439
+ sage: d.restrict([2]).rows()
440
+ [[0, 1, 2], [3, 4, 5], [0, 1, 6], [2, 3, 4, 5], [0], [1, 2, 3, 4, 5]]
441
+
442
+ This method allows to find solutions where the `0`-th row is part of a
443
+ solution::
444
+
445
+ sage: sorted(map(sorted, d.restrict([0]).solutions_iterator()))
446
+ [[0, 1]]
447
+
448
+ Some other examples::
449
+
450
+ sage: sorted(map(sorted, d.restrict([1]).solutions_iterator()))
451
+ [[0, 1]]
452
+ sage: sorted(map(sorted, d.restrict([2]).solutions_iterator()))
453
+ [[2, 3]]
454
+ sage: sorted(map(sorted, d.restrict([3]).solutions_iterator()))
455
+ [[2, 3]]
456
+
457
+ Here there are no solutions using both 0th and 3rd row::
458
+
459
+ sage: list(d.restrict([0,3]).solutions_iterator())
460
+ []
461
+
462
+ TESTS::
463
+
464
+ sage: d.restrict([]).rows()
465
+ [[0, 1, 2], [3, 4, 5], [0, 1], [2, 3, 4, 5], [0], [1, 2, 3, 4, 5]]
466
+ """
467
+ from copy import copy
468
+ rows = copy(self._rows)
469
+ ncols = self.ncols()
470
+ for i, row_index in enumerate(indices):
471
+ # in the line below we want the creation of a new list
472
+ rows[row_index] = rows[row_index] + [ncols+i]
473
+ return dlx_solver(rows)
474
+
475
+ def split(self, column):
476
+ r"""
477
+ Return a dict of independent solvers.
478
+
479
+ For each ``i``-th row containing a ``1`` in the ``column``, the
480
+ dict associates the solver giving all solution using the ``i``-th
481
+ row.
482
+
483
+ This is used for parallel computations.
484
+
485
+ INPUT:
486
+
487
+ - ``column`` -- integer; the column used to split the problem into
488
+ independent subproblems
489
+
490
+ OUTPUT: dict where keys are row numbers and values are dlx solvers
491
+
492
+ EXAMPLES::
493
+
494
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
495
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
496
+ sage: d = dlx_solver(rows)
497
+ sage: d
498
+ Dancing links solver for 6 columns and 6 rows
499
+ sage: sorted(map(sorted, d.solutions_iterator()))
500
+ [[0, 1], [2, 3], [4, 5]]
501
+
502
+ After the split each subproblem has one more column and the same
503
+ number of rows as the original problem::
504
+
505
+ sage: D = d.split(0)
506
+ sage: D
507
+ {0: Dancing links solver for 7 columns and 6 rows,
508
+ 2: Dancing links solver for 7 columns and 6 rows,
509
+ 4: Dancing links solver for 7 columns and 6 rows}
510
+
511
+ The (disjoint) union of the solutions of the subproblems is equal to the
512
+ set of solutions shown above::
513
+
514
+ sage: for x in D.values(): sorted(map(sorted, x.solutions_iterator()))
515
+ [[0, 1]]
516
+ [[2, 3]]
517
+ [[4, 5]]
518
+
519
+ TESTS::
520
+
521
+ sage: d.split(6)
522
+ Traceback (most recent call last):
523
+ ...
524
+ ValueError: column(=6) must be in range(ncols) where ncols=6
525
+
526
+ This use to take a lot of time and memory. Not anymore since
527
+ :issue:`24315`::
528
+
529
+ sage: S = Subsets(range(11))
530
+ sage: rows = map(list, S)
531
+ sage: dlx = dlx_solver(rows)
532
+ sage: dlx
533
+ Dancing links solver for 11 columns and 2048 rows
534
+ sage: d = dlx.split(0)
535
+ sage: d[1]
536
+ Dancing links solver for 12 columns and 2048 rows
537
+ """
538
+ if not 0 <= column < self.ncols():
539
+ raise ValueError("column(={}) must be in range(ncols) "
540
+ "where ncols={}".format(column, self.ncols()))
541
+ indices = (i for i, row in enumerate(self._rows) if column in row)
542
+ return {i: self.restrict([i]) for i in indices}
543
+
544
+ def solutions_iterator(self):
545
+ r"""
546
+ Return an iterator of the solutions.
547
+
548
+ EXAMPLES::
549
+
550
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
551
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
552
+ sage: d = dlx_solver(rows)
553
+ sage: sorted(map(sorted, d.solutions_iterator()))
554
+ [[0, 1], [2, 3], [4, 5]]
555
+
556
+ TESTS:
557
+
558
+ The algorithm is automatically reinitialized if needed, for example
559
+ when iterating the solutions a second time (:issue:`25125`)::
560
+
561
+ sage: sorted(map(sorted, d.solutions_iterator()))
562
+ [[0, 1], [2, 3], [4, 5]]
563
+ """
564
+ if self._x.search_is_started():
565
+ self.reinitialize()
566
+ while self.search():
567
+ yield self.get_solution()
568
+
569
+ def one_solution(self, ncpus=None, column=None):
570
+ r"""
571
+ Return the first solution found.
572
+
573
+ This method allows parallel computations which might be useful for
574
+ some kind of problems when it is very hard just to find one
575
+ solution.
576
+
577
+ INPUT:
578
+
579
+ - ``ncpus`` -- integer (default: ``None``); maximal number of
580
+ subprocesses to use at the same time. If ``None``, it detects the
581
+ number of effective CPUs in the system using
582
+ :func:`sage.parallel.ncpus.ncpus()`.
583
+ If ``ncpus=1``, the first solution is searched serially.
584
+ - ``column`` -- integer (default: ``None``); the column used to split
585
+ the problem (see :meth:`restrict`). If ``None``, a random column
586
+ is chosen. This argument is ignored if ``ncpus=1``.
587
+
588
+ OUTPUT: list of rows or ``None`` if no solution is found
589
+
590
+ .. NOTE::
591
+
592
+ For some case, increasing the number of cpus makes it
593
+ faster. For other instances, ``ncpus=1`` is faster. It all
594
+ depends on problem which is considered.
595
+
596
+ EXAMPLES::
597
+
598
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
599
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
600
+ sage: d = dlx_solver(rows)
601
+ sage: solutions = [[0,1], [2,3], [4,5]]
602
+ sage: sorted(d.one_solution()) in solutions
603
+ True
604
+
605
+ The number of CPUs can be specified as input::
606
+
607
+ sage: sorted(d.one_solution(ncpus=2)) in solutions
608
+ True
609
+
610
+ The column used to split the problem for parallel computations can
611
+ be given::
612
+
613
+ sage: sorted(d.one_solution(ncpus=2, column=4)) in solutions
614
+ True
615
+
616
+ When no solution is found::
617
+
618
+ sage: rows = [[0,1,2], [2,3,4,5], [0,1,2,3]]
619
+ sage: d = dlx_solver(rows)
620
+ sage: d.one_solution() is None
621
+ True
622
+
623
+ TESTS::
624
+
625
+ sage: [d.one_solution(column=i) for i in range(6)]
626
+ [None, None, None, None, None, None]
627
+
628
+ The preprocess needed to start the parallel computation is not so
629
+ big (less than 50ms in the example below)::
630
+
631
+ sage: S = Subsets(range(11))
632
+ sage: rows = list(map(list, S))
633
+ sage: dlx = dlx_solver(rows)
634
+ sage: dlx
635
+ Dancing links solver for 11 columns and 2048 rows
636
+ sage: solution = dlx.one_solution()
637
+ sage: subsets = [set(rows[i]) for i in solution]
638
+
639
+ We make sure the solution is an exact cover::
640
+
641
+ sage: set.union(*subsets)
642
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
643
+ sage: from itertools import combinations
644
+ sage: any(p.intersection(q) for p,q in combinations(subsets, 2))
645
+ False
646
+ """
647
+ if ncpus == 1:
648
+ return self.get_solution() if self.search() else None
649
+
650
+ if column is None:
651
+ from random import randrange
652
+ column = randrange(self.ncols())
653
+
654
+ if not 0 <= column < self.ncols():
655
+ raise ValueError("column(={}) must be in range(ncols) "
656
+ "where ncols={}".format(column, self.ncols()))
657
+
658
+ from sage.parallel.decorate import parallel
659
+
660
+ @parallel(ncpus=ncpus)
661
+ def first_solution(i):
662
+ dlx = self.restrict([i])
663
+ if dlx.search():
664
+ return dlx.get_solution()
665
+ else:
666
+ return None
667
+
668
+ indices = [i for (i, row) in enumerate(self._rows) if column in row]
669
+ for (args_kwds, val) in first_solution(indices):
670
+ if val is not None:
671
+ return val
672
+
673
+ def all_solutions(self, ncpus=None, column=None):
674
+ r"""
675
+ Return all solutions found after splitting the problem to allow
676
+ parallel computation.
677
+
678
+ INPUT:
679
+
680
+ - ``ncpus`` -- integer (default: ``None``); maximal number of
681
+ subprocesses to use at the same time. If ``None``, it detects the
682
+ number of effective CPUs in the system using
683
+ :func:`sage.parallel.ncpus.ncpus()`.
684
+ - ``column`` -- integer (default: ``None``); the column used to split
685
+ the problem, if ``None`` a random column is chosen
686
+
687
+ OUTPUT: list of solutions
688
+
689
+ EXAMPLES::
690
+
691
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
692
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
693
+ sage: d = dlx_solver(rows)
694
+ sage: S = d.all_solutions()
695
+ sage: sorted(sorted(s) for s in S)
696
+ [[0, 1], [2, 3], [4, 5]]
697
+
698
+ The number of CPUs can be specified as input::
699
+
700
+ sage: S = Subsets(range(4))
701
+ sage: rows = map(list, S)
702
+ sage: dlx = dlx_solver(rows)
703
+ sage: dlx
704
+ Dancing links solver for 4 columns and 16 rows
705
+ sage: dlx.number_of_solutions()
706
+ 15
707
+ sage: sorted(sorted(s) for s in dlx.all_solutions(ncpus=2))
708
+ [[1, 2, 3, 4],
709
+ [1, 2, 10],
710
+ [1, 3, 9],
711
+ [1, 4, 8],
712
+ [1, 14],
713
+ [2, 3, 7],
714
+ [2, 4, 6],
715
+ [2, 13],
716
+ [3, 4, 5],
717
+ [3, 12],
718
+ [4, 11],
719
+ [5, 10],
720
+ [6, 9],
721
+ [7, 8],
722
+ [15]]
723
+
724
+ If ``ncpus=1``, the computation is not done in parallel::
725
+
726
+ sage: sorted(sorted(s) for s in dlx.all_solutions(ncpus=1))
727
+ [[1, 2, 3, 4],
728
+ [1, 2, 10],
729
+ [1, 3, 9],
730
+ [1, 4, 8],
731
+ [1, 14],
732
+ [2, 3, 7],
733
+ [2, 4, 6],
734
+ [2, 13],
735
+ [3, 4, 5],
736
+ [3, 12],
737
+ [4, 11],
738
+ [5, 10],
739
+ [6, 9],
740
+ [7, 8],
741
+ [15]]
742
+
743
+ TESTS:
744
+
745
+ When no solution is found::
746
+
747
+ sage: rows = [[0,1,2], [2,3,4,5], [0,1,2,3]]
748
+ sage: d = dlx_solver(rows)
749
+ sage: d.all_solutions()
750
+ []
751
+
752
+ ::
753
+
754
+ sage: [d.all_solutions(column=i) for i in range(6)]
755
+ [[], [], [], [], [], []]
756
+ """
757
+ if ncpus == 1:
758
+ if self._x.search_is_started():
759
+ self.reinitialize()
760
+ L = []
761
+ while self.search():
762
+ L.append(self.get_solution())
763
+ return L
764
+
765
+ if column is None:
766
+ from random import randrange
767
+ column = randrange(self.ncols())
768
+
769
+ if not 0 <= column < self.ncols():
770
+ raise ValueError("column(={}) must be in range(ncols) "
771
+ "where ncols={}".format(column, self.ncols()))
772
+
773
+ from sage.parallel.decorate import parallel
774
+
775
+ @parallel(ncpus=ncpus)
776
+ def all_solutions(i):
777
+ dlx = self.restrict([i])
778
+ L = []
779
+ while dlx.search():
780
+ L.append(dlx.get_solution())
781
+ return L
782
+
783
+ indices = [i for i, row in enumerate(self._rows) if column in row]
784
+ L = []
785
+ for (args_kwds, val) in all_solutions(indices):
786
+ L.extend(val)
787
+ return L
788
+
789
+ def number_of_solutions(self, ncpus=None, column=None):
790
+ r"""
791
+ Return the number of distinct solutions.
792
+
793
+ INPUT:
794
+
795
+ - ``ncpus`` -- integer (default: ``None``); maximal number of
796
+ subprocesses to use at the same time. If ``ncpus>1`` the dancing
797
+ links problem is split into independent subproblems to allow
798
+ parallel computation. If ``None``, it detects the number of
799
+ effective CPUs in the system using
800
+ :func:`sage.parallel.ncpus.ncpus()`.
801
+ - ``column`` -- integer (default: ``None``); the column used to split
802
+ the problem, if ``None`` a random column is chosen (this argument
803
+ is ignored if ``ncpus`` is ``1``)
804
+
805
+ OUTPUT: integer
806
+
807
+ EXAMPLES::
808
+
809
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
810
+ sage: rows = [[0,1,2]]
811
+ sage: rows += [[0,2]]
812
+ sage: rows += [[1]]
813
+ sage: rows += [[3]]
814
+ sage: x = dlx_solver(rows)
815
+ sage: x.number_of_solutions()
816
+ 2
817
+
818
+ The number of CPUs can be specified as input::
819
+
820
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
821
+ sage: x = dlx_solver(rows)
822
+ sage: x.number_of_solutions(ncpus=2, column=3)
823
+ 3
824
+
825
+ ::
826
+
827
+ sage: S = Subsets(range(5))
828
+ sage: rows = map(list, S)
829
+ sage: d = dlx_solver(rows)
830
+ sage: d.number_of_solutions()
831
+ 52
832
+
833
+ TESTS:
834
+
835
+ The algorithm is automatically reinitialized if needed, for example
836
+ when counting the number of solutions a second time (:issue:`25125`)::
837
+
838
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
839
+ sage: x = dlx_solver(rows)
840
+ sage: x.number_of_solutions(ncpus=1)
841
+ 3
842
+ sage: x.number_of_solutions(ncpus=1)
843
+ 3
844
+
845
+ Works with empty rows::
846
+
847
+ sage: dlx_solver([]).number_of_solutions(ncpus=None)
848
+ 0
849
+ sage: dlx_solver([]).number_of_solutions(ncpus=1)
850
+ 0
851
+ """
852
+ cdef int N = 0
853
+ if ncpus == 1:
854
+ if self._x.search_is_started():
855
+ self.reinitialize()
856
+ while self.search():
857
+ N += 1
858
+ return N
859
+
860
+ if self.ncols() == 0:
861
+ return 0
862
+
863
+ if column is None:
864
+ from random import randrange
865
+ column = randrange(self.ncols())
866
+
867
+ if not 0 <= column < self.ncols():
868
+ raise ValueError("column(={}) must be in range(ncols) "
869
+ "where ncols={}".format(column, self.ncols()))
870
+
871
+ from sage.parallel.decorate import parallel
872
+
873
+ @parallel(ncpus=ncpus)
874
+ def nb_sol(i):
875
+ dlx = self.restrict([i])
876
+ N = 0
877
+ while dlx.search():
878
+ N += 1
879
+ return N
880
+
881
+ indices = [i for i, row in enumerate(self._rows) if column in row]
882
+ return sum(val for (args_kwds, val) in nb_sol(indices))
883
+
884
+ @cached_method
885
+ def to_sat_solver(self, solver=None):
886
+ r"""
887
+ Return the SAT solver solving an equivalent problem.
888
+
889
+ Note that row index `i` in the dancing links solver corresponds to
890
+ the boolean variable index `ì+1` for the SAT solver to avoid
891
+ the variable index `0`.
892
+
893
+ See also :mod:`sage.sat.solvers.satsolver`.
894
+
895
+ INPUT:
896
+
897
+ - ``solver`` -- string or ``None`` (default: ``None``),
898
+ possible values include ``'picosat'``, ``'cryptominisat'``,
899
+ ``'LP'``, ``'glucose'``, ``'glucose-syrup'``.
900
+
901
+ OUTPUT: SAT solver instance
902
+
903
+ EXAMPLES::
904
+
905
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
906
+ sage: rows = [[0,1,2], [0,2], [1], [3]]
907
+ sage: x = dlx_solver(rows)
908
+ sage: s = x.to_sat_solver() # needs sage.numerical.mip sage.sat
909
+
910
+ Using some optional SAT solvers::
911
+
912
+ sage: x.to_sat_solver('cryptominisat') # optional - pycryptosat # needs sage.sat
913
+ CryptoMiniSat solver: 4 variables, 7 clauses.
914
+ """
915
+ from sage.sat.solvers.satsolver import SAT
916
+ s = SAT(solver)
917
+
918
+ # Note that row number i is associated to SAT variable i+1 to
919
+ # avoid a variable zero
920
+ columns = [[] for _ in range(self.ncols())]
921
+ for i, row in enumerate(self.rows(), start=1):
922
+ for a in row:
923
+ columns[a].append(i)
924
+
925
+ # At least one 1 in each column
926
+ for clause in columns:
927
+ s.add_clause(clause)
928
+
929
+ # At most one 1 in each column
930
+ import itertools
931
+ for clause in columns:
932
+ for p, q in itertools.combinations(clause, 2):
933
+ sub_clause = [-p, -q]
934
+ s.add_clause(sub_clause)
935
+
936
+ return s
937
+
938
+ def one_solution_using_sat_solver(self, solver=None):
939
+ r"""
940
+ Return a solution found using a SAT solver.
941
+
942
+ INPUT:
943
+
944
+ - ``solver`` -- string or ``None`` (default: ``None``),
945
+ possible values include ``'picosat'``, ``'cryptominisat'``,
946
+ ``'LP'``, ``'glucose'``, ``'glucose-syrup'``.
947
+
948
+ OUTPUT: list of rows or ``None`` if no solution is found
949
+
950
+ .. NOTE::
951
+
952
+ When comparing the time taken by method ``one_solution``,
953
+ have in mind that ``one_solution_using_sat_solver`` first
954
+ creates the SAT solver instance from the dancing links
955
+ solver. This copy of data may take many seconds depending on
956
+ the size of the problem.
957
+
958
+ EXAMPLES::
959
+
960
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
961
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
962
+ sage: d = dlx_solver(rows)
963
+ sage: solutions = [[0,1], [2,3], [4,5]]
964
+ sage: d.one_solution_using_sat_solver() in solutions # needs sage.numerical.mip sage.sat
965
+ True
966
+
967
+ Using optional solvers::
968
+
969
+ sage: s = d.one_solution_using_sat_solver('glucose') # optional - glucose, needs sage.sat
970
+ sage: s in solutions # optional - glucose, needs sage.sat
971
+ True
972
+
973
+ When no solution is found::
974
+
975
+ sage: rows = [[0,1,2], [2,3,4,5], [0,1,2,3]]
976
+ sage: d = dlx_solver(rows)
977
+ sage: d.one_solution_using_sat_solver() is None # needs sage.sat sage.numerical.mip
978
+ True
979
+ """
980
+ sat_solver = self.to_sat_solver(solver)
981
+ solution = sat_solver()
982
+ if not solution:
983
+ return None
984
+ return [key for key, val in enumerate(solution, start=-1) if val]
985
+
986
+ @cached_method
987
+ def to_milp(self, solver=None):
988
+ r"""
989
+ Return the mixed integer linear program (MILP) representing an
990
+ equivalent problem.
991
+
992
+ See also :mod:`sage.numerical.mip.MixedIntegerLinearProgram`.
993
+
994
+ INPUT:
995
+
996
+ - ``solver`` -- string or ``None`` (default: ``None``); possible
997
+ values include ``'GLPK'``, ``'GLPK/exact'``, ``'Coin'``,
998
+ ``'CPLEX'``, ``'Gurobi'``, ``'CVXOPT'``, ``'PPL'``,
999
+ ``'InteractiveLP'``
1000
+
1001
+ OUTPUT:
1002
+
1003
+ - MixedIntegerLinearProgram instance
1004
+ - MIPVariable with binary components
1005
+
1006
+ EXAMPLES::
1007
+
1008
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
1009
+ sage: rows = [[0,1,2], [0,2], [1], [3]]
1010
+ sage: d = dlx_solver(rows)
1011
+ sage: p,x = d.to_milp() # needs sage.numerical.mip
1012
+ sage: p # needs sage.numerical.mip
1013
+ Boolean Program (no objective, 4 variables, ... constraints)
1014
+ sage: x # needs sage.numerical.mip
1015
+ MIPVariable with 4 binary components
1016
+
1017
+ In the reduction, the boolean variable `x_i` is ``True`` if and only if
1018
+ the `i`-th row is in the solution::
1019
+
1020
+ sage: p.show() # needs sage.numerical.mip
1021
+ Maximization:
1022
+ <BLANKLINE>
1023
+ <BLANKLINE>
1024
+ Constraints:...
1025
+ one 1 in 0-th column: 1.0 <= x_0 + x_1 <= 1.0
1026
+ one 1 in 1-th column: 1.0 <= x_0 + x_2 <= 1.0
1027
+ one 1 in 2-th column: 1.0 <= x_0 + x_1 <= 1.0
1028
+ one 1 in 3-th column: 1.0 <= x_3 <= 1.0
1029
+ Variables:
1030
+ x_0 is a boolean variable (min=0.0, max=1.0)
1031
+ x_1 is a boolean variable (min=0.0, max=1.0)
1032
+ x_2 is a boolean variable (min=0.0, max=1.0)
1033
+ x_3 is a boolean variable (min=0.0, max=1.0)
1034
+
1035
+ Using some optional MILP solvers::
1036
+
1037
+ sage: d.to_milp('gurobi') # optional - gurobi sage_numerical_backends_gurobi, needs sage.numerical.mip
1038
+ (Boolean Program (no objective, 4 variables, 4 constraints),
1039
+ MIPVariable with 4 binary components)
1040
+ """
1041
+ from sage.numerical.mip import MixedIntegerLinearProgram
1042
+ p = MixedIntegerLinearProgram(solver=solver)
1043
+
1044
+ # x[i] == True iff i-th dlx row is in the solution
1045
+ x = p.new_variable(binary=True, indices=range(self.nrows()))
1046
+
1047
+ # Construction of the columns (transpose of the rows)
1048
+ columns = [[] for _ in range(self.ncols())]
1049
+ for i, row in enumerate(self.rows()):
1050
+ for a in row:
1051
+ columns[a].append(i)
1052
+
1053
+ # Constraints: exactly one 1 in each column
1054
+ for j, column in enumerate(columns):
1055
+ S = p.sum(x[a] for a in column)
1056
+ name = "one 1 in {}-th column".format(j)
1057
+ p.add_constraint(S == 1, name=name)
1058
+
1059
+ return p, x
1060
+
1061
+ def one_solution_using_milp_solver(self, solver=None, integrality_tolerance=1e-3):
1062
+ r"""
1063
+ Return a solution found using a MILP solver.
1064
+
1065
+ INPUT:
1066
+
1067
+ - ``solver`` -- string or ``None`` (default: ``None``); possible
1068
+ values include ``'GLPK'``, ``'GLPK/exact'``, ``'Coin'``,
1069
+ ``'CPLEX'``, ``'Gurobi'``, ``'CVXOPT'``, ``'PPL'``,
1070
+ ``'InteractiveLP'``
1071
+
1072
+ OUTPUT: list of rows or ``None`` if no solution is found
1073
+
1074
+ .. NOTE::
1075
+
1076
+ When comparing the time taken by method ``one_solution``, have in
1077
+ mind that ``one_solution_using_milp_solver`` first creates (and
1078
+ caches) the MILP solver instance from the dancing links solver.
1079
+ This copy of data may take many seconds depending on the size
1080
+ of the problem.
1081
+
1082
+ EXAMPLES::
1083
+
1084
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
1085
+ sage: rows = [[0,1,2], [3,4,5], [0,1], [2,3,4,5], [0], [1,2,3,4,5]]
1086
+ sage: d = dlx_solver(rows)
1087
+ sage: solutions = [[0,1], [2,3], [4,5]]
1088
+ sage: d.one_solution_using_milp_solver() in solutions # needs sage.numerical.mip
1089
+ True
1090
+
1091
+ Using optional solvers::
1092
+
1093
+ sage: # optional - gurobi sage_numerical_backends_gurobi, needs sage.numerical.mip
1094
+ sage: s = d.one_solution_using_milp_solver('gurobi')
1095
+ sage: s in solutions
1096
+ True
1097
+
1098
+ When no solution is found::
1099
+
1100
+ sage: rows = [[0,1,2], [2,3,4,5], [0,1,2,3]]
1101
+ sage: d = dlx_solver(rows)
1102
+ sage: d.one_solution_using_milp_solver() is None # needs sage.numerical.mip
1103
+ True
1104
+ """
1105
+ from sage.numerical.mip import MIPSolverException
1106
+ p, x = self.to_milp(solver)
1107
+ try:
1108
+ p.solve()
1109
+ except MIPSolverException:
1110
+ return None
1111
+
1112
+ soln = p.get_values(x, convert=bool, tolerance=integrality_tolerance)
1113
+ return sorted(key for key in soln if soln[key])
1114
+
1115
+
1116
+ def dlx_solver(rows):
1117
+ """
1118
+ Internal-use wrapper for the dancing links C++ code.
1119
+
1120
+ EXAMPLES::
1121
+
1122
+ sage: from sage.combinat.matrices.dancing_links import dlx_solver
1123
+ sage: rows = [[0,1,2]]
1124
+ sage: rows+= [[0,2]]
1125
+ sage: rows+= [[1]]
1126
+ sage: rows+= [[3]]
1127
+ sage: x = dlx_solver(rows)
1128
+ sage: print(x.search())
1129
+ 1
1130
+ sage: print(x.get_solution())
1131
+ [3, 0]
1132
+ sage: print(x.search())
1133
+ 1
1134
+ sage: print(x.get_solution())
1135
+ [3, 1, 2]
1136
+ sage: print(x.search())
1137
+ 0
1138
+ """
1139
+ return dancing_linksWrapper(rows)
1140
+
1141
+
1142
+ def make_dlxwrapper(s):
1143
+ """
1144
+ Create a dlx wrapper from a Python *string* s.
1145
+
1146
+ This was historically used in unpickling and is kept for backwards
1147
+ compatibility. We expect s to be ``dumps(rows)`` where rows is the
1148
+ list of rows used to instantiate the object.
1149
+
1150
+ TESTS::
1151
+
1152
+ sage: from sage.combinat.matrices.dancing_links import make_dlxwrapper
1153
+ sage: rows = [[0,1,2]]
1154
+ sage: x = make_dlxwrapper(dumps(rows))
1155
+ sage: print(x.__str__())
1156
+ Dancing links solver for 3 columns and 1 rows
1157
+ """
1158
+ from sage.misc.persist import loads
1159
+ return dancing_linksWrapper(loads(s))