passagemath-flint 10.6.1rc10__cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_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 (360) hide show
  1. passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
  2. passagemath_flint-10.6.1rc10.dist-info/RECORD +360 -0
  3. passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
  4. passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
  5. passagemath_flint.libs/libflint-3701249d.so.21.0.0 +0 -0
  6. passagemath_flint.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
  7. passagemath_flint.libs/libgfortran-8a9a71bc.so.5.0.0 +0 -0
  8. passagemath_flint.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  9. passagemath_flint.libs/libgsl-e3525837.so.28.0.0 +0 -0
  10. passagemath_flint.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
  11. passagemath_flint.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  12. passagemath_flint.libs/libntl-1004113e.so.44.0.1 +0 -0
  13. passagemath_flint.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  14. sage/all__sagemath_flint.py +29 -0
  15. sage/combinat/all__sagemath_flint.py +1 -0
  16. sage/combinat/posets/all__sagemath_flint.py +1 -0
  17. sage/combinat/posets/hasse_cython_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  18. sage/combinat/posets/hasse_cython_flint.pyx +194 -0
  19. sage/data_structures/all__sagemath_flint.py +1 -0
  20. sage/data_structures/bounded_integer_sequences.cpython-312-aarch64-linux-gnu.so +0 -0
  21. sage/data_structures/bounded_integer_sequences.pxd +62 -0
  22. sage/data_structures/bounded_integer_sequences.pyx +1418 -0
  23. sage/graphs/all__sagemath_flint.py +1 -0
  24. sage/graphs/chrompoly.cpython-312-aarch64-linux-gnu.so +0 -0
  25. sage/graphs/chrompoly.pyx +555 -0
  26. sage/graphs/matchpoly.cpython-312-aarch64-linux-gnu.so +0 -0
  27. sage/graphs/matchpoly.pyx +412 -0
  28. sage/libs/all__sagemath_flint.py +17 -0
  29. sage/libs/arb/__init__.py +1 -0
  30. sage/libs/arb/acb.pxd +154 -0
  31. sage/libs/arb/acb_calc.pxd +9 -0
  32. sage/libs/arb/acb_elliptic.pxd +25 -0
  33. sage/libs/arb/acb_hypgeom.pxd +74 -0
  34. sage/libs/arb/acb_mat.pxd +62 -0
  35. sage/libs/arb/acb_modular.pxd +17 -0
  36. sage/libs/arb/acb_poly.pxd +216 -0
  37. sage/libs/arb/arb.pxd +240 -0
  38. sage/libs/arb/arb_fmpz_poly.pxd +21 -0
  39. sage/libs/arb/arb_hypgeom.pxd +83 -0
  40. sage/libs/arb/arb_wrap.h +34 -0
  41. sage/libs/arb/arf.pxd +131 -0
  42. sage/libs/arb/arith.cpython-312-aarch64-linux-gnu.so +0 -0
  43. sage/libs/arb/arith.pyx +87 -0
  44. sage/libs/arb/bernoulli.pxd +6 -0
  45. sage/libs/arb/mag.pxd +77 -0
  46. sage/libs/arb/types.pxd +37 -0
  47. sage/libs/flint/__init__.py +1 -0
  48. sage/libs/flint/acb.pxd +270 -0
  49. sage/libs/flint/acb_calc.pxd +22 -0
  50. sage/libs/flint/acb_dft.pxd +51 -0
  51. sage/libs/flint/acb_dirichlet.pxd +112 -0
  52. sage/libs/flint/acb_elliptic.pxd +42 -0
  53. sage/libs/flint/acb_hypgeom.pxd +169 -0
  54. sage/libs/flint/acb_macros.pxd +9 -0
  55. sage/libs/flint/acb_mat.pxd +136 -0
  56. sage/libs/flint/acb_mat_macros.pxd +10 -0
  57. sage/libs/flint/acb_modular.pxd +62 -0
  58. sage/libs/flint/acb_poly.pxd +251 -0
  59. sage/libs/flint/acb_poly_macros.pxd +8 -0
  60. sage/libs/flint/acb_theta.pxd +124 -0
  61. sage/libs/flint/acf.pxd +32 -0
  62. sage/libs/flint/aprcl.pxd +84 -0
  63. sage/libs/flint/arb.pxd +382 -0
  64. sage/libs/flint/arb_calc.pxd +31 -0
  65. sage/libs/flint/arb_fmpz_poly.pxd +34 -0
  66. sage/libs/flint/arb_fpwrap.pxd +215 -0
  67. sage/libs/flint/arb_hypgeom.pxd +147 -0
  68. sage/libs/flint/arb_macros.pxd +9 -0
  69. sage/libs/flint/arb_mat.pxd +140 -0
  70. sage/libs/flint/arb_mat_macros.pxd +10 -0
  71. sage/libs/flint/arb_poly.pxd +237 -0
  72. sage/libs/flint/arf.pxd +167 -0
  73. sage/libs/flint/arith.cpython-312-aarch64-linux-gnu.so +0 -0
  74. sage/libs/flint/arith.pxd +76 -0
  75. sage/libs/flint/arith.pyx +77 -0
  76. sage/libs/flint/arith_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  77. sage/libs/flint/arith_sage.pyx +308 -0
  78. sage/libs/flint/bernoulli.pxd +28 -0
  79. sage/libs/flint/bool_mat.pxd +52 -0
  80. sage/libs/flint/ca.pxd +203 -0
  81. sage/libs/flint/ca_ext.pxd +34 -0
  82. sage/libs/flint/ca_field.pxd +32 -0
  83. sage/libs/flint/ca_mat.pxd +117 -0
  84. sage/libs/flint/ca_poly.pxd +104 -0
  85. sage/libs/flint/ca_vec.pxd +46 -0
  86. sage/libs/flint/calcium.pxd +27 -0
  87. sage/libs/flint/d_mat.pxd +39 -0
  88. sage/libs/flint/d_vec.pxd +32 -0
  89. sage/libs/flint/dirichlet.pxd +57 -0
  90. sage/libs/flint/dlog.pxd +53 -0
  91. sage/libs/flint/double_extras.pxd +24 -0
  92. sage/libs/flint/double_interval.pxd +36 -0
  93. sage/libs/flint/fexpr.pxd +104 -0
  94. sage/libs/flint/fexpr_builtin.pxd +20 -0
  95. sage/libs/flint/fft.pxd +66 -0
  96. sage/libs/flint/flint.pxd +36 -0
  97. sage/libs/flint/flint_ntl_wrap.h +35 -0
  98. sage/libs/flint/flint_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  99. sage/libs/flint/flint_sage.pyx +163 -0
  100. sage/libs/flint/flint_wrap.h +190 -0
  101. sage/libs/flint/fmpq.pxd +137 -0
  102. sage/libs/flint/fmpq_mat.pxd +105 -0
  103. sage/libs/flint/fmpq_mat_macros.pxd +10 -0
  104. sage/libs/flint/fmpq_mpoly.pxd +165 -0
  105. sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
  106. sage/libs/flint/fmpq_poly.pxd +241 -0
  107. sage/libs/flint/fmpq_poly_macros.pxd +9 -0
  108. sage/libs/flint/fmpq_poly_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  109. sage/libs/flint/fmpq_poly_sage.pxd +31 -0
  110. sage/libs/flint/fmpq_poly_sage.pyx +48 -0
  111. sage/libs/flint/fmpq_vec.pxd +27 -0
  112. sage/libs/flint/fmpz.pxd +256 -0
  113. sage/libs/flint/fmpz_extras.pxd +32 -0
  114. sage/libs/flint/fmpz_factor.pxd +42 -0
  115. sage/libs/flint/fmpz_factor_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  116. sage/libs/flint/fmpz_factor_sage.pxd +4 -0
  117. sage/libs/flint/fmpz_factor_sage.pyx +29 -0
  118. sage/libs/flint/fmpz_lll.pxd +49 -0
  119. sage/libs/flint/fmpz_macros.pxd +8 -0
  120. sage/libs/flint/fmpz_mat.pxd +184 -0
  121. sage/libs/flint/fmpz_mat_macros.pxd +10 -0
  122. sage/libs/flint/fmpz_mod.pxd +46 -0
  123. sage/libs/flint/fmpz_mod_mat.pxd +71 -0
  124. sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
  125. sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
  126. sage/libs/flint/fmpz_mod_poly.pxd +249 -0
  127. sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
  128. sage/libs/flint/fmpz_mod_vec.pxd +27 -0
  129. sage/libs/flint/fmpz_mpoly.pxd +224 -0
  130. sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
  131. sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
  132. sage/libs/flint/fmpz_poly.cpython-312-aarch64-linux-gnu.so +0 -0
  133. sage/libs/flint/fmpz_poly.pxd +407 -0
  134. sage/libs/flint/fmpz_poly.pyx +19 -0
  135. sage/libs/flint/fmpz_poly_factor.pxd +33 -0
  136. sage/libs/flint/fmpz_poly_macros.pxd +8 -0
  137. sage/libs/flint/fmpz_poly_mat.pxd +71 -0
  138. sage/libs/flint/fmpz_poly_q.pxd +55 -0
  139. sage/libs/flint/fmpz_poly_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  140. sage/libs/flint/fmpz_poly_sage.pxd +20 -0
  141. sage/libs/flint/fmpz_poly_sage.pyx +500 -0
  142. sage/libs/flint/fmpz_vec.pxd +80 -0
  143. sage/libs/flint/fmpzi.pxd +52 -0
  144. sage/libs/flint/fq.pxd +97 -0
  145. sage/libs/flint/fq_default.pxd +84 -0
  146. sage/libs/flint/fq_default_mat.pxd +70 -0
  147. sage/libs/flint/fq_default_poly.pxd +97 -0
  148. sage/libs/flint/fq_default_poly_factor.pxd +39 -0
  149. sage/libs/flint/fq_embed.pxd +28 -0
  150. sage/libs/flint/fq_mat.pxd +83 -0
  151. sage/libs/flint/fq_nmod.pxd +95 -0
  152. sage/libs/flint/fq_nmod_embed.pxd +28 -0
  153. sage/libs/flint/fq_nmod_mat.pxd +83 -0
  154. sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
  155. sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
  156. sage/libs/flint/fq_nmod_poly.pxd +202 -0
  157. sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
  158. sage/libs/flint/fq_nmod_vec.pxd +33 -0
  159. sage/libs/flint/fq_poly.pxd +204 -0
  160. sage/libs/flint/fq_poly_factor.pxd +47 -0
  161. sage/libs/flint/fq_vec.pxd +33 -0
  162. sage/libs/flint/fq_zech.pxd +99 -0
  163. sage/libs/flint/fq_zech_embed.pxd +28 -0
  164. sage/libs/flint/fq_zech_mat.pxd +78 -0
  165. sage/libs/flint/fq_zech_poly.pxd +198 -0
  166. sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
  167. sage/libs/flint/fq_zech_vec.pxd +33 -0
  168. sage/libs/flint/gr.pxd +174 -0
  169. sage/libs/flint/gr_generic.pxd +215 -0
  170. sage/libs/flint/gr_mat.pxd +161 -0
  171. sage/libs/flint/gr_mpoly.pxd +68 -0
  172. sage/libs/flint/gr_poly.pxd +276 -0
  173. sage/libs/flint/gr_special.pxd +237 -0
  174. sage/libs/flint/gr_vec.pxd +120 -0
  175. sage/libs/flint/hypgeom.pxd +24 -0
  176. sage/libs/flint/long_extras.pxd +23 -0
  177. sage/libs/flint/mag.pxd +131 -0
  178. sage/libs/flint/mag_macros.pxd +8 -0
  179. sage/libs/flint/mpf_mat.pxd +36 -0
  180. sage/libs/flint/mpf_vec.pxd +34 -0
  181. sage/libs/flint/mpfr_mat.pxd +27 -0
  182. sage/libs/flint/mpfr_vec.pxd +25 -0
  183. sage/libs/flint/mpn_extras.pxd +41 -0
  184. sage/libs/flint/mpoly.pxd +72 -0
  185. sage/libs/flint/nf.pxd +19 -0
  186. sage/libs/flint/nf_elem.pxd +74 -0
  187. sage/libs/flint/nmod.pxd +35 -0
  188. sage/libs/flint/nmod_mat.pxd +104 -0
  189. sage/libs/flint/nmod_mpoly.pxd +144 -0
  190. sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
  191. sage/libs/flint/nmod_poly.pxd +339 -0
  192. sage/libs/flint/nmod_poly_factor.pxd +44 -0
  193. sage/libs/flint/nmod_poly_linkage.pxi +710 -0
  194. sage/libs/flint/nmod_poly_mat.pxd +76 -0
  195. sage/libs/flint/nmod_vec.pxd +40 -0
  196. sage/libs/flint/ntl_interface.pxd +17 -0
  197. sage/libs/flint/padic.pxd +93 -0
  198. sage/libs/flint/padic_mat.pxd +64 -0
  199. sage/libs/flint/padic_poly.pxd +88 -0
  200. sage/libs/flint/partitions.pxd +23 -0
  201. sage/libs/flint/perm.pxd +26 -0
  202. sage/libs/flint/profiler.pxd +24 -0
  203. sage/libs/flint/qadic.pxd +77 -0
  204. sage/libs/flint/qfb.pxd +44 -0
  205. sage/libs/flint/qqbar.pxd +172 -0
  206. sage/libs/flint/qsieve.cpython-312-aarch64-linux-gnu.so +0 -0
  207. sage/libs/flint/qsieve.pxd +41 -0
  208. sage/libs/flint/qsieve.pyx +21 -0
  209. sage/libs/flint/qsieve_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  210. sage/libs/flint/qsieve_sage.pyx +67 -0
  211. sage/libs/flint/thread_pool.pxd +25 -0
  212. sage/libs/flint/types.pxd +2076 -0
  213. sage/libs/flint/ulong_extras.cpython-312-aarch64-linux-gnu.so +0 -0
  214. sage/libs/flint/ulong_extras.pxd +141 -0
  215. sage/libs/flint/ulong_extras.pyx +21 -0
  216. sage/libs/flint/ulong_extras_sage.cpython-312-aarch64-linux-gnu.so +0 -0
  217. sage/libs/flint/ulong_extras_sage.pyx +21 -0
  218. sage/matrix/all__sagemath_flint.py +1 -0
  219. sage/matrix/change_ring.cpython-312-aarch64-linux-gnu.so +0 -0
  220. sage/matrix/change_ring.pyx +43 -0
  221. sage/matrix/matrix_complex_ball_dense.cpython-312-aarch64-linux-gnu.so +0 -0
  222. sage/matrix/matrix_complex_ball_dense.pxd +14 -0
  223. sage/matrix/matrix_complex_ball_dense.pyx +973 -0
  224. sage/matrix/matrix_cyclo_dense.cpython-312-aarch64-linux-gnu.so +0 -0
  225. sage/matrix/matrix_cyclo_dense.pxd +16 -0
  226. sage/matrix/matrix_cyclo_dense.pyx +1761 -0
  227. sage/matrix/matrix_integer_dense.cpython-312-aarch64-linux-gnu.so +0 -0
  228. sage/matrix/matrix_integer_dense.pxd +32 -0
  229. sage/matrix/matrix_integer_dense.pyx +5801 -0
  230. sage/matrix/matrix_integer_dense_hnf.py +1294 -0
  231. sage/matrix/matrix_integer_dense_saturation.py +346 -0
  232. sage/matrix/matrix_integer_sparse.cpython-312-aarch64-linux-gnu.so +0 -0
  233. sage/matrix/matrix_integer_sparse.pxd +9 -0
  234. sage/matrix/matrix_integer_sparse.pyx +1090 -0
  235. sage/matrix/matrix_rational_dense.cpython-312-aarch64-linux-gnu.so +0 -0
  236. sage/matrix/matrix_rational_dense.pxd +23 -0
  237. sage/matrix/matrix_rational_dense.pyx +2995 -0
  238. sage/matrix/matrix_rational_sparse.cpython-312-aarch64-linux-gnu.so +0 -0
  239. sage/matrix/matrix_rational_sparse.pxd +11 -0
  240. sage/matrix/matrix_rational_sparse.pyx +789 -0
  241. sage/matrix/misc_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  242. sage/matrix/misc_flint.pyx +109 -0
  243. sage/modular/all__sagemath_flint.py +1 -0
  244. sage/modular/modform/all__sagemath_flint.py +1 -0
  245. sage/modular/modform/eis_series_cython.cpython-312-aarch64-linux-gnu.so +0 -0
  246. sage/modular/modform/eis_series_cython.pyx +226 -0
  247. sage/modular/modsym/all__sagemath_flint.py +1 -0
  248. sage/modular/modsym/apply.cpython-312-aarch64-linux-gnu.so +0 -0
  249. sage/modular/modsym/apply.pxd +6 -0
  250. sage/modular/modsym/apply.pyx +113 -0
  251. sage/modular/modsym/heilbronn.cpython-312-aarch64-linux-gnu.so +0 -0
  252. sage/modular/modsym/heilbronn.pyx +966 -0
  253. sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
  254. sage/modular/pollack_stevens/dist.cpython-312-aarch64-linux-gnu.so +0 -0
  255. sage/modular/pollack_stevens/dist.pxd +38 -0
  256. sage/modular/pollack_stevens/dist.pyx +1439 -0
  257. sage/quivers/algebra.py +691 -0
  258. sage/quivers/algebra_elements.cpython-312-aarch64-linux-gnu.so +0 -0
  259. sage/quivers/algebra_elements.pxd +97 -0
  260. sage/quivers/algebra_elements.pxi +1324 -0
  261. sage/quivers/algebra_elements.pyx +1424 -0
  262. sage/quivers/all.py +1 -0
  263. sage/quivers/ar_quiver.py +917 -0
  264. sage/quivers/homspace.py +640 -0
  265. sage/quivers/morphism.py +1282 -0
  266. sage/quivers/path_semigroup.py +1155 -0
  267. sage/quivers/paths.cpython-312-aarch64-linux-gnu.so +0 -0
  268. sage/quivers/paths.pxd +13 -0
  269. sage/quivers/paths.pyx +809 -0
  270. sage/quivers/representation.py +2975 -0
  271. sage/rings/all__sagemath_flint.py +37 -0
  272. sage/rings/cif.py +4 -0
  273. sage/rings/complex_arb.cpython-312-aarch64-linux-gnu.so +0 -0
  274. sage/rings/complex_arb.pxd +29 -0
  275. sage/rings/complex_arb.pyx +5176 -0
  276. sage/rings/complex_interval.cpython-312-aarch64-linux-gnu.so +0 -0
  277. sage/rings/complex_interval.pxd +30 -0
  278. sage/rings/complex_interval.pyx +2475 -0
  279. sage/rings/complex_interval_field.py +711 -0
  280. sage/rings/convert/all.py +1 -0
  281. sage/rings/convert/mpfi.cpython-312-aarch64-linux-gnu.so +0 -0
  282. sage/rings/convert/mpfi.pxd +6 -0
  283. sage/rings/convert/mpfi.pyx +576 -0
  284. sage/rings/factorint_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  285. sage/rings/factorint_flint.pyx +99 -0
  286. sage/rings/fraction_field_FpT.cpython-312-aarch64-linux-gnu.so +0 -0
  287. sage/rings/fraction_field_FpT.pxd +28 -0
  288. sage/rings/fraction_field_FpT.pyx +2043 -0
  289. sage/rings/imaginary_unit.py +5 -0
  290. sage/rings/monomials.py +73 -0
  291. sage/rings/number_field/S_unit_solver.py +2870 -0
  292. sage/rings/number_field/all__sagemath_flint.py +7 -0
  293. sage/rings/number_field/bdd_height.py +664 -0
  294. sage/rings/number_field/class_group.py +762 -0
  295. sage/rings/number_field/galois_group.py +1307 -0
  296. sage/rings/number_field/homset.py +612 -0
  297. sage/rings/number_field/maps.py +687 -0
  298. sage/rings/number_field/morphism.py +272 -0
  299. sage/rings/number_field/number_field.py +12820 -0
  300. sage/rings/number_field/number_field_element.cpython-312-aarch64-linux-gnu.so +0 -0
  301. sage/rings/number_field/number_field_element.pxd +59 -0
  302. sage/rings/number_field/number_field_element.pyx +5735 -0
  303. sage/rings/number_field/number_field_element_quadratic.cpython-312-aarch64-linux-gnu.so +0 -0
  304. sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
  305. sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
  306. sage/rings/number_field/number_field_ideal_rel.py +925 -0
  307. sage/rings/number_field/number_field_morphisms.cpython-312-aarch64-linux-gnu.so +0 -0
  308. sage/rings/number_field/number_field_morphisms.pyx +781 -0
  309. sage/rings/number_field/number_field_rel.py +2734 -0
  310. sage/rings/number_field/order.py +2981 -0
  311. sage/rings/number_field/order_ideal.py +804 -0
  312. sage/rings/number_field/selmer_group.py +715 -0
  313. sage/rings/number_field/small_primes_of_degree_one.py +242 -0
  314. sage/rings/number_field/splitting_field.py +606 -0
  315. sage/rings/number_field/structure.py +380 -0
  316. sage/rings/number_field/unit_group.py +721 -0
  317. sage/rings/padics/all__sagemath_flint.py +3 -0
  318. sage/rings/polynomial/all__sagemath_flint.py +1 -0
  319. sage/rings/polynomial/complex_roots.py +312 -0
  320. sage/rings/polynomial/evaluation_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  321. sage/rings/polynomial/evaluation_flint.pxd +7 -0
  322. sage/rings/polynomial/evaluation_flint.pyx +68 -0
  323. sage/rings/polynomial/hilbert.cpython-312-aarch64-linux-gnu.so +0 -0
  324. sage/rings/polynomial/hilbert.pyx +602 -0
  325. sage/rings/polynomial/polynomial_complex_arb.cpython-312-aarch64-linux-gnu.so +0 -0
  326. sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
  327. sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
  328. sage/rings/polynomial/polynomial_integer_dense_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  329. sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
  330. sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
  331. sage/rings/polynomial/polynomial_number_field.cpython-312-aarch64-linux-gnu.so +0 -0
  332. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  333. sage/rings/polynomial/polynomial_rational_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  334. sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
  335. sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
  336. sage/rings/polynomial/polynomial_zmod_flint.cpython-312-aarch64-linux-gnu.so +0 -0
  337. sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
  338. sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
  339. sage/rings/polynomial/real_roots.cpython-312-aarch64-linux-gnu.so +0 -0
  340. sage/rings/polynomial/real_roots.pxd +81 -0
  341. sage/rings/polynomial/real_roots.pyx +4704 -0
  342. sage/rings/polynomial/refine_root.cpython-312-aarch64-linux-gnu.so +0 -0
  343. sage/rings/polynomial/refine_root.pyx +142 -0
  344. sage/rings/polynomial/weil/all.py +4 -0
  345. sage/rings/polynomial/weil/power_sums.h +46 -0
  346. sage/rings/polynomial/weil/weil_polynomials.cpython-312-aarch64-linux-gnu.so +0 -0
  347. sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
  348. sage/rings/qqbar.py +9025 -0
  349. sage/rings/real_arb.cpython-312-aarch64-linux-gnu.so +0 -0
  350. sage/rings/real_arb.pxd +21 -0
  351. sage/rings/real_arb.pyx +4065 -0
  352. sage/rings/real_interval_absolute.cpython-312-aarch64-linux-gnu.so +0 -0
  353. sage/rings/real_interval_absolute.pyx +1073 -0
  354. sage/rings/real_mpfi.cpython-312-aarch64-linux-gnu.so +0 -0
  355. sage/rings/real_mpfi.pyx +5428 -0
  356. sage/schemes/all__sagemath_flint.py +1 -0
  357. sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
  358. sage/schemes/elliptic_curves/descent_two_isogeny.cpython-312-aarch64-linux-gnu.so +0 -0
  359. sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
  360. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,1155 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.graphs
3
+ """
4
+ Path Semigroups
5
+ """
6
+
7
+ # ****************************************************************************
8
+ # Copyright (C) 2012 Jim Stark <jstarx@gmail.com>
9
+ # 2013 Simon King <simon.king@uni-jena.de>
10
+ #
11
+ # Distributed under the terms of the GNU General Public License (GPL)
12
+ #
13
+ # This code is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty
15
+ # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
+ #
17
+ # See the GNU General Public License for more details; the full text
18
+ # is available at:
19
+ #
20
+ # https://www.gnu.org/licenses/
21
+ # ****************************************************************************
22
+
23
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
24
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
25
+ from sage.categories.monoids import Monoids
26
+ from sage.categories.semigroups import Semigroups
27
+ from sage.misc.cachefunc import cached_method
28
+ from sage.misc.lazy_attribute import lazy_attribute
29
+ from sage.rings.integer import Integer
30
+ from sage.rings.integer_ring import ZZ
31
+ from sage.structure.parent import Parent
32
+ from sage.structure.unique_representation import UniqueRepresentation
33
+
34
+ from .paths import QuiverPath
35
+ from .representation import QuiverRep
36
+
37
+ #########################
38
+ # Some auxiliary function to create generating functions to count paths.
39
+
40
+
41
+ class PathSemigroup(UniqueRepresentation, Parent):
42
+ r"""
43
+ The partial semigroup that is given by the directed paths of a quiver,
44
+ subject to concatenation.
45
+
46
+ See :mod:`~sage.quivers.representation` for a definition of this
47
+ semigroup and of the notion of a path in a quiver.
48
+
49
+ Note that a *partial semigroup* here is defined as a set `G` with a
50
+ partial binary operation `G \times G \to G \cup \{\mbox{None}\}`,
51
+ which is written infix as a `*` sign and satisfies associativity in
52
+ the following sense: If `a`, `b` and `c` are three elements of `G`,
53
+ and if one of the products `(a*b)*c` and `a*(b*c)` exists, then so
54
+ does the other and the two products are equal. A partial semigroup
55
+ is not required to have a neutral element (and this one usually has
56
+ no such element).
57
+
58
+ EXAMPLES::
59
+
60
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
61
+ sage: S = Q.path_semigroup()
62
+ sage: S
63
+ Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
64
+ sage: S.variable_names()
65
+ ('e_1', 'e_2', 'e_3', 'a', 'b', 'c', 'd')
66
+ sage: S.gens()
67
+ (e_1, e_2, e_3, a, b, c, d)
68
+ sage: S.category()
69
+ Category of finite enumerated semigroups
70
+
71
+ In the test suite, we skip the associativity test, as in this example the
72
+ paths used for testing cannot be concatenated::
73
+
74
+ sage: TestSuite(S).run(skip=['_test_associativity'])
75
+
76
+ If there is only a single vertex, the partial semigroup is a monoid. If
77
+ the underlying quiver has cycles or loops, then the (partial) semigroup
78
+ only is an infinite enumerated set. This time, there is no need to skip
79
+ tests::
80
+
81
+ sage: Q = DiGraph({1:{1:['a', 'b', 'c', 'd']}})
82
+ sage: M = Q.path_semigroup()
83
+ sage: M
84
+ Monoid formed by the directed paths of Looped multi-digraph on 1 vertex
85
+ sage: M.category()
86
+ Category of infinite enumerated monoids
87
+ sage: TestSuite(M).run()
88
+ """
89
+ Element = QuiverPath
90
+
91
+ @staticmethod
92
+ def __classcall__(cls, Q):
93
+ """
94
+ Normalize the arguments passed to the constructor.
95
+
96
+ The normalization consists of making an immutable copy of ``Q``
97
+ that is made weighted.
98
+
99
+ INPUT:
100
+
101
+ - ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph`
102
+
103
+ TESTS::
104
+
105
+ sage: G1 = DiGraph({1:{2:['a']}})
106
+ sage: G2 = DiGraph({1:{2:['b']}})
107
+ sage: P1 = G1.path_semigroup()
108
+ sage: P2 = G2.path_semigroup()
109
+ sage: G1 == G2 # equality of unweighted graphs ignores edge labels
110
+ True
111
+ sage: P1.quiver() == P2.quiver() # edge labels no longer ignored
112
+ False
113
+ sage: P1 == P2
114
+ False
115
+ """
116
+ # If self is immutable and weighted, then the copy is really cheap:
117
+ # __copy__ just returns self.
118
+ Q = Q.copy(immutable=True, weighted=True)
119
+ return super().__classcall__(cls, Q)
120
+
121
+ def __init__(self, Q):
122
+ """
123
+ Initialize ``self``.
124
+
125
+ INPUT:
126
+
127
+ - ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph`
128
+
129
+ EXAMPLES:
130
+
131
+ Note that usually a path semigroup is created using
132
+ :meth:`sage.graphs.digraph.DiGraph.path_semigroup`. Here, we
133
+ demonstrate the direct construction::
134
+
135
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}, immutable=True)
136
+ sage: from sage.quivers.path_semigroup import PathSemigroup
137
+ sage: P = PathSemigroup(Q)
138
+ sage: P is DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}).path_semigroup() # indirect doctest
139
+ True
140
+ sage: P
141
+ Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
142
+
143
+ While hardly of any use, it is possible to construct the path
144
+ semigroup of an empty quiver (it is, of course, empty)::
145
+
146
+ sage: D = DiGraph({})
147
+ sage: A = D.path_semigroup(); A
148
+ Partial semigroup formed by the directed paths of Digraph on 0 vertices
149
+ sage: A.list()
150
+ []
151
+
152
+ .. TODO::
153
+
154
+ When the graph has more than one edge, the proper category would be
155
+ a "partial semigroup" or a "semigroupoid" but definitely not a
156
+ semigroup!
157
+ """
158
+ #########
159
+ # Verify that the graph labels are acceptable for this implementation
160
+ # Check that edges are labelled with nonempty strings and do not begin
161
+ # with 'e_' or contain '*'
162
+ labels = Q.edge_labels()
163
+ if len(set(labels)) != len(labels):
164
+ raise ValueError("edge labels of the digraph must be unique")
165
+ for x in labels:
166
+ if not isinstance(x, str) or x == '':
167
+ raise ValueError("edge labels of the digraph must be nonempty strings")
168
+ if x[0:2] == 'e_':
169
+ raise ValueError("edge labels of the digraph must not begin with 'e_'")
170
+ if x.find('*') != -1:
171
+ raise ValueError("edge labels of the digraph must not contain '*'")
172
+
173
+ # Check validity of input: vertices have to be labelled 1,2,3,... and
174
+ # edge labels must be unique
175
+ for v in Q:
176
+ if not isinstance(v, (Integer, int)):
177
+ raise ValueError("vertices of the digraph must be labelled by integers")
178
+
179
+ # Determine the category which this (partial) semigroup belongs to
180
+ if Q.is_directed_acyclic():
181
+ cat = FiniteEnumeratedSets()
182
+ else:
183
+ cat = InfiniteEnumeratedSets()
184
+ self._sorted_edges = tuple(sorted(Q.edges(sort=True), key=lambda x: x[2]))
185
+ self._labels = tuple([x[2] for x in self._sorted_edges])
186
+ self._label_index = {s[2]: i for i, s in enumerate(self._sorted_edges)}
187
+ self._nb_arrows = max(len(self._sorted_edges), 1)
188
+ names = ['e_{0}'.format(v) for v in Q.vertex_iterator()]
189
+ names += list(self._labels)
190
+ self._quiver = Q
191
+ if Q.num_verts() == 1:
192
+ cat = cat.join([cat, Monoids()])
193
+ else:
194
+ cat = cat.join([cat, Semigroups()])
195
+ Parent.__init__(self, names=names, category=cat)
196
+
197
+ def _repr_(self):
198
+ """
199
+ String representation.
200
+
201
+ EXAMPLES::
202
+
203
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
204
+ sage: Q.path_semigroup()
205
+ Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
206
+ sage: Q = DiGraph({1:{1:['a','b', 'c', 'd']}})
207
+ sage: Q.path_semigroup()
208
+ Monoid formed by the directed paths of Looped multi-digraph on 1 vertex
209
+ """
210
+ if self._quiver.num_verts() != 1:
211
+ return "Partial semigroup formed by the directed paths of {}".format(self._quiver)
212
+ return "Monoid formed by the directed paths of {}".format(self._quiver)
213
+
214
+ def _coerce_map_from_(self, other):
215
+ """
216
+ A coercion from `A` to `B` exists if the underlying quiver
217
+ of `A` is a sub-quiver of the underlying quiver of `B` (preserving
218
+ names).
219
+
220
+ EXAMPLES::
221
+
222
+ sage: Q1 = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
223
+ sage: Q2 = DiGraph({1:{2:['a'], 3:['c']}})
224
+ sage: Q3 = DiGraph({1:{2:['a','x'], 3:['c']}, 3:{1:['d']}})
225
+ sage: P1 = Q1.path_semigroup()
226
+ sage: P2 = Q2.path_semigroup()
227
+ sage: P3 = Q3.path_semigroup()
228
+ sage: P1.has_coerce_map_from(P2) # indirect doctest
229
+ True
230
+ sage: P1.has_coerce_map_from(P3)
231
+ False
232
+ sage: d = P1([(3,1,'d')]); d
233
+ d
234
+ sage: c = P2([(1,3,'c')]); c
235
+ c
236
+ sage: c.parent() is P1
237
+ False
238
+ sage: c in P1 # indirect doctest
239
+ True
240
+ sage: d*c # indirect doctest
241
+ d*c
242
+ sage: (d*c).parent() is P1
243
+ True
244
+ sage: c3 = P3([(1,3,'c')]); c3
245
+ c
246
+ sage: c3 in P1 # indirect doctest
247
+ False
248
+ sage: d*c3
249
+ Traceback (most recent call last):
250
+ ...
251
+ TypeError: unsupported operand parent(s) for *:
252
+ 'Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices'
253
+ and 'Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices'
254
+ """
255
+ if not isinstance(other, PathSemigroup):
256
+ return
257
+ # This is what we would like to do:
258
+ # return other.quiver().is_subgraph(self._quiver, induced=False)
259
+ # However, this is deprecated for non-induced subgraphs
260
+ # of directed multi-graphs.
261
+ #
262
+ # We ignore the deprecation and do what the deprecated method is doing
263
+ # internally, directly using the backend to make things faster.
264
+ sQ = self._quiver._backend
265
+ oQ = other.quiver()._backend
266
+ if sQ.num_verts() < oQ.num_verts():
267
+ return False
268
+ if any(not sQ.has_vertex(v) for v in oQ.iterator_verts(None)):
269
+ return False
270
+ return all(sQ.has_edge(*e) for e in oQ.iterator_out_edges(oQ.iterator_verts(None), True))
271
+
272
+ def _element_constructor_(self, data, check=True):
273
+ """
274
+ The accepted data are:
275
+
276
+ - the integer ``1``, which returns the first idempotent,
277
+ - a list, whose only item is a tuple ``(v,v)`` for a vertex ``v``,
278
+ - a list of edge labels,
279
+ - a single edge label,
280
+ - a list of triples ``(v, w, s)`` that are edges of the underlying quiver, or
281
+ - an element of another path semigroup.
282
+
283
+ EXAMPLES::
284
+
285
+ sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
286
+ sage: P(1)
287
+ e_1
288
+ sage: P([(3,3)])
289
+ e_3
290
+ sage: P(['c','d'])
291
+ c*d
292
+ sage: P('c')
293
+ c
294
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d'], 2:['e']}}).path_semigroup()
295
+ sage: Q([(1,3,'c'), (3,1,'d'), (1,2,'b')])
296
+ c*d*b
297
+ sage: Q(P(['c','d']))
298
+ c*d
299
+
300
+ A :exc:`TypeError` or a :exc:`ValueError` is raised appropriately
301
+ if the input is wrong::
302
+
303
+ sage: G = DiGraph([(0,0,'a'), (0,1,'b'), (1,0,'c')], loops=True)
304
+ sage: P = G.path_semigroup()
305
+
306
+ sage: P([(0,0)])
307
+ e_0
308
+ sage: P([(2,2)])
309
+ Traceback (most recent call last):
310
+ ...
311
+ ValueError: startpoint 2 should belong to [0, 1]
312
+ sage: P([(0,1,'a'),(1,0,'b')])
313
+ Traceback (most recent call last):
314
+ ...
315
+ ValueError: (0, 1, 'a') is not an edge
316
+ sage: P('d')
317
+ Traceback (most recent call last):
318
+ ...
319
+ ValueError: data='d' is not the label of an edge
320
+ sage: P([(0,0,'a'),(0,1,2,3)])
321
+ Traceback (most recent call last):
322
+ ...
323
+ ValueError: each edge must be a triple, got (0, 1, 2, 3)
324
+ sage: P(18)
325
+ Traceback (most recent call last):
326
+ ...
327
+ TypeError: data=18 is not valid. A path must be initialized from
328
+ either a tuple or a list
329
+ """
330
+ L = self._label_index
331
+ E = self._sorted_edges
332
+ if isinstance(data, QuiverPath):
333
+ if data.parent() is self:
334
+ return data
335
+ start = data.initial_vertex()
336
+ end = data.terminal_vertex()
337
+ edge_index = {e: i for i, e in enumerate(E)}
338
+ path = [edge_index.get(e) for e in data]
339
+ elif not data:
340
+ raise ValueError("no data given to define this path")
341
+ elif data == 1:
342
+ start = end = next(self._quiver.vertex_iterator())
343
+ path = []
344
+ elif isinstance(data, str): # one edge
345
+ i = L.get(data, None)
346
+ if i is None:
347
+ raise ValueError("data={!r} is not the label of an edge".format(data))
348
+ start, end, _ = E[i]
349
+ path = [i]
350
+ elif not isinstance(data, (tuple, list)):
351
+ raise TypeError("data={} is not valid. A path must be initialized from either a tuple or a list".format(data))
352
+ elif isinstance(data[0], str): # a list of labels
353
+ start = L.get(data[0])
354
+ if start is None:
355
+ raise ValueError("data[0]={!r} is not the label of an edge".format(data[0]))
356
+ start = E[start][0]
357
+ end = L.get(data[-1])
358
+ if end is None:
359
+ raise ValueError("data[-1]={!r} is not the label of an edge".format(data[-1]))
360
+ end = E[end][1]
361
+ path = [L.get(e) for e in data]
362
+ elif len(data) == 1 and len(data[0]) == 2: # an idempotent
363
+ start = data[0][0]
364
+ end = data[0][1]
365
+ path = []
366
+ else: # a list of edges
367
+ if any(len(x) != 3 for x in data):
368
+ x = next(x for x in data if len(x) != 3)
369
+ raise ValueError("each edge must be a triple, got {}".format(x))
370
+ start = data[0][0]
371
+ end = data[-1][1]
372
+ edge_index = {e: i for i, e in enumerate(E)}
373
+ path = [edge_index.get(e) for e in data]
374
+
375
+ if check:
376
+ Q = self._quiver
377
+ if start is None or start not in Q:
378
+ raise ValueError("startpoint {} should belong to {}".format(start, Q.vertices(sort=False)))
379
+ if end is None or end not in Q:
380
+ raise ValueError("endpoint {} should belong to {}".format(end, Q.vertices(sort=False)))
381
+ if not path:
382
+ if start != end:
383
+ raise ValueError("start and endpoint of a path of length 0 must coincide")
384
+ else:
385
+ if any(x is None for x in path):
386
+ i = next((i for i, x in enumerate(path) if x is None))
387
+ raise ValueError("{} is not an edge".format(data[i]))
388
+ for n in range(1, len(path)):
389
+ e0 = E[path[n - 1]][1]
390
+ e1 = E[path[n]][0]
391
+ if e0 != e1:
392
+ raise ValueError("edge {} ends at {}, but edge {} starts at {}".format(
393
+ E[path[n - 1]][2], e0, E[path[n]][2], e1))
394
+ if E[path[0]][0] != start:
395
+ raise ValueError("first edge should start at vertex {}".format(start))
396
+ if E[path[-1]][1] != end:
397
+ raise ValueError("last edge should end at vertex {}".format(end))
398
+
399
+ return self.element_class(self, start, end, path)
400
+
401
+ @cached_method
402
+ def arrows(self):
403
+ """
404
+ Return the elements corresponding to edges of the underlying quiver.
405
+
406
+ EXAMPLES::
407
+
408
+ sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
409
+ sage: P.arrows()
410
+ (a, b, c, d)
411
+ """
412
+ return tuple(self.element_class(self, e[0], e[1], [i])
413
+ for i, e in enumerate(self._sorted_edges))
414
+
415
+ @cached_method
416
+ def idempotents(self):
417
+ """
418
+ Return the idempotents corresponding to the vertices of the
419
+ underlying quiver.
420
+
421
+ EXAMPLES::
422
+
423
+ sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
424
+ sage: P.idempotents()
425
+ (e_1, e_2, e_3)
426
+ """
427
+ return tuple(self.element_class(self, v, v, [])
428
+ for v in self._quiver.vertex_iterator())
429
+
430
+ def ngens(self):
431
+ """
432
+ Return the number of generators (:meth:`arrows` and
433
+ :meth:`idempotents`).
434
+
435
+ EXAMPLES::
436
+
437
+ sage: F = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
438
+ sage: F.ngens()
439
+ 7
440
+ """
441
+ Q = self._quiver
442
+ return Q.num_verts() + Q.num_edges()
443
+
444
+ @cached_method
445
+ def gen(self, i):
446
+ """
447
+ Return generator number `i`.
448
+
449
+ INPUT:
450
+
451
+ - ``i`` -- integer
452
+
453
+ OUTPUT:
454
+
455
+ An idempotent, if `i` is smaller than the number of vertices,
456
+ or an arrow otherwise.
457
+
458
+ EXAMPLES::
459
+
460
+ sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
461
+ sage: P.1 # indirect doctest
462
+ e_2
463
+ sage: P.idempotents()[1]
464
+ e_2
465
+ sage: P.5
466
+ c
467
+ sage: P.gens()[5]
468
+ c
469
+ """
470
+ return self.gens()[i]
471
+
472
+ @cached_method
473
+ def gens(self) -> tuple:
474
+ """
475
+ Return the tuple of generators.
476
+
477
+ .. NOTE::
478
+
479
+ This coincides with the sum of the output of
480
+ :meth:`idempotents` and :meth:`arrows`.
481
+
482
+ EXAMPLES::
483
+
484
+ sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
485
+ sage: P.gens()
486
+ (e_1, e_2, e_3, a, b, c, d)
487
+ sage: P.gens() == P.idempotents() + P.arrows()
488
+ True
489
+ """
490
+ return self.idempotents() + self.arrows()
491
+
492
+ def is_finite(self) -> bool:
493
+ """
494
+ This partial semigroup is finite if and only if the underlying
495
+ quiver is acyclic.
496
+
497
+ EXAMPLES::
498
+
499
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
500
+ sage: Q.path_semigroup().is_finite()
501
+ True
502
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
503
+ sage: Q.path_semigroup().is_finite()
504
+ False
505
+ """
506
+ return self._quiver.is_directed_acyclic() and not self._quiver.has_loops()
507
+
508
+ def __len__(self):
509
+ """
510
+ EXAMPLES::
511
+
512
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
513
+ sage: F = Q.path_semigroup()
514
+ sage: len(F)
515
+ 9
516
+ sage: list(F)
517
+ [e_1, e_2, e_3, a, b, c, d, a*d, b*d]
518
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
519
+ sage: F = Q.path_semigroup()
520
+ sage: len(F)
521
+ Traceback (most recent call last):
522
+ ...
523
+ ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
524
+ """
525
+ return len(self.all_paths())
526
+
527
+ def cardinality(self):
528
+ """
529
+ EXAMPLES::
530
+
531
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
532
+ sage: F = Q.path_semigroup()
533
+ sage: F.cardinality()
534
+ 9
535
+ sage: A = F.algebra(QQ)
536
+ sage: list(A.basis())
537
+ [e_1, e_2, e_3, a, b, c, d, a*d, b*d]
538
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
539
+ sage: F = Q.path_semigroup()
540
+ sage: F.cardinality()
541
+ +Infinity
542
+ sage: A = F.algebra(QQ)
543
+ sage: list(A.basis())
544
+ Traceback (most recent call last):
545
+ ...
546
+ ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
547
+ """
548
+ from sage.rings.integer_ring import ZZ
549
+ if self._quiver.is_directed_acyclic() and not self._quiver.has_loops():
550
+ return ZZ(len(self))
551
+ from sage.rings.infinity import Infinity
552
+ return Infinity
553
+
554
+ def __iter__(self):
555
+ """
556
+ Iterate over the elements of ``self``, i.e., over quiver paths.
557
+
558
+ EXAMPLES::
559
+
560
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
561
+ sage: P = Q.path_semigroup()
562
+ sage: list(P)
563
+ [e_1, e_2, e_3, a, b, c, d, a*d, b*d]
564
+
565
+ The elements are sorted by length. Of course, the list of elements
566
+ is infinite for quivers with cycles. ::
567
+
568
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
569
+ sage: P = Q.path_semigroup()
570
+ sage: P.is_finite()
571
+ False
572
+ sage: list(P)
573
+ Traceback (most recent call last):
574
+ ...
575
+ ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
576
+
577
+ However, one can iterate::
578
+
579
+ sage: counter = 0
580
+ sage: for p in P:
581
+ ....: counter += 1
582
+ ....: print(p)
583
+ ....: if counter==20:
584
+ ....: break
585
+ e_1
586
+ e_2
587
+ e_3
588
+ a
589
+ b
590
+ d
591
+ c
592
+ a*d
593
+ b*d
594
+ d*c
595
+ c*a
596
+ c*b
597
+ a*d*c
598
+ b*d*c
599
+ d*c*a
600
+ d*c*b
601
+ c*a*d
602
+ c*b*d
603
+ a*d*c*a
604
+ a*d*c*b
605
+ """
606
+ d = 0
607
+ length_d_available = True
608
+ while length_d_available:
609
+ length_d_available = False
610
+ for v in self._quiver.vertex_iterator():
611
+ for w in self.iter_paths_by_length_and_startpoint(d, v):
612
+ length_d_available = True
613
+ yield w
614
+ d += 1
615
+
616
+ def iter_paths_by_length_and_startpoint(self, d, v):
617
+ """
618
+ An iterator over quiver paths with a fixed length and start point.
619
+
620
+ INPUT:
621
+
622
+ - ``d`` -- integer; the path length
623
+ - ``v`` -- a vertex; start point of the paths
624
+
625
+ EXAMPLES::
626
+
627
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
628
+ sage: P = Q.path_semigroup()
629
+ sage: P.is_finite()
630
+ False
631
+ sage: list(P.iter_paths_by_length_and_startpoint(4,1))
632
+ [a*d*c*a, a*d*c*b, b*d*c*a, b*d*c*b]
633
+ sage: list(P.iter_paths_by_length_and_startpoint(5,1))
634
+ [a*d*c*a*d, a*d*c*b*d, b*d*c*a*d, b*d*c*b*d]
635
+ sage: list(P.iter_paths_by_length_and_startpoint(5,2))
636
+ [d*c*a*d*c, d*c*b*d*c]
637
+
638
+ TESTS::
639
+
640
+ sage: Q = DiGraph({1:{1:['a','b', 'c', 'd']}})
641
+ sage: P = Q.path_semigroup()
642
+ sage: list(P.iter_paths_by_length_and_startpoint(2,1))
643
+ [a*a,
644
+ a*b,
645
+ a*c,
646
+ a*d,
647
+ b*a,
648
+ b*b,
649
+ b*c,
650
+ b*d,
651
+ c*a,
652
+ c*b,
653
+ c*c,
654
+ c*d,
655
+ d*a,
656
+ d*b,
657
+ d*c,
658
+ d*d]
659
+ sage: len(list(P.iter_paths_by_length_and_startpoint(2,1)))
660
+ 16
661
+ """
662
+ # iterate over length d paths starting at vertex v
663
+ if not d >= 0:
664
+ raise ValueError("path length must be a nonnegative integer")
665
+ if v not in self._quiver:
666
+ raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v))
667
+ if not d:
668
+ yield self.element_class(self, v, v, [])
669
+ else:
670
+ for w in self.iter_paths_by_length_and_startpoint(d - 1, v):
671
+ for a in self._quiver._backend.iterator_out_edges([w.terminal_vertex()], True):
672
+ yield self(list(w) + [a], check=False)
673
+
674
+ def iter_paths_by_length_and_endpoint(self, d, v):
675
+ """
676
+ An iterator over quiver paths with a fixed length and end point.
677
+
678
+ INPUT:
679
+
680
+ - ``d`` -- integer; the path length
681
+ - ``v`` -- a vertex; end point of the paths
682
+
683
+ EXAMPLES::
684
+
685
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
686
+ sage: F = Q.path_semigroup()
687
+ sage: F.is_finite()
688
+ False
689
+ sage: list(F.iter_paths_by_length_and_endpoint(4,1))
690
+ [c*a*d*c, c*b*d*c]
691
+ sage: list(F.iter_paths_by_length_and_endpoint(5,1))
692
+ [d*c*a*d*c, d*c*b*d*c]
693
+ sage: list(F.iter_paths_by_length_and_endpoint(5,2))
694
+ [c*a*d*c*a, c*b*d*c*a, c*a*d*c*b, c*b*d*c*b]
695
+ """
696
+ # iterate over length d paths ending at vertex v
697
+ if not d >= 0:
698
+ raise ValueError("path length must be a nonnegative integer")
699
+ if v not in self._quiver:
700
+ raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v))
701
+ if not d:
702
+ yield self.element_class(self, v, v, [])
703
+ else:
704
+ for w in self.iter_paths_by_length_and_endpoint(d - 1, v):
705
+ for a in self._quiver._backend.iterator_in_edges([w.initial_vertex()], True):
706
+ yield self([a] + list(w), check=False)
707
+
708
+ def quiver(self):
709
+ """
710
+ Return the underlying quiver (i.e., digraph) of this path semigroup.
711
+
712
+ .. NOTE::
713
+
714
+ The returned digraph always is an immutable copy of the originally
715
+ given digraph that is made weighted.
716
+
717
+ EXAMPLES::
718
+
719
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}},
720
+ ....: weighted=False)
721
+ sage: F = Q.path_semigroup()
722
+ sage: F.quiver() == Q
723
+ False
724
+ sage: Q.weighted(True)
725
+ sage: F.quiver() == Q
726
+ True
727
+ """
728
+ return self._quiver
729
+
730
+ @cached_method
731
+ def reverse(self):
732
+ """
733
+ The path semigroup of the reverse quiver.
734
+
735
+ EXAMPLES::
736
+
737
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
738
+ sage: F = Q.path_semigroup()
739
+ sage: F.reverse() is Q.reverse().path_semigroup()
740
+ True
741
+ """
742
+ return self._quiver.reverse().path_semigroup()
743
+
744
+ def algebra(self, k, order='negdegrevlex'):
745
+ """
746
+ Return the path algebra of the underlying quiver.
747
+
748
+ INPUT:
749
+
750
+ - ``k`` -- a commutative ring
751
+
752
+ - ``order`` -- (optional) string, one of ``'negdegrevlex'`` (default),
753
+ ``'degrevlex'``, ``'negdeglex'`` or ``'deglex'``, defining the
754
+ monomial order to be used
755
+
756
+ .. NOTE::
757
+
758
+ Monomial orders that are not degree orders are not supported.
759
+
760
+ EXAMPLES::
761
+
762
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
763
+ sage: P = Q.path_semigroup()
764
+ sage: P.algebra(GF(3))
765
+ Path algebra of Multi-digraph on 3 vertices over Finite Field of size 3
766
+
767
+ Now some example with different monomial orderings::
768
+
769
+ sage: P1 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'))
770
+ sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex')
771
+ sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='negdeglex')
772
+ sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='deglex')
773
+ sage: P1.order_string()
774
+ 'negdegrevlex'
775
+ sage: sage_eval('(x+2*z+1)^3', P1.gens_dict())
776
+ e_1 + z + 3*x + 2*z*z + x*z + z*x + 3*x*x + 3*z*z*z + 4*x*z*z + 4*z*x*z + 2*x*x*z + 4*z*z*x + 2*x*z*x + 2*z*x*x + x*x*x
777
+ sage: sage_eval('(x+2*z+1)^3', P2.gens_dict())
778
+ 3*z*z*z + 4*x*z*z + 4*z*x*z + 2*x*x*z + 4*z*z*x + 2*x*z*x + 2*z*x*x + x*x*x + 2*z*z + x*z + z*x + 3*x*x + z + 3*x + e_1
779
+ sage: sage_eval('(x+2*z+1)^3', P3.gens_dict())
780
+ e_1 + z + 3*x + 2*z*z + z*x + x*z + 3*x*x + 3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x
781
+ sage: sage_eval('(x+2*z+1)^3', P4.gens_dict())
782
+ 3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x + 2*z*z + z*x + x*z + 3*x*x + z + 3*x + e_1
783
+ """
784
+ from sage.quivers.algebra import PathAlgebra
785
+ return PathAlgebra(k, self, order)
786
+
787
+ ###########################################################################
788
+ # #
789
+ # REPRESENTATION THEORETIC FUNCTIONS #
790
+ # These functions involve the representation theory of quivers. #
791
+ # #
792
+ ###########################################################################
793
+
794
+ def representation(self, k, *args, **kwds):
795
+ """
796
+ Return a representation of the quiver.
797
+
798
+ For more information see the
799
+ :class:`~sage.quivers.representation.QuiverRep` documentation.
800
+
801
+ TESTS::
802
+
803
+ sage: Q = DiGraph({1:{3:['a']}, 2:{3:['b']}}).path_semigroup()
804
+ sage: spaces = {1: QQ^2, 2: QQ^3, 3: QQ^2}
805
+ sage: maps = {(1, 3, 'a'): (QQ^2).Hom(QQ^2).identity(), (2, 3, 'b'): [[1, 0], [0, 0], [0, 0]]}
806
+ sage: M = Q.representation(QQ, spaces, maps)
807
+ sage: M
808
+ Representation with dimension vector (2, 3, 2)
809
+ """
810
+ return QuiverRep(k, self, *args, **kwds)
811
+
812
+ def S(self, k, vertex):
813
+ """
814
+ Return the simple module over `k` at the given vertex
815
+ ``vertex``.
816
+
817
+ This module is literally simple only when `k` is a field.
818
+
819
+ INPUT:
820
+
821
+ - ``k`` -- the base ring of the representation
822
+
823
+ - ``vertex`` -- integer; a vertex of the quiver
824
+
825
+ OUTPUT: :class:`~sage.quivers.representation.QuiverRep`; the simple
826
+ module at ``vertex`` with base ring `k`
827
+
828
+ EXAMPLES::
829
+
830
+ sage: P = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
831
+ sage: S1 = P.S(GF(3), 1)
832
+ sage: P.S(ZZ, 3).dimension_vector()
833
+ (0, 0, 1)
834
+ sage: P.S(ZZ, 1).dimension_vector()
835
+ (1, 0, 0)
836
+
837
+ The vertex given must be a vertex of the quiver::
838
+
839
+ sage: P.S(QQ, 4)
840
+ Traceback (most recent call last):
841
+ ...
842
+ ValueError: must specify a valid vertex of the quiver
843
+ """
844
+ if vertex not in self._quiver:
845
+ raise ValueError("must specify a valid vertex of the quiver")
846
+
847
+ # This is the module with k at the given vertex and zero elsewhere. As
848
+ # all maps are zero we only need to specify that the given vertex has
849
+ # dimension 1 and the constructor will zero out everything else.
850
+ return QuiverRep(k, self, {vertex: 1})
851
+
852
+ simple = S
853
+
854
+ def P(self, k, vertex):
855
+ """
856
+ Return the indecomposable projective module over `k` at the given
857
+ vertex ``vertex``.
858
+
859
+ This module is literally indecomposable only when `k` is a field.
860
+
861
+ INPUT:
862
+
863
+ - ``k`` -- the base ring of the representation
864
+
865
+ - ``vertex`` -- integer; a vertex of the quiver
866
+
867
+ OUTPUT: :class:`~sage.quivers.representation.QuiverRep`, the
868
+ indecomposable projective module at ``vertex`` with base ring `k`
869
+
870
+ EXAMPLES::
871
+
872
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
873
+ sage: P2 = Q.P(GF(3), 2)
874
+ sage: Q.P(ZZ, 3).dimension_vector()
875
+ (0, 0, 1)
876
+ sage: Q.P(ZZ, 1).dimension_vector()
877
+ (1, 2, 4)
878
+
879
+ The vertex given must be a vertex of the quiver::
880
+
881
+ sage: Q.P(QQ, 4)
882
+ Traceback (most recent call last):
883
+ ...
884
+ ValueError: must specify a valid vertex of the quiver
885
+ """
886
+ if vertex not in self._quiver:
887
+ raise ValueError("must specify a valid vertex of the quiver")
888
+ return QuiverRep(k, self, [[(vertex, vertex)]], option='paths')
889
+
890
+ projective = P
891
+
892
+ def I(self, k, vertex):
893
+ """
894
+ Return the indecomposable injective module over `k` at the
895
+ given vertex ``vertex``.
896
+
897
+ This module is literally indecomposable only when `k` is a field.
898
+
899
+ INPUT:
900
+
901
+ - ``k`` -- the base ring of the representation
902
+
903
+ - ``vertex`` -- integer; a vertex of the quiver
904
+
905
+ OUTPUT:
906
+
907
+ - :class:`~sage.quivers.representation.QuiverRep`, the indecomposable
908
+ injective module at vertex ``vertex`` with base ring `k`
909
+
910
+ EXAMPLES::
911
+
912
+ sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
913
+ sage: I2 = Q.I(GF(3), 2)
914
+ sage: Q.I(ZZ, 3).dimension_vector()
915
+ (4, 2, 1)
916
+ sage: Q.I(ZZ, 1).dimension_vector()
917
+ (1, 0, 0)
918
+
919
+ The vertex given must be a vertex of the quiver::
920
+
921
+ sage: Q.I(QQ, 4)
922
+ Traceback (most recent call last):
923
+ ...
924
+ ValueError: must specify a valid vertex of the quiver
925
+ """
926
+ if vertex not in self._quiver:
927
+ raise ValueError("must specify a valid vertex of the quiver")
928
+ return QuiverRep(k, self, [[(vertex, vertex)]], option='dual paths')
929
+
930
+ injective = I
931
+
932
+ def free_module(self, k):
933
+ """
934
+ Return a free module of rank `1` over ``kP``, where `P` is
935
+ ``self``. (In other words, the regular representation.)
936
+
937
+ INPUT:
938
+
939
+ - ``k`` -- ring; the base ring of the representation
940
+
941
+ OUTPUT:
942
+
943
+ - :class:`~sage.quivers.representation.QuiverRep_with_path_basis`, the
944
+ path algebra considered as a right module over itself.
945
+
946
+ EXAMPLES::
947
+
948
+ sage: Q = DiGraph({1:{2:['a', 'b'], 3: ['c', 'd']}, 2:{3:['e']}}).path_semigroup()
949
+ sage: Q.free_module(GF(3)).dimension_vector()
950
+ (1, 3, 6)
951
+ """
952
+ return QuiverRep(k, self, [[(v, v)] for v in self._quiver], option='paths')
953
+
954
+ @lazy_attribute
955
+ def _poincare_series(self):
956
+ r"""
957
+ The Poincaré series matrix of this path semigroup.
958
+
959
+ The coefficient `(i,j)` of the matrix is a generating function for the
960
+ number of paths from vertex number `i` to vertex number `j`.
961
+
962
+ EXAMPLES::
963
+
964
+ sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']}, 2:{0:['e'],2:['f']}}).path_semigroup()
965
+ sage: S._poincare_series
966
+ [ (-t + 1)/(-2*t^2 - t + 1) t/(-2*t^2 - t + 1) t/(-2*t^2 - t + 1)]
967
+ [ t/(-2*t^2 - t + 1) (t^2 + t - 1)/(-2*t^3 + t^2 + 2*t - 1) -t^2/(-2*t^3 + t^2 + 2*t - 1)]
968
+ [ t/(-2*t^2 - t + 1) -t^2/(-2*t^3 + t^2 + 2*t - 1) (-t^2 - t + 1)/(2*t^3 - t^2 - 2*t + 1)]
969
+
970
+ Let us check that the result is plausible. We study the paths from
971
+ vertex `1` to vertex `2`. The number of paths sorted by length are
972
+ given by the power series expansion of the corresponding matrix
973
+ entry::
974
+
975
+ sage: P = PowerSeriesRing(ZZ, 't', default_prec=10)
976
+ sage: P(S._poincare_series[1,2].numerator())/P(S._poincare_series[1,2].denominator())
977
+ t^2 + 2*t^3 + 5*t^4 + 10*t^5 + 21*t^6 + 42*t^7 + 85*t^8 + 170*t^9 + 341*t^10 + 682*t^11 + O(t^12)
978
+
979
+ For comparison, we list the paths that start at `1` and end at `2`, by
980
+ length, and see that the Poincaré series matrix predicts the correct
981
+ numbers::
982
+
983
+ sage: [p for p in S.iter_paths_by_length_and_startpoint(1,1) if p.terminal_vertex()==2]
984
+ []
985
+ sage: [p for p in S.iter_paths_by_length_and_startpoint(2,1) if p.terminal_vertex()==2]
986
+ [c*b]
987
+ sage: [p for p in S.iter_paths_by_length_and_startpoint(3,1) if p.terminal_vertex()==2]
988
+ [c*b*f, d*c*b]
989
+ sage: [p for p in S.iter_paths_by_length_and_startpoint(4,1) if p.terminal_vertex()==2]
990
+ [c*a*c*b, c*b*e*b, c*b*f*f, d*c*b*f, d*d*c*b]
991
+ sage: len([p for p in S.iter_paths_by_length_and_startpoint(5,1) if p.terminal_vertex()==2])
992
+ 10
993
+ sage: len([p for p in S.iter_paths_by_length_and_startpoint(10,1) if p.terminal_vertex()==2])
994
+ 341
995
+ """
996
+ P = ZZ['t']
997
+ t = P.gen()
998
+ M = self._quiver.adjacency_matrix()
999
+ out = ~(1 - M * t)
1000
+ out.set_immutable()
1001
+ return out
1002
+
1003
+ def all_paths(self, start=None, end=None):
1004
+ """
1005
+ List of all paths between a pair of vertices ``(start, end)``.
1006
+
1007
+ INPUT:
1008
+
1009
+ - ``start`` -- integer or ``None`` (default: ``None``); the initial
1010
+ vertex of the paths in the output; if ``None`` is given then
1011
+ the initial vertex is arbitrary.
1012
+ - ``end`` -- integer or ``None`` (default: ``None``); the terminal
1013
+ vertex of the paths in the output; if ``None`` is given then
1014
+ the terminal vertex is arbitrary
1015
+
1016
+ OUTPUT: list of paths, excluding the invalid path
1017
+
1018
+ .. TODO::
1019
+
1020
+ This currently does not work for quivers with cycles, even if
1021
+ there are only finitely many paths from ``start`` to ``end``.
1022
+
1023
+ .. NOTE::
1024
+
1025
+ If there are multiple edges between two vertices, the method
1026
+ :meth:`sage.graphs.digraph.all_paths` will not differentiate
1027
+ between them. But this method, which is not for digraphs but for
1028
+ their path semigroup associated with them, will.
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
1033
+ sage: F = Q.path_semigroup()
1034
+ sage: F.all_paths(1, 3)
1035
+ [a*d, b*d, c]
1036
+
1037
+ If ``start=end`` then we expect only the trivial path at that vertex::
1038
+
1039
+ sage: F.all_paths(1, 1)
1040
+ [e_1]
1041
+
1042
+ The empty list is returned if there are no paths between the
1043
+ given vertices::
1044
+
1045
+ sage: F.all_paths(3, 1)
1046
+ []
1047
+
1048
+ If ``end=None`` then all edge paths beginning at ``start`` are
1049
+ returned, including the trivial path::
1050
+
1051
+ sage: F.all_paths(2)
1052
+ [e_2, d]
1053
+
1054
+ If ``start=None`` then all edge paths ending at ``end`` are
1055
+ returned, including the trivial path. Note that the two edges
1056
+ from vertex 1 to vertex 2 count as two different edge paths::
1057
+
1058
+ sage: F.all_paths(None, 2)
1059
+ [a, b, e_2]
1060
+ sage: F.all_paths(end=2)
1061
+ [a, b, e_2]
1062
+
1063
+ If ``start=end=None`` then all edge paths are returned, including
1064
+ trivial paths::
1065
+
1066
+ sage: F.all_paths()
1067
+ [e_1, a, b, a*d, b*d, c, e_2, d, e_3]
1068
+
1069
+ The vertex given must be a vertex of the quiver::
1070
+
1071
+ sage: F.all_paths(1, 4)
1072
+ Traceback (most recent call last):
1073
+ ...
1074
+ ValueError: the end vertex 4 is not a vertex of the quiver
1075
+
1076
+ If the underlying quiver is cyclic, a :exc:`ValueError`
1077
+ is raised::
1078
+
1079
+ sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
1080
+ sage: F = Q.path_semigroup()
1081
+ sage: F.all_paths()
1082
+ Traceback (most recent call last):
1083
+ ...
1084
+ ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
1085
+
1086
+ TESTS:
1087
+
1088
+ We check a single edge with a multi-character label::
1089
+
1090
+ sage: Q = DiGraph([[1,2,'abc']])
1091
+ sage: PQ = Q.path_semigroup()
1092
+ sage: PQ.all_paths(1,2)
1093
+ [abc]
1094
+
1095
+ An example with multiple edges::
1096
+
1097
+ sage: Q = DiGraph([[1,2,'abc'], [1,2,'def']], multiedges=True)
1098
+ sage: PQ = Q.path_semigroup()
1099
+ sage: PQ.all_paths(1,2)
1100
+ [abc, def]
1101
+ """
1102
+ # Check that given arguments are vertices
1103
+ if start is not None and start not in self._quiver:
1104
+ raise ValueError("the start vertex {} is not a vertex of the quiver".format(start))
1105
+ if end is not None and end not in self._quiver:
1106
+ raise ValueError("the end vertex {} is not a vertex of the quiver".format(end))
1107
+
1108
+ # Handle quivers with cycles
1109
+ Q = self._quiver
1110
+ if not (Q.is_directed_acyclic()):
1111
+ raise ValueError("the underlying quiver has cycles, thus, there may be an infinity of directed paths")
1112
+
1113
+ # Handle start=None
1114
+ if start is None:
1115
+ results = []
1116
+ for v in Q:
1117
+ results += self.all_paths(v, end)
1118
+ return results
1119
+
1120
+ # Handle end=None
1121
+ if end is None:
1122
+ results = []
1123
+ for v in Q:
1124
+ results += self.all_paths(start, v)
1125
+ return results
1126
+
1127
+ # Handle the trivial case
1128
+ if start == end:
1129
+ return [self.element_class(self, start, end, [])]
1130
+
1131
+ # This function will recursively convert a path given in terms of
1132
+ # vertices to a list of QuiverPaths.
1133
+ def _v_to_e(path):
1134
+ if len(path) == 1:
1135
+ return [self.element_class(self, path[0], path[0], [])]
1136
+ paths = []
1137
+ ell = Q.edge_label(path[0], path[1])
1138
+ if isinstance(ell, str):
1139
+ for b in _v_to_e(path[1:]):
1140
+ paths.append(self([(path[0], path[1], ell)]
1141
+ + list(b), check=False))
1142
+ else:
1143
+ for a in ell:
1144
+ for b in _v_to_e(path[1:]):
1145
+ paths.append(self([(path[0], path[1], a)]
1146
+ + list(b), check=False))
1147
+ return paths
1148
+
1149
+ # For each vertex path we append the resulting edge paths
1150
+ result = []
1151
+ for path in Q.all_paths(start, end):
1152
+ result += _v_to_e(path)
1153
+
1154
+ # The result is all paths from start to end
1155
+ return result