passagemath-singular 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-singular might be problematic. Click here for more details.

Files changed (491) hide show
  1. PySingular.cpython-314-x86_64-linux-gnu.so +0 -0
  2. passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
  3. passagemath_singular-10.6.31rc3.dist-info/RECORD +491 -0
  4. passagemath_singular-10.6.31rc3.dist-info/WHEEL +6 -0
  5. passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
  6. passagemath_singular.libs/libSingular-4-20aec911.4.1.so +0 -0
  7. passagemath_singular.libs/libcddgmp-21acf0c6.so.0.1.3 +0 -0
  8. passagemath_singular.libs/libfactory-4-fcee31da.4.1.so +0 -0
  9. passagemath_singular.libs/libflint-66e12231.so.21.0.0 +0 -0
  10. passagemath_singular.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  11. passagemath_singular.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
  12. passagemath_singular.libs/libgmp-6e109695.so.10.5.0 +0 -0
  13. passagemath_singular.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  14. passagemath_singular.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  15. passagemath_singular.libs/libntl-e6f0d543.so.44.0.1 +0 -0
  16. passagemath_singular.libs/libomalloc-0-5c9e866e.9.6.so +0 -0
  17. passagemath_singular.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  18. passagemath_singular.libs/libpolys-4-5c0a87e0.4.1.so +0 -0
  19. passagemath_singular.libs/libquadmath-2284e583.so.0.0.0 +0 -0
  20. passagemath_singular.libs/libreadline-ea270e21.so.8.2 +0 -0
  21. passagemath_singular.libs/libsingular_resources-4-a1aafc6d.4.1.so +0 -0
  22. passagemath_singular.libs/libtinfo-ceb117d9.so.6.3 +0 -0
  23. sage/algebras/all__sagemath_singular.py +3 -0
  24. sage/algebras/fusion_rings/all.py +19 -0
  25. sage/algebras/fusion_rings/f_matrix.py +2448 -0
  26. sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-x86_64-linux-gnu.so +0 -0
  27. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
  28. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
  29. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-x86_64-linux-gnu.so +0 -0
  30. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
  31. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
  32. sage/algebras/fusion_rings/fusion_double.py +899 -0
  33. sage/algebras/fusion_rings/fusion_ring.py +1580 -0
  34. sage/algebras/fusion_rings/poly_tup_engine.cpython-314-x86_64-linux-gnu.so +0 -0
  35. sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
  36. sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
  37. sage/algebras/fusion_rings/shm_managers.cpython-314-x86_64-linux-gnu.so +0 -0
  38. sage/algebras/fusion_rings/shm_managers.pxd +24 -0
  39. sage/algebras/fusion_rings/shm_managers.pyx +780 -0
  40. sage/algebras/letterplace/all.py +1 -0
  41. sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
  42. sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
  43. sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
  44. sage/algebras/letterplace/free_algebra_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
  45. sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
  46. sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
  47. sage/algebras/letterplace/letterplace_ideal.cpython-314-x86_64-linux-gnu.so +0 -0
  48. sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
  49. sage/algebras/quatalg/all.py +2 -0
  50. sage/algebras/quatalg/quaternion_algebra.py +4778 -0
  51. sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-x86_64-linux-gnu.so +0 -0
  52. sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
  53. sage/algebras/quatalg/quaternion_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
  54. sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
  55. sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
  56. sage/all__sagemath_singular.py +11 -0
  57. sage/ext_data/all__sagemath_singular.py +1 -0
  58. sage/ext_data/singular/function_field/core.lib +98 -0
  59. sage/interfaces/all__sagemath_singular.py +1 -0
  60. sage/interfaces/singular.py +2835 -0
  61. sage/libs/all__sagemath_singular.py +1 -0
  62. sage/libs/singular/__init__.py +1 -0
  63. sage/libs/singular/decl.pxd +1168 -0
  64. sage/libs/singular/function.cpython-314-x86_64-linux-gnu.so +0 -0
  65. sage/libs/singular/function.pxd +87 -0
  66. sage/libs/singular/function.pyx +1901 -0
  67. sage/libs/singular/function_factory.py +61 -0
  68. sage/libs/singular/groebner_strategy.cpython-314-x86_64-linux-gnu.so +0 -0
  69. sage/libs/singular/groebner_strategy.pxd +22 -0
  70. sage/libs/singular/groebner_strategy.pyx +582 -0
  71. sage/libs/singular/option.cpython-314-x86_64-linux-gnu.so +0 -0
  72. sage/libs/singular/option.pyx +671 -0
  73. sage/libs/singular/polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
  74. sage/libs/singular/polynomial.pxd +39 -0
  75. sage/libs/singular/polynomial.pyx +661 -0
  76. sage/libs/singular/ring.cpython-314-x86_64-linux-gnu.so +0 -0
  77. sage/libs/singular/ring.pxd +58 -0
  78. sage/libs/singular/ring.pyx +893 -0
  79. sage/libs/singular/singular.cpython-314-x86_64-linux-gnu.so +0 -0
  80. sage/libs/singular/singular.pxd +72 -0
  81. sage/libs/singular/singular.pyx +1944 -0
  82. sage/libs/singular/standard_options.py +145 -0
  83. sage/matrix/all__sagemath_singular.py +1 -0
  84. sage/matrix/matrix_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  85. sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
  86. sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
  87. sage/rings/all__sagemath_singular.py +1 -0
  88. sage/rings/function_field/all__sagemath_singular.py +1 -0
  89. sage/rings/function_field/derivations_polymod.py +911 -0
  90. sage/rings/function_field/element_polymod.cpython-314-x86_64-linux-gnu.so +0 -0
  91. sage/rings/function_field/element_polymod.pyx +406 -0
  92. sage/rings/function_field/function_field_polymod.py +2611 -0
  93. sage/rings/function_field/ideal_polymod.py +1775 -0
  94. sage/rings/function_field/order_polymod.py +1475 -0
  95. sage/rings/function_field/place_polymod.py +681 -0
  96. sage/rings/polynomial/all__sagemath_singular.py +1 -0
  97. sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
  98. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
  99. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
  100. sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
  101. sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
  102. sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
  103. sage/rings/polynomial/plural.cpython-314-x86_64-linux-gnu.so +0 -0
  104. sage/rings/polynomial/plural.pxd +48 -0
  105. sage/rings/polynomial/plural.pyx +3171 -0
  106. sage/symbolic/all__sagemath_singular.py +1 -0
  107. sage/symbolic/comparison_impl.pxi +428 -0
  108. sage/symbolic/constants_c_impl.pxi +178 -0
  109. sage/symbolic/expression.cpython-314-x86_64-linux-gnu.so +0 -0
  110. sage/symbolic/expression.pxd +7 -0
  111. sage/symbolic/expression.pyx +14200 -0
  112. sage/symbolic/getitem_impl.pxi +202 -0
  113. sage/symbolic/pynac.pxi +572 -0
  114. sage/symbolic/pynac_constant_impl.pxi +133 -0
  115. sage/symbolic/pynac_function_impl.pxi +206 -0
  116. sage/symbolic/pynac_impl.pxi +2576 -0
  117. sage/symbolic/pynac_wrap.h +124 -0
  118. sage/symbolic/series_impl.pxi +272 -0
  119. sage/symbolic/substitution_map_impl.pxi +94 -0
  120. sage_wheels/bin/ESingular +0 -0
  121. sage_wheels/bin/Singular +0 -0
  122. sage_wheels/bin/TSingular +0 -0
  123. sage_wheels/lib/singular/MOD/cohomo.la +41 -0
  124. sage_wheels/lib/singular/MOD/cohomo.so +0 -0
  125. sage_wheels/lib/singular/MOD/customstd.la +41 -0
  126. sage_wheels/lib/singular/MOD/customstd.so +0 -0
  127. sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
  128. sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
  129. sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
  130. sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
  131. sage_wheels/lib/singular/MOD/gitfan.la +41 -0
  132. sage_wheels/lib/singular/MOD/gitfan.so +0 -0
  133. sage_wheels/lib/singular/MOD/interval.la +41 -0
  134. sage_wheels/lib/singular/MOD/interval.so +0 -0
  135. sage_wheels/lib/singular/MOD/loctriv.la +41 -0
  136. sage_wheels/lib/singular/MOD/loctriv.so +0 -0
  137. sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
  138. sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
  139. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
  140. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
  141. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
  142. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
  143. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
  144. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
  145. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
  146. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
  147. sage_wheels/lib/singular/MOD/partialgb.la +41 -0
  148. sage_wheels/lib/singular/MOD/partialgb.so +0 -0
  149. sage_wheels/lib/singular/MOD/pyobject.la +41 -0
  150. sage_wheels/lib/singular/MOD/pyobject.so +0 -0
  151. sage_wheels/lib/singular/MOD/singmathic.la +41 -0
  152. sage_wheels/lib/singular/MOD/singmathic.so +0 -0
  153. sage_wheels/lib/singular/MOD/sispasm.la +41 -0
  154. sage_wheels/lib/singular/MOD/sispasm.so +0 -0
  155. sage_wheels/lib/singular/MOD/subsets.la +41 -0
  156. sage_wheels/lib/singular/MOD/subsets.so +0 -0
  157. sage_wheels/lib/singular/MOD/systhreads.la +41 -0
  158. sage_wheels/lib/singular/MOD/systhreads.so +0 -0
  159. sage_wheels/lib/singular/MOD/syzextra.la +41 -0
  160. sage_wheels/lib/singular/MOD/syzextra.so +0 -0
  161. sage_wheels/libexec/singular/MOD/change_cost +0 -0
  162. sage_wheels/libexec/singular/MOD/singularsurf +11 -0
  163. sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
  164. sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
  165. sage_wheels/libexec/singular/MOD/solve_IP +0 -0
  166. sage_wheels/libexec/singular/MOD/surfex +16 -0
  167. sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
  168. sage_wheels/share/factory/gftables/10201 +342 -0
  169. sage_wheels/share/factory/gftables/1024 +37 -0
  170. sage_wheels/share/factory/gftables/10609 +356 -0
  171. sage_wheels/share/factory/gftables/11449 +384 -0
  172. sage_wheels/share/factory/gftables/11881 +398 -0
  173. sage_wheels/share/factory/gftables/121 +6 -0
  174. sage_wheels/share/factory/gftables/12167 +408 -0
  175. sage_wheels/share/factory/gftables/125 +7 -0
  176. sage_wheels/share/factory/gftables/12769 +428 -0
  177. sage_wheels/share/factory/gftables/128 +7 -0
  178. sage_wheels/share/factory/gftables/1331 +47 -0
  179. sage_wheels/share/factory/gftables/1369 +48 -0
  180. sage_wheels/share/factory/gftables/14641 +490 -0
  181. sage_wheels/share/factory/gftables/15625 +523 -0
  182. sage_wheels/share/factory/gftables/16 +3 -0
  183. sage_wheels/share/factory/gftables/16129 +540 -0
  184. sage_wheels/share/factory/gftables/16384 +549 -0
  185. sage_wheels/share/factory/gftables/16807 +563 -0
  186. sage_wheels/share/factory/gftables/1681 +58 -0
  187. sage_wheels/share/factory/gftables/169 +8 -0
  188. sage_wheels/share/factory/gftables/17161 +574 -0
  189. sage_wheels/share/factory/gftables/1849 +64 -0
  190. sage_wheels/share/factory/gftables/18769 +628 -0
  191. sage_wheels/share/factory/gftables/19321 +646 -0
  192. sage_wheels/share/factory/gftables/19683 +659 -0
  193. sage_wheels/share/factory/gftables/2048 +71 -0
  194. sage_wheels/share/factory/gftables/2187 +75 -0
  195. sage_wheels/share/factory/gftables/2197 +76 -0
  196. sage_wheels/share/factory/gftables/2209 +76 -0
  197. sage_wheels/share/factory/gftables/22201 +742 -0
  198. sage_wheels/share/factory/gftables/22801 +762 -0
  199. sage_wheels/share/factory/gftables/2401 +82 -0
  200. sage_wheels/share/factory/gftables/243 +11 -0
  201. sage_wheels/share/factory/gftables/24389 +815 -0
  202. sage_wheels/share/factory/gftables/24649 +824 -0
  203. sage_wheels/share/factory/gftables/25 +3 -0
  204. sage_wheels/share/factory/gftables/256 +11 -0
  205. sage_wheels/share/factory/gftables/26569 +888 -0
  206. sage_wheels/share/factory/gftables/27 +3 -0
  207. sage_wheels/share/factory/gftables/27889 +932 -0
  208. sage_wheels/share/factory/gftables/2809 +96 -0
  209. sage_wheels/share/factory/gftables/28561 +954 -0
  210. sage_wheels/share/factory/gftables/289 +12 -0
  211. sage_wheels/share/factory/gftables/29791 +995 -0
  212. sage_wheels/share/factory/gftables/29929 +1000 -0
  213. sage_wheels/share/factory/gftables/3125 +107 -0
  214. sage_wheels/share/factory/gftables/32 +4 -0
  215. sage_wheels/share/factory/gftables/32041 +1070 -0
  216. sage_wheels/share/factory/gftables/32761 +1094 -0
  217. sage_wheels/share/factory/gftables/32768 +1095 -0
  218. sage_wheels/share/factory/gftables/343 +14 -0
  219. sage_wheels/share/factory/gftables/3481 +118 -0
  220. sage_wheels/share/factory/gftables/361 +14 -0
  221. sage_wheels/share/factory/gftables/36481 +1218 -0
  222. sage_wheels/share/factory/gftables/3721 +126 -0
  223. sage_wheels/share/factory/gftables/37249 +1244 -0
  224. sage_wheels/share/factory/gftables/38809 +1296 -0
  225. sage_wheels/share/factory/gftables/39601 +1322 -0
  226. sage_wheels/share/factory/gftables/4 +3 -0
  227. sage_wheels/share/factory/gftables/4096 +139 -0
  228. sage_wheels/share/factory/gftables/44521 +1486 -0
  229. sage_wheels/share/factory/gftables/4489 +152 -0
  230. sage_wheels/share/factory/gftables/49 +4 -0
  231. sage_wheels/share/factory/gftables/4913 +166 -0
  232. sage_wheels/share/factory/gftables/49729 +1660 -0
  233. sage_wheels/share/factory/gftables/5041 +170 -0
  234. sage_wheels/share/factory/gftables/50653 +1691 -0
  235. sage_wheels/share/factory/gftables/512 +20 -0
  236. sage_wheels/share/factory/gftables/51529 +1720 -0
  237. sage_wheels/share/factory/gftables/52441 +1750 -0
  238. sage_wheels/share/factory/gftables/529 +20 -0
  239. sage_wheels/share/factory/gftables/5329 +180 -0
  240. sage_wheels/share/factory/gftables/54289 +1812 -0
  241. sage_wheels/share/factory/gftables/57121 +1906 -0
  242. sage_wheels/share/factory/gftables/58081 +1938 -0
  243. sage_wheels/share/factory/gftables/59049 +1971 -0
  244. sage_wheels/share/factory/gftables/6241 +210 -0
  245. sage_wheels/share/factory/gftables/625 +23 -0
  246. sage_wheels/share/factory/gftables/63001 +2102 -0
  247. sage_wheels/share/factory/gftables/64 +5 -0
  248. sage_wheels/share/factory/gftables/6561 +221 -0
  249. sage_wheels/share/factory/gftables/6859 +231 -0
  250. sage_wheels/share/factory/gftables/6889 +232 -0
  251. sage_wheels/share/factory/gftables/729 +27 -0
  252. sage_wheels/share/factory/gftables/7921 +266 -0
  253. sage_wheels/share/factory/gftables/8 +3 -0
  254. sage_wheels/share/factory/gftables/81 +5 -0
  255. sage_wheels/share/factory/gftables/8192 +276 -0
  256. sage_wheels/share/factory/gftables/841 +30 -0
  257. sage_wheels/share/factory/gftables/9 +3 -0
  258. sage_wheels/share/factory/gftables/9409 +316 -0
  259. sage_wheels/share/factory/gftables/961 +34 -0
  260. sage_wheels/share/info/singular.info +191898 -0
  261. sage_wheels/share/singular/LIB/GND.lib +1359 -0
  262. sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
  263. sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
  264. sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
  265. sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
  266. sage_wheels/share/singular/LIB/VecField.lib +1542 -0
  267. sage_wheels/share/singular/LIB/absfact.lib +959 -0
  268. sage_wheels/share/singular/LIB/ainvar.lib +730 -0
  269. sage_wheels/share/singular/LIB/aksaka.lib +419 -0
  270. sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
  271. sage_wheels/share/singular/LIB/algebra.lib +1193 -0
  272. sage_wheels/share/singular/LIB/all.lib +136 -0
  273. sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
  274. sage_wheels/share/singular/LIB/arnold.lib +4553 -0
  275. sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
  276. sage_wheels/share/singular/LIB/arr.lib +3486 -0
  277. sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
  278. sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
  279. sage_wheels/share/singular/LIB/bfun.lib +1964 -0
  280. sage_wheels/share/singular/LIB/bimodules.lib +774 -0
  281. sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
  282. sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
  283. sage_wheels/share/singular/LIB/central.lib +2169 -0
  284. sage_wheels/share/singular/LIB/chern.lib +4162 -0
  285. sage_wheels/share/singular/LIB/cimonom.lib +571 -0
  286. sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
  287. sage_wheels/share/singular/LIB/classify.lib +3239 -0
  288. sage_wheels/share/singular/LIB/classify2.lib +1462 -0
  289. sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
  290. sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
  291. sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
  292. sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
  293. sage_wheels/share/singular/LIB/combinat.lib +91 -0
  294. sage_wheels/share/singular/LIB/compregb.lib +276 -0
  295. sage_wheels/share/singular/LIB/control.lib +1636 -0
  296. sage_wheels/share/singular/LIB/crypto.lib +3795 -0
  297. sage_wheels/share/singular/LIB/curveInv.lib +667 -0
  298. sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
  299. sage_wheels/share/singular/LIB/customstd.lib +100 -0
  300. sage_wheels/share/singular/LIB/deRham.lib +5979 -0
  301. sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
  302. sage_wheels/share/singular/LIB/decomp.lib +1655 -0
  303. sage_wheels/share/singular/LIB/deflation.lib +872 -0
  304. sage_wheels/share/singular/LIB/deform.lib +925 -0
  305. sage_wheels/share/singular/LIB/difform.lib +3055 -0
  306. sage_wheels/share/singular/LIB/divisors.lib +750 -0
  307. sage_wheels/share/singular/LIB/dmod.lib +5817 -0
  308. sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
  309. sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
  310. sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
  311. sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
  312. sage_wheels/share/singular/LIB/dummy.lib +17 -0
  313. sage_wheels/share/singular/LIB/elim.lib +1009 -0
  314. sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
  315. sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
  316. sage_wheels/share/singular/LIB/equising.lib +2127 -0
  317. sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
  318. sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
  319. sage_wheels/share/singular/LIB/findifs.lib +778 -0
  320. sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
  321. sage_wheels/share/singular/LIB/finvar.lib +7989 -0
  322. sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
  323. sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
  324. sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
  325. sage_wheels/share/singular/LIB/freegb.lib +3853 -0
  326. sage_wheels/share/singular/LIB/general.lib +1350 -0
  327. sage_wheels/share/singular/LIB/gfan.lib +1768 -0
  328. sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
  329. sage_wheels/share/singular/LIB/gkdim.lib +99 -0
  330. sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
  331. sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
  332. sage_wheels/share/singular/LIB/goettsche.lib +909 -0
  333. sage_wheels/share/singular/LIB/graal.lib +1366 -0
  334. sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
  335. sage_wheels/share/singular/LIB/graphics.lib +360 -0
  336. sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
  337. sage_wheels/share/singular/LIB/groups.lib +1123 -0
  338. sage_wheels/share/singular/LIB/grwalk.lib +507 -0
  339. sage_wheels/share/singular/LIB/hdepth.lib +194 -0
  340. sage_wheels/share/singular/LIB/help.cnf +57 -0
  341. sage_wheels/share/singular/LIB/hess.lib +1946 -0
  342. sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
  343. sage_wheels/share/singular/LIB/hodge.lib +400 -0
  344. sage_wheels/share/singular/LIB/homolog.lib +1965 -0
  345. sage_wheels/share/singular/LIB/hyperel.lib +975 -0
  346. sage_wheels/share/singular/LIB/inout.lib +679 -0
  347. sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
  348. sage_wheels/share/singular/LIB/interval.lib +1418 -0
  349. sage_wheels/share/singular/LIB/intprog.lib +778 -0
  350. sage_wheels/share/singular/LIB/invar.lib +443 -0
  351. sage_wheels/share/singular/LIB/involut.lib +980 -0
  352. sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
  353. sage_wheels/share/singular/LIB/kskernel.lib +534 -0
  354. sage_wheels/share/singular/LIB/latex.lib +3146 -0
  355. sage_wheels/share/singular/LIB/lejeune.lib +651 -0
  356. sage_wheels/share/singular/LIB/linalg.lib +2040 -0
  357. sage_wheels/share/singular/LIB/locnormal.lib +212 -0
  358. sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
  359. sage_wheels/share/singular/LIB/makedbm.lib +294 -0
  360. sage_wheels/share/singular/LIB/mathml.lib +813 -0
  361. sage_wheels/share/singular/LIB/matrix.lib +1372 -0
  362. sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
  363. sage_wheels/share/singular/LIB/methods.lib +212 -0
  364. sage_wheels/share/singular/LIB/moddiq.lib +322 -0
  365. sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
  366. sage_wheels/share/singular/LIB/modnormal.lib +218 -0
  367. sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
  368. sage_wheels/share/singular/LIB/modquotient.lib +269 -0
  369. sage_wheels/share/singular/LIB/modstd.lib +1024 -0
  370. sage_wheels/share/singular/LIB/modular.lib +545 -0
  371. sage_wheels/share/singular/LIB/modules.lib +2561 -0
  372. sage_wheels/share/singular/LIB/modwalk.lib +609 -0
  373. sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
  374. sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
  375. sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
  376. sage_wheels/share/singular/LIB/mregular.lib +1863 -0
  377. sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
  378. sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
  379. sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
  380. sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
  381. sage_wheels/share/singular/LIB/ncall.lib +31 -0
  382. sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
  383. sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
  384. sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
  385. sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
  386. sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
  387. sage_wheels/share/singular/LIB/ncloc.lib +361 -0
  388. sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
  389. sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
  390. sage_wheels/share/singular/LIB/nctools.lib +1887 -0
  391. sage_wheels/share/singular/LIB/nets.lib +1456 -0
  392. sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
  393. sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
  394. sage_wheels/share/singular/LIB/noether.lib +1106 -0
  395. sage_wheels/share/singular/LIB/normal.lib +8700 -0
  396. sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
  397. sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
  398. sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
  399. sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
  400. sage_wheels/share/singular/LIB/olga.lib +1933 -0
  401. sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
  402. sage_wheels/share/singular/LIB/parallel.lib +319 -0
  403. sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
  404. sage_wheels/share/singular/LIB/perron.lib +202 -0
  405. sage_wheels/share/singular/LIB/pfd.lib +2223 -0
  406. sage_wheels/share/singular/LIB/phindex.lib +642 -0
  407. sage_wheels/share/singular/LIB/pointid.lib +673 -0
  408. sage_wheels/share/singular/LIB/polybori.lib +1430 -0
  409. sage_wheels/share/singular/LIB/polyclass.lib +525 -0
  410. sage_wheels/share/singular/LIB/polylib.lib +1174 -0
  411. sage_wheels/share/singular/LIB/polymake.lib +1902 -0
  412. sage_wheels/share/singular/LIB/presolve.lib +1533 -0
  413. sage_wheels/share/singular/LIB/primdec.lib +9576 -0
  414. sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
  415. sage_wheels/share/singular/LIB/primitiv.lib +401 -0
  416. sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
  417. sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
  418. sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
  419. sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
  420. sage_wheels/share/singular/LIB/random.lib +455 -0
  421. sage_wheels/share/singular/LIB/ratgb.lib +489 -0
  422. sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
  423. sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
  424. sage_wheels/share/singular/LIB/realrad.lib +1197 -0
  425. sage_wheels/share/singular/LIB/recover.lib +2628 -0
  426. sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
  427. sage_wheels/share/singular/LIB/reesclos.lib +465 -0
  428. sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
  429. sage_wheels/share/singular/LIB/resgraph.lib +789 -0
  430. sage_wheels/share/singular/LIB/resjung.lib +820 -0
  431. sage_wheels/share/singular/LIB/resolve.lib +5110 -0
  432. sage_wheels/share/singular/LIB/resources.lib +170 -0
  433. sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
  434. sage_wheels/share/singular/LIB/ring.lib +1328 -0
  435. sage_wheels/share/singular/LIB/ringgb.lib +343 -0
  436. sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
  437. sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
  438. sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
  439. sage_wheels/share/singular/LIB/rootsur.lib +886 -0
  440. sage_wheels/share/singular/LIB/rstandard.lib +607 -0
  441. sage_wheels/share/singular/LIB/rwalk.lib +336 -0
  442. sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
  443. sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
  444. sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
  445. sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
  446. sage_wheels/share/singular/LIB/schreyer.lib +321 -0
  447. sage_wheels/share/singular/LIB/schubert.lib +2551 -0
  448. sage_wheels/share/singular/LIB/sets.lib +524 -0
  449. sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
  450. sage_wheels/share/singular/LIB/signcond.lib +437 -0
  451. sage_wheels/share/singular/LIB/sing.lib +1094 -0
  452. sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
  453. sage_wheels/share/singular/LIB/solve.lib +2243 -0
  454. sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
  455. sage_wheels/share/singular/LIB/spectrum.lib +62 -0
  456. sage_wheels/share/singular/LIB/sresext.lib +757 -0
  457. sage_wheels/share/singular/LIB/ssi.lib +143 -0
  458. sage_wheels/share/singular/LIB/standard.lib +2769 -0
  459. sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
  460. sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
  461. sage_wheels/share/singular/LIB/stratify.lib +1070 -0
  462. sage_wheels/share/singular/LIB/surf.lib +506 -0
  463. sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
  464. sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
  465. sage_wheels/share/singular/LIB/surfex.lib +1462 -0
  466. sage_wheels/share/singular/LIB/swalk.lib +877 -0
  467. sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
  468. sage_wheels/share/singular/LIB/systhreads.lib +74 -0
  469. sage_wheels/share/singular/LIB/tasks.lib +1324 -0
  470. sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
  471. sage_wheels/share/singular/LIB/teachstd.lib +858 -0
  472. sage_wheels/share/singular/LIB/template.lib +116 -0
  473. sage_wheels/share/singular/LIB/toric.lib +1119 -0
  474. sage_wheels/share/singular/LIB/transformation.lib +116 -0
  475. sage_wheels/share/singular/LIB/triang.lib +1197 -0
  476. sage_wheels/share/singular/LIB/tropical.lib +8741 -0
  477. sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
  478. sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
  479. sage_wheels/share/singular/LIB/tst.lib +1108 -0
  480. sage_wheels/share/singular/LIB/weierstr.lib +241 -0
  481. sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
  482. sage_wheels/share/singular/emacs/.emacs-general +184 -0
  483. sage_wheels/share/singular/emacs/.emacs-singular +234 -0
  484. sage_wheels/share/singular/emacs/COPYING +44 -0
  485. sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
  486. sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
  487. sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
  488. sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
  489. sage_wheels/share/singular/emacs/singular.el +4273 -0
  490. sage_wheels/share/singular/emacs/singular.xpm +39 -0
  491. sage_wheels/share/singular/singular.idx +5002 -0
@@ -0,0 +1,2835 @@
1
+ # sage_setup: distribution = sagemath-singular
2
+ r"""
3
+ Interface to Singular
4
+
5
+ Introduction
6
+ ------------
7
+
8
+ This interface is extremely flexible, since it's exactly like
9
+ typing into the Singular interpreter, and anything that works there
10
+ should work here.
11
+
12
+ The Singular interface will only work if Singular is installed on
13
+ your computer; this should be the case, since Singular is included
14
+ with Sage. The interface offers three pieces of functionality:
15
+
16
+ #. ``singular_console()`` -- a function that dumps you
17
+ into an interactive command-line Singular session.
18
+
19
+ #. ``singular(expr, type='def')`` -- creation of a
20
+ Singular object. This provides a Pythonic interface to Singular.
21
+ For example, if ``f=singular(10)``, then
22
+ ``f.factorize()`` returns the factorization of
23
+ `10` computed using Singular.
24
+
25
+ #. ``singular.eval(expr)`` -- evaluation of arbitrary
26
+ Singular expressions, with the result returned as a string.
27
+
28
+ Of course, there are polynomial rings and ideals in Sage as well
29
+ (often based on a C-library interface to Singular). One can convert
30
+ an object in the Singular interpreter interface to Sage by the
31
+ method ``sage()``.
32
+
33
+
34
+ Tutorial
35
+ --------
36
+
37
+ EXAMPLES: First we illustrate multivariate polynomial
38
+ factorization::
39
+
40
+ sage: R1 = singular.ring(0, '(x,y)', 'dp')
41
+ sage: R1
42
+ polynomial ring, over a field, global ordering
43
+ // coefficients: QQ...
44
+ // number of vars : 2
45
+ // block 1 : ordering dp
46
+ // : names x y
47
+ // block 2 : ordering C
48
+ sage: f = singular('9x16 - 18x13y2 - 9x12y3 + 9x10y4 - 18x11y2 + 36x8y4 + 18x7y5 - 18x5y6 + 9x6y4 - 18x3y6 - 9x2y7 + 9y8')
49
+ sage: f
50
+ 9*x^16-18*x^13*y^2-9*x^12*y^3+9*x^10*y^4-18*x^11*y^2+36*x^8*y^4+18*x^7*y^5-18*x^5*y^6+9*x^6*y^4-18*x^3*y^6-9*x^2*y^7+9*y^8
51
+ sage: f.parent()
52
+ Singular
53
+
54
+ ::
55
+
56
+ sage: F = f.factorize(); F
57
+ [1]:
58
+ _[1]=9
59
+ _[2]=x^6-2*x^3*y^2-x^2*y^3+y^4
60
+ _[3]=-x^5+y^2
61
+ [2]:
62
+ 1,1,2
63
+
64
+ ::
65
+
66
+ sage: F[1]
67
+ 9,
68
+ x^6-2*x^3*y^2-x^2*y^3+y^4,
69
+ -x^5+y^2
70
+ sage: F[1][2]
71
+ x^6-2*x^3*y^2-x^2*y^3+y^4
72
+
73
+ We can convert `f` and each exponent back to Sage objects
74
+ as well.
75
+
76
+ ::
77
+
78
+ sage: g = f.sage(); g
79
+ 9*x^16 - 18*x^13*y^2 - 9*x^12*y^3 + 9*x^10*y^4 - 18*x^11*y^2 + 36*x^8*y^4 + 18*x^7*y^5 - 18*x^5*y^6 + 9*x^6*y^4 - 18*x^3*y^6 - 9*x^2*y^7 + 9*y^8
80
+ sage: F[1][2].sage()
81
+ x^6 - 2*x^3*y^2 - x^2*y^3 + y^4
82
+ sage: g.parent()
83
+ Multivariate Polynomial Ring in x, y over Rational Field
84
+
85
+ This example illustrates polynomial GCD's::
86
+
87
+ sage: R2 = singular.ring(0, '(x,y,z)', 'lp')
88
+ sage: a = singular.new('3x2*(x+y)')
89
+ sage: b = singular.new('9x*(y2-x2)')
90
+ sage: g = a.gcd(b)
91
+ sage: g
92
+ x^2+x*y
93
+
94
+ This example illustrates computation of a Groebner basis::
95
+
96
+ sage: R3 = singular.ring(0, '(a,b,c,d)', 'lp')
97
+ sage: I = singular.ideal(['a + b + c + d', 'a*b + a*d + b*c + c*d', 'a*b*c + a*b*d + a*c*d + b*c*d', 'a*b*c*d - 1'])
98
+ sage: I2 = I.groebner()
99
+ sage: I2
100
+ c^2*d^6-c^2*d^2-d^4+1,
101
+ c^3*d^2+c^2*d^3-c-d,
102
+ b*d^4-b+d^5-d,
103
+ b*c-b*d^5+c^2*d^4+c*d-d^6-d^2,
104
+ b^2+2*b*d+d^2,
105
+ a+b+c+d
106
+
107
+ The following example is the same as the one in the Singular - Gap
108
+ interface documentation::
109
+
110
+ sage: R = singular.ring(0, '(x0,x1,x2)', 'lp')
111
+ sage: I1 = singular.ideal(['x0*x1*x2 -x0^2*x2', 'x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2', 'x0*x1-x0*x2-x1*x2'])
112
+ sage: I2 = I1.groebner()
113
+ sage: I2
114
+ x1^2*x2^2,
115
+ x0*x2^3-x1^2*x2^2+x1*x2^3,
116
+ x0*x1-x0*x2-x1*x2,
117
+ x0^2*x2-x0*x2^2-x1*x2^2
118
+ sage: I2.sage()
119
+ Ideal (x1^2*x2^2, x0*x2^3 - x1^2*x2^2 + x1*x2^3, x0*x1 - x0*x2 - x1*x2, x0^2*x2 - x0*x2^2 - x1*x2^2) of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field
120
+
121
+
122
+ This example illustrates moving a polynomial from one ring to
123
+ another. It also illustrates calling a method of an object with an
124
+ argument.
125
+
126
+ ::
127
+
128
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
129
+ sage: f = singular('x3+y3+(x-y)*x2y2+z2')
130
+ sage: f
131
+ x^3*y^2-x^2*y^3+x^3+y^3+z^2
132
+ sage: R1 = singular.ring(0, '(x,y,z)', 'ds')
133
+ sage: f = R.fetch(f)
134
+ sage: f
135
+ z^2+x^3+y^3+x^3*y^2-x^2*y^3
136
+
137
+ We can calculate the Milnor number of `f`::
138
+
139
+ sage: _=singular.LIB('sing.lib') # assign to _ to suppress printing
140
+ sage: f.milnor()
141
+ 4
142
+
143
+ The Jacobian applied twice yields the Hessian matrix of
144
+ `f`, with which we can compute.
145
+
146
+ ::
147
+
148
+ sage: H = f.jacob().jacob()
149
+ sage: H
150
+ 6*x+6*x*y^2-2*y^3,6*x^2*y-6*x*y^2, 0,
151
+ 6*x^2*y-6*x*y^2, 6*y+2*x^3-6*x^2*y,0,
152
+ 0, 0, 2
153
+ sage: H.sage()
154
+ [6*x + 6*x*y^2 - 2*y^3 6*x^2*y - 6*x*y^2 0]
155
+ [ 6*x^2*y - 6*x*y^2 6*y + 2*x^3 - 6*x^2*y 0]
156
+ [ 0 0 2]
157
+ sage: H.det() # This is a polynomial in Singular
158
+ 72*x*y+24*x^4-72*x^3*y+72*x*y^3-24*y^4-48*x^4*y^2+64*x^3*y^3-48*x^2*y^4
159
+ sage: H.det().sage() # This is the corresponding polynomial in Sage
160
+ 72*x*y + 24*x^4 - 72*x^3*y + 72*x*y^3 - 24*y^4 - 48*x^4*y^2 + 64*x^3*y^3 - 48*x^2*y^4
161
+
162
+ The 1x1 and 2x2 minors::
163
+
164
+ sage: H.minor(1)
165
+ 2,
166
+ 6*y+2*x^3-6*x^2*y,
167
+ 6*x^2*y-6*x*y^2,
168
+ 6*x^2*y-6*x*y^2,
169
+ 6*x+6*x*y^2-2*y^3,
170
+ 0,
171
+ 0,
172
+ 0,
173
+ 0
174
+ sage: H.minor(2)
175
+ 12*y+4*x^3-12*x^2*y,
176
+ 12*x^2*y-12*x*y^2,
177
+ 12*x^2*y-12*x*y^2,
178
+ 12*x+12*x*y^2-4*y^3,
179
+ -36*x*y-12*x^4+36*x^3*y-36*x*y^3+12*y^4+24*x^4*y^2-32*x^3*y^3+24*x^2*y^4,
180
+ 0,
181
+ 0,
182
+ 0,
183
+ 0
184
+
185
+ ::
186
+
187
+ sage: _=singular.eval('option(redSB)')
188
+ sage: H.minor(1).groebner()
189
+ 1
190
+
191
+ Computing the Genus
192
+ -------------------
193
+
194
+ We compute the projective genus of ideals that define curves over
195
+ `\QQ`. It is *very important* to load the
196
+ ``normal.lib`` library before calling the
197
+ ``genus`` command, or you'll get an error message.
198
+
199
+ EXAMPLES::
200
+
201
+ sage: singular.lib('normal.lib')
202
+ sage: R = singular.ring(0,'(x,y)','dp')
203
+ sage: i2 = singular.ideal('y9 - x2*(x-1)^9 + x')
204
+ sage: i2.genus()
205
+ 40
206
+
207
+ Note that the genus can be much smaller than the degree::
208
+
209
+ sage: i = singular.ideal('y9 - x2*(x-1)^9')
210
+ sage: i.genus()
211
+ 0
212
+
213
+ An Important Concept
214
+ --------------------
215
+
216
+ The following illustrates an important concept: how Sage interacts
217
+ with the data being used and returned by Singular. Let's compute a
218
+ Groebner basis for some ideal, using Singular through Sage.
219
+
220
+ ::
221
+
222
+ sage: singular.lib('polylib.lib')
223
+ sage: singular.ring(32003, '(a,b,c,d,e,f)', 'lp')
224
+ polynomial ring, over a field, global ordering
225
+ // coefficients: ZZ/32003...
226
+ // number of vars : 6
227
+ // block 1 : ordering lp
228
+ // : names a b c d e f
229
+ // block 2 : ordering C
230
+ sage: I = singular.ideal('cyclic(6)')
231
+ sage: g = singular('groebner(I)')
232
+ Traceback (most recent call last):
233
+ ...
234
+ TypeError: Singular error:
235
+ ...
236
+
237
+ We restart everything and try again, but correctly.
238
+
239
+ ::
240
+
241
+ sage: singular.quit()
242
+ sage: singular.lib('polylib.lib'); R = singular.ring(32003, '(a,b,c,d,e,f)', 'lp')
243
+ sage: I = singular.ideal('cyclic(6)')
244
+ sage: I.groebner()
245
+ f^48-2554*f^42-15674*f^36+12326*f^30-12326*f^18+15674*f^12+2554*f^6-1,
246
+ ...
247
+
248
+ It's important to understand why the first attempt at computing a
249
+ basis failed. The line where we gave singular the input
250
+ 'groebner(I)' was useless because Singular has no idea what 'I' is!
251
+ Although 'I' is an object that we computed with calls to Singular
252
+ functions, it actually lives in Sage. As a consequence, the name
253
+ 'I' means nothing to Singular. When we called
254
+ ``I.groebner()``, Sage was able to call the groebner
255
+ function on 'I' in Singular, since 'I' actually means something to
256
+ Sage.
257
+
258
+ Long Input
259
+ ----------
260
+
261
+ The Singular interface reads in even very long input (using files)
262
+ in a robust manner, as long as you are creating a new object.
263
+
264
+ ::
265
+
266
+ sage: t = '"%s"'%10^15000 # 15 thousand character string (note that normal Singular input must be at most 10000)
267
+ sage: a = singular.eval(t)
268
+ sage: a = singular(t)
269
+
270
+ TESTS:
271
+
272
+ We test an automatic coercion::
273
+
274
+ sage: a = 3*singular('2'); a
275
+ 6
276
+ sage: type(a)
277
+ <class 'sage.interfaces.singular.SingularElement'>
278
+ sage: a = singular('2')*3; a
279
+ 6
280
+ sage: type(a)
281
+ <class 'sage.interfaces.singular.SingularElement'>
282
+
283
+ Create a ring over GF(9) to check that ``gftables`` has been installed,
284
+ see :issue:`11645`::
285
+
286
+ sage: singular.eval("ring testgf9 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp);")
287
+ ''
288
+
289
+ Verify that :issue:`17720` is fixed::
290
+
291
+ sage: R.<p> = QQ[]
292
+ sage: K.<p> = QQ.extension(p^2 - p - 1)
293
+ sage: r.<x,z> = K[]
294
+ sage: I = r.ideal(z)
295
+ sage: I.primary_decomposition()
296
+ [Ideal (z) of Multivariate Polynomial Ring in x, z over Number Field in p with defining polynomial p^2 - p - 1]
297
+ sage: [ J.gens() for J in I.primary_decomposition("gtz")]
298
+ [[z]]
299
+
300
+ AUTHORS:
301
+
302
+ - David Joyner and William Stein (2005): first version
303
+
304
+ - Neal Harris (unknown): perhaps added "An Important Concept"
305
+
306
+ - Martin Albrecht (2006-03-05): code so singular.[tab] and x =
307
+ singular(...), x.[tab] includes all singular commands.
308
+
309
+ - Martin Albrecht (2006-03-06): This patch adds the equality symbol to
310
+ singular. Also fix a problem in which " " as prompt means comparison
311
+ will break all further communication with Singular.
312
+
313
+ - Martin Albrecht (2006-03-13): added current_ring() and
314
+ current_ring_name()
315
+
316
+ - William Stein (2006-04-10): Fixed problems with ideal constructor
317
+
318
+ - Martin Albrecht (2006-05-18): added sage_poly.
319
+
320
+ - Simon King (2010-11-23): Reduce the overhead caused by waiting for
321
+ the Singular prompt by doing garbage collection differently.
322
+
323
+ - Simon King (2011-06-06): Make conversion from Singular to Sage more flexible.
324
+
325
+ - Simon King (2015): Extend pickling capabilities.
326
+ """
327
+
328
+ # ****************************************************************************
329
+ # Copyright (C) 2005 David Joyner and William Stein
330
+ #
331
+ # This program is free software: you can redistribute it and/or modify
332
+ # it under the terms of the GNU General Public License as published by
333
+ # the Free Software Foundation, either version 2 of the License, or
334
+ # (at your option) any later version.
335
+ # https://www.gnu.org/licenses/
336
+ # ****************************************************************************
337
+
338
+ import os
339
+ import platform
340
+ import re
341
+ import sys
342
+ import pexpect
343
+ import shlex
344
+ import time
345
+
346
+ from .expect import Expect, ExpectElement, FunctionElement, ExpectFunction
347
+
348
+ import sage.interfaces.abc
349
+
350
+ from sage.interfaces.tab_completion import ExtraTabCompletion
351
+ from sage.structure.sequence import Sequence_generic
352
+ from sage.structure.element import RingElement
353
+ import sage.features.singular
354
+
355
+ import sage.rings.integer
356
+
357
+ from sage.misc.verbose import get_verbose
358
+ from sage.misc.instancedoc import instancedoc
359
+
360
+
361
+ class SingularError(RuntimeError):
362
+ """
363
+ Raised if Singular printed an error message
364
+ """
365
+ pass
366
+
367
+
368
+ class Singular(ExtraTabCompletion, Expect):
369
+ r"""
370
+ Interface to the Singular interpreter.
371
+
372
+ EXAMPLES: A Groebner basis example.
373
+
374
+ ::
375
+
376
+ sage: R = singular.ring(0, '(x0,x1,x2)', 'lp')
377
+ sage: I = singular.ideal([ 'x0*x1*x2 -x0^2*x2', 'x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2', 'x0*x1-x0*x2-x1*x2'])
378
+ sage: I.groebner()
379
+ x1^2*x2^2,
380
+ x0*x2^3-x1^2*x2^2+x1*x2^3,
381
+ x0*x1-x0*x2-x1*x2,
382
+ x0^2*x2-x0*x2^2-x1*x2^2
383
+
384
+ AUTHORS:
385
+
386
+ - David Joyner and William Stein
387
+ """
388
+ def __init__(self, maxread=None, script_subdirectory=None,
389
+ logfile=None, server=None, server_tmpdir=None,
390
+ seed=None):
391
+ """
392
+ EXAMPLES::
393
+
394
+ sage: singular == loads(dumps(singular))
395
+ True
396
+ """
397
+ prompt = '> '
398
+ Expect.__init__(self,
399
+ terminal_echo=False,
400
+ name='singular',
401
+ prompt=prompt,
402
+ # no tty, fine grained cputime()
403
+ # and do not display CTRL-C prompt
404
+ command="{} -t --ticks-per-sec 1000 --cntrlc=a".format(
405
+ shlex.quote(sage.features.singular.Singular().absolute_filename())),
406
+ server=server,
407
+ server_tmpdir=server_tmpdir,
408
+ script_subdirectory=script_subdirectory,
409
+ restart_on_ctrlc=True,
410
+ verbose_start=False,
411
+ logfile=logfile,
412
+ eval_using_file_cutoff=100 if platform.system() == "SunOS" else 1000)
413
+ self.__libs = []
414
+ self._prompt_wait = prompt
415
+ self.__to_clear = [] # list of variable names that need to be cleared.
416
+ self._seed = seed
417
+
418
+ def set_seed(self, seed=None):
419
+ """
420
+ Set the seed for singular interpreter.
421
+
422
+ The seed should be an integer at least 1
423
+ and not more than 30 bits.
424
+ See
425
+ http://www.singular.uni-kl.de/Manual/html/sing_19.htm#SEC26
426
+ and
427
+ http://www.singular.uni-kl.de/Manual/html/sing_283.htm#SEC323
428
+
429
+ EXAMPLES::
430
+
431
+ sage: s = Singular()
432
+ sage: s.set_seed(1)
433
+ 1
434
+ sage: [s.random(1,10) for i in range(5)]
435
+ [8, 10, 4, 9, 1]
436
+ """
437
+ if seed is None:
438
+ seed = self.rand_seed()
439
+ self.eval('system("--random",%d)' % seed)
440
+ self._seed = seed
441
+ return seed
442
+
443
+ def _start(self, alt_message=None):
444
+ """
445
+ EXAMPLES::
446
+
447
+ sage: s = Singular()
448
+ sage: s.is_running()
449
+ False
450
+ sage: s._start()
451
+ sage: s.is_running()
452
+ True
453
+ sage: s.quit()
454
+ """
455
+ self.__libs = []
456
+ Expect._start(self, alt_message)
457
+ # Load some standard libraries.
458
+ self.lib('general') # assumed loaded by misc/constants.py
459
+
460
+ # these options are required by the new coefficient rings
461
+ # supported by Singular 3-1-0.
462
+ self.option("redTail")
463
+ self.option("redThrough")
464
+ self.option("intStrategy")
465
+ self._saved_options = self.option('get')
466
+ # set random seed
467
+ self.set_seed(self._seed)
468
+
469
+ def __reduce__(self):
470
+ """
471
+ EXAMPLES::
472
+
473
+ sage: from sage.interfaces.singular import singular
474
+ sage: singular.__reduce__()
475
+ (<function reduce_load_Singular at 0x...>, ())
476
+ """
477
+ return reduce_load_Singular, ()
478
+
479
+ def _equality_symbol(self):
480
+ """
481
+ EXAMPLES::
482
+
483
+ sage: singular._equality_symbol()
484
+ '=='
485
+ """
486
+ return '=='
487
+
488
+ def _true_symbol(self):
489
+ """
490
+ EXAMPLES::
491
+
492
+ sage: singular._true_symbol()
493
+ '1'
494
+ """
495
+ return '1'
496
+
497
+ def _false_symbol(self):
498
+ """
499
+ EXAMPLES::
500
+
501
+ sage: singular._false_symbol()
502
+ '0'
503
+ """
504
+ return '0'
505
+
506
+ def _quit_string(self):
507
+ """
508
+ EXAMPLES::
509
+
510
+ sage: singular._quit_string()
511
+ 'quit;'
512
+ """
513
+ return 'quit;'
514
+
515
+ def _send_interrupt(self):
516
+ """
517
+ Send an interrupt to Singular. If needed, additional
518
+ semi-colons are sent until we get back at the prompt.
519
+
520
+ TESTS:
521
+
522
+ The following works without restarting Singular::
523
+
524
+ sage: a = singular(1)
525
+ sage: _ = singular._expect.sendline('while(1){};')
526
+ sage: singular.interrupt()
527
+ True
528
+
529
+ We can still access a::
530
+
531
+ sage: 2*a
532
+ 2
533
+
534
+ Interrupting nothing or unfinished input also works::
535
+
536
+ sage: singular.interrupt()
537
+ True
538
+ sage: _ = singular._expect.sendline('1+')
539
+ sage: singular.interrupt()
540
+ True
541
+ sage: 3*a
542
+ 3
543
+ """
544
+ # Work around for Singular bug
545
+ # http://www.singular.uni-kl.de:8002/trac/ticket/727
546
+ time.sleep(0.1)
547
+
548
+ E = self._expect
549
+ E.sendline(chr(3))
550
+ # The following is needed so interrupt() works even when
551
+ # there is no computation going on.
552
+ for i in range(5):
553
+ try:
554
+ E.expect_upto(self._prompt, timeout=0.1)
555
+ return
556
+ except pexpect.TIMEOUT:
557
+ pass
558
+ E.sendline(";")
559
+
560
+ def _read_in_file_command(self, filename):
561
+ r"""
562
+ EXAMPLES::
563
+
564
+ sage: singular._read_in_file_command('test')
565
+ '< "...";'
566
+
567
+ sage: filename = tmp_filename()
568
+ sage: f = open(filename, 'w')
569
+ sage: _ = f.write('int x = 2;\n')
570
+ sage: f.close()
571
+ sage: singular.read(filename)
572
+ sage: singular.get('x')
573
+ '2'
574
+ """
575
+ return '< "%s";' % filename
576
+
577
+ def eval(self, x, allow_semicolon=True, strip=True, **kwds):
578
+ r"""
579
+ Send the code x to the Singular interpreter and return the output
580
+ as a string.
581
+
582
+ INPUT:
583
+
584
+ - ``x`` -- string (of code)
585
+
586
+ - ``allow_semicolon`` -- (default: ``False``) if ``False`` then
587
+ raise a :exc:`TypeError` if the input line contains a semicolon
588
+
589
+ - ``strip`` -- ignored
590
+
591
+ EXAMPLES::
592
+
593
+ sage: singular.eval('2 > 1')
594
+ '1'
595
+ sage: singular.eval('2 + 2')
596
+ '4'
597
+
598
+ if the verbosity level is `> 1` comments are also printed
599
+ and not only returned.
600
+
601
+ ::
602
+
603
+ sage: r = singular.ring(0,'(x,y,z)','dp')
604
+ sage: i = singular.ideal(['x^2','y^2','z^2'])
605
+ sage: s = i.std()
606
+ sage: singular.eval('hilb(%s)'%(s.name()))
607
+ '...// dimension (affine) = 0\n//
608
+ degree (affine) = 8'
609
+
610
+ ::
611
+
612
+ sage: from sage.misc.verbose import set_verbose
613
+ sage: set_verbose(1)
614
+ sage: o = singular.eval('hilb(%s)'%(s.name()))
615
+ ...// dimension (affine) = 0
616
+ // degree (affine) = 8
617
+
618
+ This is mainly useful if this method is called implicitly. Because
619
+ then intermediate results, debugging outputs and printed statements
620
+ are printed
621
+
622
+ ::
623
+
624
+ sage: o = s.hilb()
625
+ ...// dimension (affine) = 0
626
+ // degree (affine) = 8
627
+ // ** right side is not a datum, assignment ignored
628
+ ...
629
+
630
+ rather than ignored
631
+
632
+ ::
633
+
634
+ sage: set_verbose(0)
635
+ sage: o = s.hilb()
636
+ """
637
+ # Simon King:
638
+ # In previous versions, the interface was first synchronised and then
639
+ # unused variables were killed. This created a considerable overhead.
640
+ # By github issue #10296, killing unused variables is now done inside
641
+ # singular.set(). Moreover, it is not done by calling a separate _eval_line.
642
+ # In that way, the time spent by waiting for the singular prompt is reduced.
643
+
644
+ # Before #10296, it was possible that garbage collection occurred inside
645
+ # of _eval_line. But collection of the garbage would launch another call
646
+ # to _eval_line. The result would have been a dead lock, that could only
647
+ # be avoided by synchronisation. Since garbage collection is now done
648
+ # without an additional call to _eval_line, synchronisation is not
649
+ # needed anymore, saving even more waiting time for the prompt.
650
+
651
+ # Uncomment the print statements below for low-level debugging of
652
+ # code that involves the singular interfaces. Everything goes
653
+ # through here.
654
+
655
+ x = str(x).rstrip().rstrip(';')
656
+ x = x.replace("> ", ">\t") # don't send a prompt (added by Martin Albrecht)
657
+ if not allow_semicolon and x.find(";") != -1:
658
+ raise TypeError("singular input must not contain any semicolons:\n%s" % x)
659
+ if len(x) == 0 or x[len(x) - 1] != ';':
660
+ x += ';'
661
+
662
+ s = Expect.eval(self, x, **kwds)
663
+
664
+ # "Segment fault" is not a typo:
665
+ # Singular actually does use that string
666
+ if s.find("error occurred") != -1 or s.find("Segment fault") != -1:
667
+ raise SingularError('Singular error:\n%s' % s)
668
+
669
+ if get_verbose() > 0:
670
+ for line in s.splitlines():
671
+ if line.startswith("//"):
672
+ print(line)
673
+ return s
674
+ else:
675
+ return s
676
+
677
+ def set(self, type, name, value):
678
+ """
679
+ Set the variable with given name to the given value.
680
+
681
+ REMARK:
682
+
683
+ If a variable in the Singular interface was previously marked for
684
+ deletion, the actual deletion is done here, before the new variable
685
+ is created in Singular.
686
+
687
+ EXAMPLES::
688
+
689
+ sage: singular.set('int', 'x', '2')
690
+ sage: singular.get('x')
691
+ '2'
692
+
693
+ We test that an unused variable is only actually deleted if this method
694
+ is called::
695
+
696
+ sage: a = singular(3)
697
+ sage: n = a.name()
698
+ sage: del a
699
+ sage: singular.eval(n)
700
+ '3'
701
+ sage: singular.set('int', 'y', '5')
702
+ sage: singular.eval('defined(%s)'%n)
703
+ '0'
704
+ """
705
+ cmd = ''.join('if(defined(%s)){kill %s;};' % (v, v)
706
+ for v in self.__to_clear)
707
+ cmd += '%s %s=%s;' % (type, name, value)
708
+ self.__to_clear = []
709
+ self.eval(cmd)
710
+
711
+ def get(self, var):
712
+ """
713
+ Get string representation of variable named var.
714
+
715
+ EXAMPLES::
716
+
717
+ sage: singular.set('int', 'x', '2')
718
+ sage: singular.get('x')
719
+ '2'
720
+ """
721
+ return self.eval('print(%s);' % var)
722
+
723
+ def clear(self, var):
724
+ """
725
+ Clear the variable named ``var``.
726
+
727
+ EXAMPLES::
728
+
729
+ sage: singular.set('int', 'x', '2')
730
+ sage: singular.get('x')
731
+ '2'
732
+ sage: singular.clear('x')
733
+
734
+ "Clearing the variable" means to allow to free the memory
735
+ that it uses in the Singular sub-process. However, the
736
+ actual deletion of the variable is only committed when
737
+ the next element in the Singular interface is created::
738
+
739
+ sage: singular.get('x')
740
+ '2'
741
+ sage: a = singular(3)
742
+ sage: singular.get('x')
743
+ '`x`'
744
+ """
745
+ # We add the variable to the list of vars to clear when we do an eval.
746
+ # We queue up all the clears and do them at once to avoid synchronizing
747
+ # the interface at the same time we do garbage collection, which can
748
+ # lead to subtle problems. This was Willem Jan's ideas, implemented
749
+ # by William Stein.
750
+ self.__to_clear.append(var)
751
+
752
+ def _create(self, value, type='def'):
753
+ """
754
+ Create a new variable in the Singular session and returns the name
755
+ of that variable.
756
+
757
+ EXAMPLES::
758
+
759
+ sage: singular._create('2', type='int')
760
+ 'sage...'
761
+ sage: singular.get(_)
762
+ '2'
763
+ """
764
+ name = self._next_var_name()
765
+ self.set(type, name, value)
766
+ return name
767
+
768
+ def __call__(self, x, type='def'):
769
+ """
770
+ Create a singular object X with given type determined by the string
771
+ x. This returns var, where var is built using the Singular
772
+ statement type var = ... x ... Note that the actual name of var
773
+ could be anything, and can be recovered using X.name().
774
+
775
+ The object X returned can be used like any Sage object, and wraps
776
+ an object in ``self``. The standard arithmetic operators work. Moreover
777
+ if foo is a function then X.foo(y,z,...) calls foo(X, y, z, ...)
778
+ and returns the corresponding object.
779
+
780
+ EXAMPLES::
781
+
782
+ sage: R = singular.ring(0, '(x0,x1,x2)', 'lp')
783
+ sage: I = singular.ideal([ 'x0*x1*x2 -x0^2*x2', 'x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2', 'x0*x1-x0*x2-x1*x2'])
784
+ sage: I
785
+ -x0^2*x2+x0*x1*x2,
786
+ x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2,
787
+ x0*x1-x0*x2-x1*x2
788
+ sage: type(I)
789
+ <class 'sage.interfaces.singular.SingularElement'>
790
+ sage: I.parent()
791
+ Singular
792
+ """
793
+ if isinstance(x, SingularElement) and x.parent() is self:
794
+ return x
795
+ elif isinstance(x, ExpectElement):
796
+ return self(x.sage())
797
+ elif not isinstance(x, ExpectElement) and hasattr(x, '_singular_'):
798
+ return x._singular_(self)
799
+
800
+ # some convenient conversions
801
+ if type in ("module", "list") and isinstance(x, (list, tuple, Sequence_generic)):
802
+ x = str(x)[1:-1]
803
+
804
+ return SingularElement(self, type, x, False)
805
+
806
+ def _coerce_map_from_(self, S):
807
+ """
808
+ Return ``True`` if ``S`` admits a coercion map into the
809
+ Singular interface.
810
+
811
+ EXAMPLES::
812
+
813
+ sage: singular._coerce_map_from_(ZZ)
814
+ True
815
+ sage: singular.coerce_map_from(ZZ)
816
+ Call morphism:
817
+ From: Integer Ring
818
+ To: Singular
819
+ sage: singular.coerce_map_from(float)
820
+ """
821
+ # we want to implement this without coercing, since singular has state.
822
+ if hasattr(S, 'an_element'):
823
+ if hasattr(S.an_element(), '_singular_'):
824
+ return True
825
+ elif S is int:
826
+ return True
827
+ return None
828
+
829
+ def cputime(self, t=None):
830
+ r"""
831
+ Return the amount of CPU time that the Singular session has used.
832
+ If ``t`` is not None, then it returns the difference
833
+ between the current CPU time and ``t``.
834
+
835
+ EXAMPLES::
836
+
837
+ sage: t = singular.cputime()
838
+ sage: R = singular.ring(0, '(x0,x1,x2)', 'lp')
839
+ sage: I = singular.ideal([ 'x0*x1*x2 -x0^2*x2', 'x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2', 'x0*x1-x0*x2-x1*x2'])
840
+ sage: gb = I.groebner()
841
+ sage: singular.cputime(t) #random
842
+ 0.02
843
+ """
844
+ if t:
845
+ return float(self.eval('timer-(%d)' % (int(1000 * t)))) / 1000.0
846
+ else:
847
+ return float(self.eval('timer')) / 1000.0
848
+
849
+ ###########################################################
850
+ # Singular libraries
851
+ ###########################################################
852
+ def lib(self, lib, reload=False):
853
+ """
854
+ Load the Singular library named lib.
855
+
856
+ Note that if the library was already loaded during this session it
857
+ is not reloaded unless the optional reload argument is ``True`` (the
858
+ default is ``False``).
859
+
860
+ EXAMPLES::
861
+
862
+ sage: singular.lib('sing.lib')
863
+ sage: singular.lib('sing.lib', reload=True)
864
+ """
865
+ if lib[-4:] != ".lib":
866
+ lib += ".lib"
867
+ if not reload and lib in self.__libs:
868
+ return
869
+ self.eval('LIB "%s"' % lib)
870
+ self.__libs.append(lib)
871
+
872
+ LIB = lib
873
+ load = lib
874
+
875
+ ##########################################################
876
+ # constructors
877
+ ##########################################################
878
+ def ideal(self, *gens):
879
+ """
880
+ Return the ideal generated by gens.
881
+
882
+ INPUT:
883
+
884
+ - ``gens`` -- list or tuple of Singular objects (or
885
+ objects that can be made into Singular objects via evaluation)
886
+
887
+ OUTPUT: the Singular ideal generated by the given list of gens
888
+
889
+ EXAMPLES: A Groebner basis example done in a different way.
890
+
891
+ ::
892
+
893
+ sage: _ = singular.eval("ring R=0,(x0,x1,x2),lp")
894
+ sage: i1 = singular.ideal([ 'x0*x1*x2 -x0^2*x2', 'x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2', 'x0*x1-x0*x2-x1*x2'])
895
+ sage: i1
896
+ -x0^2*x2+x0*x1*x2,
897
+ x0^2*x1*x2-x0*x1^2*x2-x0*x1*x2^2,
898
+ x0*x1-x0*x2-x1*x2
899
+
900
+ ::
901
+
902
+ sage: i2 = singular.ideal('groebner(%s);'%i1.name())
903
+ sage: i2
904
+ x1^2*x2^2,
905
+ x0*x2^3-x1^2*x2^2+x1*x2^3,
906
+ x0*x1-x0*x2-x1*x2,
907
+ x0^2*x2-x0*x2^2-x1*x2^2
908
+ """
909
+ if isinstance(gens, str):
910
+ gens = self(gens)
911
+
912
+ if isinstance(gens, SingularElement):
913
+ return self(gens.name(), 'ideal')
914
+
915
+ if not isinstance(gens, (list, tuple)):
916
+ raise TypeError("gens (=%s) must be a list, tuple, string, or Singular element" % gens)
917
+
918
+ if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
919
+ gens = gens[0]
920
+ gens2 = []
921
+ for g in gens:
922
+ if not isinstance(g, SingularElement):
923
+ gens2.append(self.new(g))
924
+ else:
925
+ gens2.append(g)
926
+ return self(",".join(g.name() for g in gens2), 'ideal')
927
+
928
+ def list(self, x):
929
+ r"""
930
+ Create a list in Singular from a Sage list ``x``.
931
+
932
+ EXAMPLES::
933
+
934
+ sage: singular.list([1,2])
935
+ [1]:
936
+ 1
937
+ [2]:
938
+ 2
939
+
940
+ sage: singular.list([1,2,[3,4]])
941
+ [1]:
942
+ 1
943
+ [2]:
944
+ 2
945
+ [3]:
946
+ [1]:
947
+ 3
948
+ [2]:
949
+ 4
950
+
951
+ sage: R.<x,y> = QQ[]
952
+ sage: singular.list([1,2,[x,ideal(x,y)]])
953
+ [1]:
954
+ 1
955
+ [2]:
956
+ 2
957
+ [3]:
958
+ [1]:
959
+ x
960
+ [2]:
961
+ _[1]=x
962
+ _[2]=y
963
+
964
+ Strings have to be escaped before passing them to this method::
965
+
966
+ sage: singular.list([1,2,'"hi"'])
967
+ [1]:
968
+ 1
969
+ [2]:
970
+ 2
971
+ [3]:
972
+ hi
973
+
974
+ TESTS:
975
+
976
+ Check that a list already converted to Singular can be
977
+ embedded into a list to be converted::
978
+
979
+ sage: singular.list([1, 2, singular.list([3, 4])])
980
+ [1]:
981
+ 1
982
+ [2]:
983
+ 2
984
+ [3]:
985
+ [1]:
986
+ 3
987
+ [2]:
988
+ 4
989
+ """
990
+
991
+ # We have to be careful about object destruction.
992
+
993
+ # If we convert an object to a Singular element, the only
994
+ # thing that goes into the list definition statement is the
995
+ # Singular variable name, so we need to keep the element
996
+ # around long enough to ensure that the variable still exists
997
+ # when we create the list. We ensure this by putting created
998
+ # elements on a list, which gets destroyed when this function
999
+ # returns, by which time the list has been created.
1000
+
1001
+ singular_elements = []
1002
+
1003
+ def strify(x):
1004
+ if isinstance(x, (list, tuple, Sequence_generic)):
1005
+ return 'list(' + ','.join(strify(i) for i in x) + ')'
1006
+ elif isinstance(x, SingularElement):
1007
+ return x.name()
1008
+ elif isinstance(x, (int, sage.rings.integer.Integer)):
1009
+ return repr(x)
1010
+ elif hasattr(x, '_singular_'):
1011
+ e = x._singular_()
1012
+ singular_elements.append(e)
1013
+ return e.name()
1014
+ else:
1015
+ return str(x)
1016
+
1017
+ return self(strify(x), 'list')
1018
+
1019
+ def matrix(self, nrows, ncols, entries=None):
1020
+ """
1021
+ EXAMPLES::
1022
+
1023
+ sage: singular.lib("matrix")
1024
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1025
+ sage: A = singular.matrix(3,2,'1,2,3,4,5,6')
1026
+ sage: A
1027
+ 1,2,
1028
+ 3,4,
1029
+ 5,6
1030
+ sage: A.gauss_col()
1031
+ 2,-1,
1032
+ 1,0,
1033
+ 0,1
1034
+
1035
+ AUTHORS:
1036
+
1037
+ - Martin Albrecht (2006-01-14)
1038
+ """
1039
+ name = self._next_var_name()
1040
+ if entries is None:
1041
+ self.eval('matrix %s[%s][%s]' % (name, nrows, ncols))
1042
+ else:
1043
+ self.eval('matrix %s[%s][%s] = %s' % (name, nrows, ncols, entries))
1044
+ return SingularElement(self, None, name, True)
1045
+
1046
+ def ring(self, char=0, vars='(x)', order='lp', check=None):
1047
+ r"""
1048
+ Create a Singular ring and makes it the current ring.
1049
+
1050
+ INPUT:
1051
+
1052
+ - ``char`` -- string; a string specifying the characteristic
1053
+ of the base ring, in the format accepted by Singular (see
1054
+ examples below)
1055
+
1056
+ - ``vars`` -- tuple or string defining the variable names
1057
+
1058
+ - ``order`` -- string; the monomial order (default: ``'lp'``)
1059
+
1060
+ OUTPUT: a Singular ring
1061
+
1062
+ .. NOTE::
1063
+
1064
+ This function is *not* identical to calling the Singular
1065
+ ``ring`` function. In particular, it also attempts to
1066
+ "kill" the variable names, so they can actually be used
1067
+ without getting errors, and it sets printing of elements
1068
+ for this range to short (i.e., with \*'s and carets).
1069
+
1070
+ EXAMPLES: We first declare `\QQ[x,y,z]` with degree reverse
1071
+ lexicographic ordering.
1072
+
1073
+ ::
1074
+
1075
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1076
+ sage: R
1077
+ polynomial ring, over a field, global ordering
1078
+ // coefficients: QQ...
1079
+ // number of vars : 3
1080
+ // block 1 : ordering dp
1081
+ // : names x y z
1082
+ // block 2 : ordering C
1083
+
1084
+ ::
1085
+
1086
+ sage: R1 = singular.ring(32003, '(x,y,z)', 'dp')
1087
+ sage: R2 = singular.ring(32003, '(a,b,c,d)', 'lp')
1088
+
1089
+ This is a ring in variables named x(1) through x(10) over the
1090
+ finite field of order `7`::
1091
+
1092
+ sage: R3 = singular.ring(7, '(x(1..10))', 'ds')
1093
+
1094
+ This is a polynomial ring over the transcendental extension
1095
+ `\QQ(a)` of `\QQ`::
1096
+
1097
+ sage: R4 = singular.ring('(0,a)', '(mu,nu)', 'lp')
1098
+
1099
+ This is a ring over the field of single-precision floats::
1100
+
1101
+ sage: R5 = singular.ring('real', '(a,b)', 'lp')
1102
+
1103
+ This is over 50-digit floats::
1104
+
1105
+ sage: R6 = singular.ring('(real,50)', '(a,b)', 'lp')
1106
+ sage: R7 = singular.ring('(complex,50,i)', '(a,b)', 'lp')
1107
+
1108
+ To use a ring that you've defined, use the set_ring() method on
1109
+ the ring. This sets the ring to be the "current ring". For
1110
+ example,
1111
+
1112
+ ::
1113
+
1114
+ sage: R = singular.ring(7, '(a,b)', 'ds')
1115
+ sage: S = singular.ring('real', '(a,b)', 'lp')
1116
+ sage: singular.new('10*a')
1117
+ (1.000e+01)*a
1118
+ sage: R.set_ring()
1119
+ sage: singular.new('10*a')
1120
+ 3*a
1121
+ """
1122
+ if len(vars) > 2:
1123
+ s = '; '.join('if(defined(%s)>0){kill %s;};' % (x, x)
1124
+ for x in vars[1:-1].split(','))
1125
+ self.eval(s)
1126
+
1127
+ if check is not None:
1128
+ from sage.misc.superseded import deprecation
1129
+ deprecation(33319, 'The check= keyword argument does nothing.' + f'({check})')
1130
+
1131
+ R = self('%s,%s,%s' % (char, vars, order), 'ring')
1132
+ self.eval('short=0') # make output include *'s for multiplication for *THIS* ring.
1133
+ return R
1134
+
1135
+ def string(self, x):
1136
+ """
1137
+ Create a Singular string from a Sage string. Note that the Sage
1138
+ string has to be "double-quoted".
1139
+
1140
+ EXAMPLES::
1141
+
1142
+ sage: singular.string('"Sage"')
1143
+ Sage
1144
+ """
1145
+ return self(x, 'string')
1146
+
1147
+ def set_ring(self, R):
1148
+ """
1149
+ Set the current Singular ring to `R`.
1150
+
1151
+ EXAMPLES::
1152
+
1153
+ sage: R = singular.ring(7, '(a,b)', 'ds')
1154
+ sage: S = singular.ring('real', '(a,b)', 'lp')
1155
+ sage: singular.current_ring()
1156
+ polynomial ring, over a field, global ordering
1157
+ // coefficients: Float()...
1158
+ // number of vars : 2
1159
+ // block 1 : ordering lp
1160
+ // : names a b
1161
+ // block 2 : ordering C
1162
+ sage: singular.set_ring(R)
1163
+ sage: singular.current_ring()
1164
+ polynomial ring, over a field, local ordering
1165
+ // coefficients: ZZ/7...
1166
+ // number of vars : 2
1167
+ // block 1 : ordering ds
1168
+ // : names a b
1169
+ // block 2 : ordering C
1170
+ """
1171
+ if not isinstance(R, SingularElement):
1172
+ raise TypeError("R must be a singular ring")
1173
+ self.eval("setring %s; short=0" % R.name(), allow_semicolon=True)
1174
+
1175
+ setring = set_ring
1176
+
1177
+ def current_ring_name(self):
1178
+ """
1179
+ Return the Singular name of the currently active ring in
1180
+ Singular.
1181
+
1182
+ OUTPUT: currently active ring's name
1183
+
1184
+ EXAMPLES::
1185
+
1186
+ sage: r = PolynomialRing(GF(127),3,'xyz')
1187
+ sage: r._singular_().name() == singular.current_ring_name()
1188
+ True
1189
+ """
1190
+ ringlist = self.eval("listvar(ring)").splitlines()
1191
+ p = re.compile(r"// ([a-zA-Z0-9_]*).*\[.*\].*\*.*") # do this in constructor?
1192
+ for line in ringlist:
1193
+ m = p.match(line)
1194
+ if m:
1195
+ return m.group(1)
1196
+ return None
1197
+
1198
+ def current_ring(self):
1199
+ """
1200
+ Return the current ring of the running Singular session.
1201
+
1202
+ EXAMPLES::
1203
+
1204
+ sage: r = PolynomialRing(GF(127),3,'xyz', order='invlex')
1205
+ sage: r._singular_()
1206
+ polynomial ring, over a field, global ordering
1207
+ // coefficients: ZZ/127...
1208
+ // number of vars : 3
1209
+ // block 1 : ordering ip
1210
+ // : names x y z
1211
+ // block 2 : ordering C
1212
+ sage: singular.current_ring()
1213
+ polynomial ring, over a field, global ordering
1214
+ // coefficients: ZZ/127...
1215
+ // number of vars : 3
1216
+ // block 1 : ordering ip
1217
+ // : names x y z
1218
+ // block 2 : ordering C
1219
+ """
1220
+ name = self.current_ring_name()
1221
+ if name:
1222
+ return self(name)
1223
+ else:
1224
+ return None
1225
+
1226
+ def _tab_completion(self) -> list:
1227
+ """
1228
+ Return a list of all Singular commands.
1229
+
1230
+ EXAMPLES::
1231
+
1232
+ sage: singular._tab_completion()
1233
+ ['exteriorPower',
1234
+ ...
1235
+ 'crossprod']
1236
+ """
1237
+ p = re.compile("// *([a-z0-9A-Z_]*).*") # compiles regular expression
1238
+ proclist = self.eval("listvar(proc)").splitlines()
1239
+ return [p.match(line).group(1) for line in proclist]
1240
+
1241
+ def console(self):
1242
+ r"""
1243
+ EXAMPLES::
1244
+
1245
+ sage: singular_console() #not tested
1246
+ SINGULAR / Development
1247
+ A Computer Algebra System for Polynomial Computations / version 3-0-4
1248
+ 0<
1249
+ by: G.-M. Greuel, G. Pfister, H. Schoenemann \ Nov 2007
1250
+ FB Mathematik der Universitaet, D-67653 Kaiserslautern \
1251
+ """
1252
+ singular_console()
1253
+
1254
+ def version(self):
1255
+ """
1256
+ Return the version of Singular being used.
1257
+
1258
+ EXAMPLES::
1259
+
1260
+ sage: singular.version()
1261
+ "Singular ... version 4...
1262
+ """
1263
+ return singular_version()
1264
+
1265
+ def _function_class(self):
1266
+ """
1267
+ EXAMPLES::
1268
+
1269
+ sage: singular._function_class()
1270
+ <class 'sage.interfaces.singular.SingularFunction'>
1271
+ """
1272
+ return SingularFunction
1273
+
1274
+ def _function_element_class(self):
1275
+ """
1276
+ EXAMPLES::
1277
+
1278
+ sage: singular._function_element_class()
1279
+ <class 'sage.interfaces.singular.SingularFunctionElement'>
1280
+ """
1281
+ return SingularFunctionElement
1282
+
1283
+ def option(self, cmd=None, val=None):
1284
+ """
1285
+ Access to Singular's options as follows:
1286
+
1287
+ Syntax: option() Returns a string of all defined options.
1288
+
1289
+ Syntax: option( 'option_name' ) Sets an option. Note to disable an
1290
+ option, use the prefix no.
1291
+
1292
+ Syntax: option( 'get' ) Returns an intvec of the state of all
1293
+ options.
1294
+
1295
+ Syntax: option( 'set', intvec_expression ) Restores the state of
1296
+ all options from an intvec (produced by option('get')).
1297
+
1298
+ EXAMPLES::
1299
+
1300
+ sage: singular.option()
1301
+ //options: redefine loadLib usage prompt
1302
+ sage: singular.option('get')
1303
+ 0,
1304
+ 10321
1305
+ sage: old_options = _
1306
+ sage: singular.option('noredefine')
1307
+ sage: singular.option()
1308
+ //options: loadLib usage prompt
1309
+ sage: singular.option('set', old_options)
1310
+ sage: singular.option('get')
1311
+ 0,
1312
+ 10321
1313
+ """
1314
+ if cmd is None:
1315
+ return SingularFunction(self, "option")()
1316
+ elif cmd == "get":
1317
+ # return SingularFunction(self, "option")("\"get\"")
1318
+ return self(self.eval("option(get)"), "intvec")
1319
+ elif cmd == "set":
1320
+ if not isinstance(val, SingularElement):
1321
+ raise TypeError("singular.option('set') needs SingularElement as second parameter")
1322
+ # SingularFunction(self,"option")("\"set\"",val)
1323
+ self.eval("option(set,%s)" % val.name())
1324
+ else:
1325
+ SingularFunction(self, "option")(f'"{str(cmd)}"')
1326
+
1327
+ def _keyboard_interrupt(self):
1328
+ print("Interrupting %s..." % self)
1329
+ try:
1330
+ self._expect.sendline(chr(4))
1331
+ except pexpect.ExceptionPexpect as msg:
1332
+ raise pexpect.ExceptionPexpect("THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg)
1333
+ self._start()
1334
+ raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self)
1335
+
1336
+
1337
+ @instancedoc
1338
+ class SingularElement(ExtraTabCompletion, ExpectElement, sage.interfaces.abc.SingularElement):
1339
+
1340
+ def __init__(self, parent, type, value, is_name=False):
1341
+ """
1342
+ EXAMPLES::
1343
+
1344
+ sage: a = singular(2)
1345
+ sage: loads(dumps(a))
1346
+ 2
1347
+ """
1348
+ RingElement.__init__(self, parent)
1349
+ if parent is None:
1350
+ return
1351
+ if not is_name:
1352
+ try:
1353
+ self._name = parent._create(value, type)
1354
+ # Convert SingularError to TypeError for
1355
+ # coercion to work properly.
1356
+ except SingularError as x:
1357
+ self._session_number = -1
1358
+ raise TypeError(x)
1359
+ except BaseException:
1360
+ self._session_number = -1
1361
+ raise
1362
+ else:
1363
+ self._name = value
1364
+ self._session_number = parent._session_number
1365
+
1366
+ def _repr_(self):
1367
+ r"""
1368
+ Return string representation of ``self``.
1369
+
1370
+ EXAMPLES::
1371
+
1372
+ sage: r = singular.ring(0,'(x,y)','dp')
1373
+ sage: singular(0)
1374
+ 0
1375
+ sage: singular('x') # indirect doctest
1376
+ x
1377
+ sage: singular.matrix(2,2)
1378
+ 0,0,
1379
+ 0,0
1380
+ sage: singular.matrix(2,2,"(25/47*x^2*y^4 + 63/127*x + 27)^3,y,0,1")
1381
+ 15625/103823*x^6*y.., y,
1382
+ 0, 1
1383
+
1384
+ Note that the output is truncated, and if ``self`` has a custom name then
1385
+ it is used to print the items of the matrix, rather than abbreviating its
1386
+ contents::
1387
+
1388
+ sage: M = singular.matrix(2,2,"(25/47*x^2*y^4 + 63/127*x + 27)^3,y,0,1")
1389
+ sage: M.rename('T')
1390
+ sage: M
1391
+ T[1,1],y,
1392
+ 0, 1
1393
+ """
1394
+ s = super()._repr_()
1395
+ if self._name in s:
1396
+ if self.get_custom_name() is None and self.type() == 'matrix':
1397
+ s = self.parent().eval('pmat(%s,20)' % (self.name()))
1398
+ # compatibility for singular 4.3.2p10 and before
1399
+ if s.startswith("polynomial ring,"):
1400
+ from sage.rings.polynomial.term_order import singular_name_mapping
1401
+ from sage.repl.rich_output import get_display_manager
1402
+ # this is our cue that singular uses `rp` instead of `ip`
1403
+ if singular_name_mapping['invlex'] == 'rp' and 'doctest' in str(get_display_manager()):
1404
+ s = re.sub('^(// .*block.* : ordering )rp$', '\\1ip',
1405
+ s, flags=re.MULTILINE)
1406
+ return s
1407
+
1408
+ def __copy__(self):
1409
+ r"""
1410
+ Return a copy of ``self``.
1411
+
1412
+ EXAMPLES::
1413
+
1414
+ sage: R=singular.ring(0,'(x,y)','dp')
1415
+ sage: M=singular.matrix(3,3,'0,0,-x, 0,y,0, x*y,0,0')
1416
+ sage: N=copy(M)
1417
+ sage: N[1,1]=singular('x+y')
1418
+ sage: N
1419
+ x+y,0,-x,
1420
+ 0, y,0,
1421
+ x*y,0,0
1422
+ sage: M
1423
+ 0, 0,-x,
1424
+ 0, y,0,
1425
+ x*y,0,0
1426
+ sage: L=R.ringlist()
1427
+ sage: L[4]=singular.ideal('x**2-5')
1428
+ sage: Q=L.ring()
1429
+ sage: otherR=singular.ring(5,'(x)','dp')
1430
+ sage: cpQ=copy(Q)
1431
+ sage: cpQ.set_ring()
1432
+ sage: cpQ
1433
+ polynomial ring, over a field, global ordering
1434
+ // coefficients: QQ...
1435
+ // number of vars : 2
1436
+ // block 1 : ordering dp
1437
+ // : names x y
1438
+ // block 2 : ordering C
1439
+ // quotient ring from ideal
1440
+ _[1]=x^2-5
1441
+ sage: R.fetch(M)
1442
+ 0, 0,-x,
1443
+ 0, y,0,
1444
+ x*y,0,0
1445
+ """
1446
+ if (self.type() == 'ring') or (self.type() == 'qring'):
1447
+ # Problem: singular has no clean method to produce
1448
+ # a copy of a ring/qring. We use ringlist, but this
1449
+ # is only possible if we make self the active ring,
1450
+ # use ringlist, and switch back to the previous
1451
+ # base ring.
1452
+ br = self.parent().current_ring()
1453
+ self.set_ring()
1454
+ OUT = (self.ringlist()).ring()
1455
+ br.set_ring()
1456
+ return OUT
1457
+ else:
1458
+ return self.parent()(self.name())
1459
+
1460
+ def __len__(self):
1461
+ """
1462
+ Return the size of this Singular element.
1463
+
1464
+ EXAMPLES::
1465
+
1466
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1467
+ sage: A = singular.matrix(2,2)
1468
+ sage: len(A)
1469
+ 4
1470
+ """
1471
+ return int(self.size())
1472
+
1473
+ def __setitem__(self, n, value):
1474
+ """
1475
+ Set the `n`-th element of ``self`` to `x`.
1476
+
1477
+ INPUT:
1478
+
1479
+ - ``n`` -- integer *or* a 2-tuple (for setting
1480
+ matrix elements)
1481
+
1482
+ - ``value`` -- anything (is coerced to a Singular
1483
+ object if it is not one already)
1484
+
1485
+ OUTPUT: changes elements of ``self``
1486
+
1487
+ EXAMPLES::
1488
+
1489
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1490
+ sage: A = singular.matrix(2,2)
1491
+ sage: A
1492
+ 0,0,
1493
+ 0,0
1494
+ sage: A[1,1] = 5
1495
+ sage: A
1496
+ 5,0,
1497
+ 0,0
1498
+ sage: A[1,2] = '5*x + y + z3'
1499
+ sage: A
1500
+ 5,z^3+5*x+y,
1501
+ 0,0
1502
+ """
1503
+ P = self.parent()
1504
+ if not isinstance(value, SingularElement):
1505
+ value = P(value)
1506
+ if isinstance(n, tuple):
1507
+ if len(n) != 2:
1508
+ raise ValueError("If n (=%s) is a tuple, it must be a 2-tuple" % n)
1509
+ x, y = n
1510
+ P.eval('%s[%s,%s] = %s' % (self.name(), x, y, value.name()))
1511
+ else:
1512
+ P.eval('%s[%s] = %s' % (self.name(), n, value.name()))
1513
+
1514
+ def __bool__(self):
1515
+ """
1516
+ Return ``True`` if this Singular element is not zero.
1517
+
1518
+ EXAMPLES::
1519
+
1520
+ sage: bool(singular(0))
1521
+ False
1522
+ sage: bool(singular(1))
1523
+ True
1524
+ """
1525
+ P = self.parent()
1526
+ return P.eval('%s == 0' % self.name()) == '0'
1527
+
1528
+ def sage_polystring(self):
1529
+ r"""
1530
+ If this Singular element is a polynomial, return a string
1531
+ representation of this polynomial that is suitable for evaluation
1532
+ in Python. Thus \* is used for multiplication and \*\* for
1533
+ exponentiation. This function is primarily used internally.
1534
+
1535
+ The short=0 option *must* be set for the parent ring or this
1536
+ function will not work as expected. This option is set by default
1537
+ for rings created using ``singular.ring`` or set using
1538
+ ``ring_name.set_ring()``.
1539
+
1540
+ EXAMPLES::
1541
+
1542
+ sage: R = singular.ring(0,'(x,y)')
1543
+ sage: f = singular('x^3 + 3*y^11 + 5')
1544
+ sage: f
1545
+ x^3+3*y^11+5
1546
+ sage: f.sage_polystring()
1547
+ 'x**3+3*y**11+5'
1548
+ """
1549
+ return str(self).replace('^', '**')
1550
+
1551
+ def sage_global_ring(self):
1552
+ """
1553
+ Return the current basering in Singular as a polynomial ring or quotient ring.
1554
+
1555
+ EXAMPLES::
1556
+
1557
+ sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)')
1558
+ ''
1559
+ sage: R = singular('r1').sage_global_ring()
1560
+ sage: R
1561
+ Multivariate Polynomial Ring in a, b, c, d, e, f over Finite Field in x of size 3^2
1562
+ sage: R.term_order()
1563
+ Block term order with blocks:
1564
+ (Matrix term order with matrix
1565
+ [1 2]
1566
+ [3 0],
1567
+ Weighted degree reverse lexicographic term order with weights (2, 3),
1568
+ Lexicographic term order of length 2)
1569
+
1570
+ ::
1571
+
1572
+ sage: singular.eval('ring r2 = (0,x),(a,b,c),dp')
1573
+ ''
1574
+ sage: singular('r2').sage_global_ring()
1575
+ Multivariate Polynomial Ring in a, b, c over Fraction Field of Univariate Polynomial Ring in x over Rational Field
1576
+
1577
+ ::
1578
+
1579
+ sage: singular.eval('ring r3 = (3,z),(a,b,c),dp')
1580
+ ''
1581
+ sage: singular.eval('minpoly = 1+z+z2+z3+z4')
1582
+ ''
1583
+ sage: singular('r3').sage_global_ring()
1584
+ Multivariate Polynomial Ring in a, b, c over Finite Field in z of size 3^4
1585
+
1586
+ Real and complex fields in both Singular and Sage are defined with a precision.
1587
+ The precision in Singular is given in terms of digits, but in Sage it is given
1588
+ in terms of bits. So, the digit precision is internally converted to a reasonable
1589
+ bit precision::
1590
+
1591
+ sage: singular.eval('ring r4 = (real,20),(a,b,c),dp')
1592
+ ''
1593
+ sage: singular('r4').sage_global_ring()
1594
+ Multivariate Polynomial Ring in a, b, c over Real Field with 70 bits of precision
1595
+
1596
+ The case of complex coefficients is not fully supported, yet, since
1597
+ the generator of a complex field in Sage is always called "I"::
1598
+
1599
+ sage: singular.eval('ring r5 = (complex,15,j),(a,b,c),dp')
1600
+ ''
1601
+ sage: R = singular('r5').sage_global_ring(); R
1602
+ Multivariate Polynomial Ring in a, b, c over Complex Field with 54 bits of precision
1603
+ sage: R.base_ring()('k')
1604
+ Traceback (most recent call last):
1605
+ ...
1606
+ ValueError: given string 'k' is not a complex number
1607
+ sage: R.base_ring()('I')
1608
+ 1.00000000000000*I
1609
+
1610
+ An example where the base ring is a polynomial ring over an extension of the rational field::
1611
+
1612
+ sage: singular.eval('ring r7 = (0,a), (x,y), dp')
1613
+ ''
1614
+ sage: singular.eval('minpoly = a2 + 1')
1615
+ ''
1616
+ sage: singular('r7').sage_global_ring()
1617
+ Multivariate Polynomial Ring in x, y over Number Field in a with defining polynomial a^2 + 1
1618
+
1619
+ In our last example, the base ring is a quotient ring::
1620
+
1621
+ sage: singular.eval('ring r6 = (9,a), (x,y,z),lp')
1622
+ ''
1623
+ sage: Q = singular('std(ideal(x^2,x+y^2+z^3))', type='qring')
1624
+ sage: Q.sage_global_ring()
1625
+ Quotient of Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 3^2 by the ideal (y^4 - y^2*z^3 + z^6, x + y^2 + z^3)
1626
+
1627
+ AUTHOR:
1628
+
1629
+ - Simon King (2011-06-06)
1630
+ """
1631
+ # extract the ring of coefficients
1632
+ singular = self.parent()
1633
+ charstr = singular.eval('charstr(basering)').split(',', 1)
1634
+ from sage.rings.integer_ring import ZZ
1635
+ is_extension = len(charstr) == 2
1636
+ if charstr[0] in ['integer', 'ZZ']:
1637
+ br = ZZ
1638
+ is_extension = False
1639
+ elif charstr[0] in ['0', 'QQ']:
1640
+ from sage.rings.rational_field import QQ
1641
+ br = QQ
1642
+ elif charstr[0].startswith('Float'):
1643
+ from sage.rings.real_mpfr import RealField
1644
+ from sage.functions.other import ceil
1645
+ from sage.misc.functional import log
1646
+ prec = singular.eval('ringlist(basering)[1][2][1]')
1647
+ br = RealField(ceil((ZZ(prec) + 1) / log(2, 10)))
1648
+ is_extension = False
1649
+ elif charstr[0] == 'complex':
1650
+ from sage.rings.complex_mpfr import ComplexField
1651
+ from sage.functions.other import ceil
1652
+ from sage.misc.functional import log
1653
+ prec = singular.eval('ringlist(basering)[1][2][1]')
1654
+ br = ComplexField(ceil((ZZ(prec) + 1) / log(2, 10)))
1655
+ is_extension = False
1656
+ else:
1657
+ # it ought to be a finite field
1658
+ q = ZZ(charstr[0].lstrip('ZZ/'))
1659
+ from sage.rings.finite_rings.finite_field_constructor import GF
1660
+ if q.is_prime():
1661
+ br = GF(q)
1662
+ else:
1663
+ br = GF(q, charstr[1])
1664
+ # Singular has no extension of a non-prime field
1665
+ is_extension = False
1666
+
1667
+ # We have the base ring of the base ring. But is it
1668
+ # an extension?
1669
+ if is_extension:
1670
+ minpoly = singular.eval('minpoly')
1671
+ if minpoly == '0':
1672
+ from sage.rings.fraction_field import FractionField as Frac
1673
+ BR = Frac(br[charstr[1]])
1674
+ else:
1675
+ is_short = singular.eval('short')
1676
+ if is_short != '0':
1677
+ singular.eval('short=0')
1678
+ minpoly = ZZ[charstr[1]](singular.eval('minpoly'))
1679
+ singular.eval('short=%s' % is_short)
1680
+ else:
1681
+ minpoly = ZZ[charstr[1]](minpoly)
1682
+ BR = br.extension(minpoly, names=charstr[1])
1683
+ else:
1684
+ BR = br
1685
+
1686
+ # Now, we form the polynomial ring over BR with the given variables,
1687
+ # using Singular's term order
1688
+ from sage.rings.polynomial.term_order import termorder_from_singular
1689
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1690
+ # Meanwhile Singulars quotient rings are also of 'ring' type, not 'qring' as it was in the past.
1691
+ # To find out if a singular ring is a quotient ring or not checking for ring type does not help
1692
+ # and instead of that we check if the quotient ring is zero or not:
1693
+ if (singular.eval('ideal(basering)==0') == '1'):
1694
+ return PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=termorder_from_singular(singular))
1695
+ P = PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=termorder_from_singular(singular))
1696
+ return P.quotient(singular('ringlist(basering)[4]')._sage_(P), names=singular.eval('varstr(basering)'))
1697
+
1698
+ def sage_poly(self, R=None, kcache=None):
1699
+ """
1700
+ Return a Sage polynomial in the ring r matching the provided poly
1701
+ which is a singular polynomial.
1702
+
1703
+ INPUT:
1704
+
1705
+ - ``R`` -- (default: ``None``) an optional polynomial ring.
1706
+ If it is provided, then you have to make sure that it
1707
+ matches the current singular ring as, e.g., returned by
1708
+ ``singular.current_ring()``. By default, the output of
1709
+ :meth:`sage_global_ring` is used.
1710
+
1711
+ - ``kcache`` -- (default: ``None``) an optional dictionary
1712
+ for faster finite field lookups, this is mainly useful for finite
1713
+ extension fields
1714
+
1715
+
1716
+ OUTPUT: MPolynomial
1717
+
1718
+ EXAMPLES::
1719
+
1720
+ sage: R = PolynomialRing(GF(2^8,'a'), 'x,y')
1721
+ sage: f = R('a^20*x^2*y+a^10+x')
1722
+ sage: f._singular_().sage_poly(R) == f
1723
+ True
1724
+ sage: R = PolynomialRing(GF(2^8,'a'), 'x', implementation='singular')
1725
+ sage: f = R('a^20*x^3+x^2+a^10')
1726
+ sage: f._singular_().sage_poly(R) == f
1727
+ True
1728
+
1729
+ ::
1730
+
1731
+ sage: P.<x,y> = PolynomialRing(QQ, 2)
1732
+ sage: f = x*y**3 - 1/9 * x + 1; f
1733
+ x*y^3 - 1/9*x + 1
1734
+ sage: singular(f)
1735
+ x*y^3-1/9*x+1
1736
+ sage: P(singular(f))
1737
+ x*y^3 - 1/9*x + 1
1738
+
1739
+ TESTS::
1740
+
1741
+ sage: singular.eval('ring r = (3,z),(a,b,c),dp')
1742
+ ''
1743
+ sage: singular.eval('minpoly = 1+z+z2+z3+z4')
1744
+ ''
1745
+ sage: p = singular('z^4*a^3+z^2*a*b*c')
1746
+ sage: p.sage_poly()
1747
+ (-z^3 - z^2 - z - 1)*a^3 + (z^2)*a*b*c
1748
+ sage: singular('z^4')
1749
+ (-z3-z2-z-1)
1750
+
1751
+ Test that :issue:`25297` is fixed::
1752
+
1753
+ sage: R.<x,y> = QQ[]
1754
+ sage: SE.<xbar,ybar> = R.quotient(x^2 + y^2 - 1)
1755
+ sage: P = ideal(xbar,ybar)
1756
+ sage: P2 = P._singular_().sage()
1757
+ sage: P2.0.lift().parent()
1758
+ Multivariate Polynomial Ring in x, y over Rational Field
1759
+
1760
+ Test that :issue:`29396` is fixed::
1761
+
1762
+ sage: Rxz.<x,z> = RR[]
1763
+ sage: f = x**3 + x*z + 1
1764
+ sage: f.discriminant(x)
1765
+ -4.00000000000000*z^3 - 27.0000000000000
1766
+ sage: Rx.<x> = RR[]
1767
+ sage: Rx("x + 7.5")._singular_().sage_poly()
1768
+ x + 7.50000
1769
+ sage: Rx("x + 7.5")._singular_().sage_poly(Rx)
1770
+ x + 7.50000000000000
1771
+
1772
+ AUTHORS:
1773
+
1774
+ - Martin Albrecht (2006-05-18)
1775
+ - Simon King (2011-06-06): Deal with Singular's short polynomial representation,
1776
+ automatic construction of a polynomial ring, if it is not explicitly given.
1777
+
1778
+ .. NOTE::
1779
+
1780
+ For very simple polynomials
1781
+ ``eval(SingularElement.sage_polystring())`` is faster than
1782
+ SingularElement.sage_poly(R), maybe we should detect the
1783
+ crossover point (in dependence of the string length) and
1784
+ choose an appropriate conversion strategy
1785
+ """
1786
+ # TODO: Refactor imports to move this to the top
1787
+ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict
1788
+ from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
1789
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
1790
+ from sage.rings.polynomial.polydict import ETuple
1791
+ from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
1792
+ from sage.rings.quotient_ring import QuotientRing_generic
1793
+
1794
+ ring_is_fine = False
1795
+ if R is None:
1796
+ ring_is_fine = True
1797
+ R = self.sage_global_ring()
1798
+
1799
+ if isinstance(R, QuotientRing_generic) and (ring_is_fine or can_convert_to_singular(R)):
1800
+ p = self.sage_poly(R.ambient(), kcache)
1801
+ return R(p)
1802
+
1803
+ sage_repr = {}
1804
+ k = R.base_ring()
1805
+
1806
+ variable_str = "*".join(R.variable_names())
1807
+
1808
+ # This returns a string which looks like a list where the first
1809
+ # half of the list is filled with monomials occurring in the
1810
+ # Singular polynomial and the second half filled with the matching
1811
+ # coefficients.
1812
+ #
1813
+ # Our strategy is to split the monomials at "*" to get the powers
1814
+ # in the single variables and then to split the result to get
1815
+ # actual exponent.
1816
+ #
1817
+ # So e.g. ['x^3*y^3','a'] get's split to
1818
+ # [[['x','3'],['y','3']],'a']. We may do this quickly,
1819
+ # as we know what to expect.
1820
+
1821
+ is_short = self.parent().eval('short')
1822
+ if is_short != '0':
1823
+ self.parent().eval('short=0')
1824
+ if isinstance(R, MPolynomialRing_libsingular):
1825
+ out = R(self)
1826
+ self.parent().eval('short=%s' % is_short)
1827
+ return out
1828
+ singular_poly_list = self.parent().eval("string(coef(%s,%s))" % (
1829
+ self.name(), variable_str)).split(",")
1830
+ self.parent().eval('short=%s' % is_short)
1831
+ else:
1832
+ if isinstance(R, MPolynomialRing_libsingular):
1833
+ return R(self)
1834
+ singular_poly_list = self.parent().eval("string(coef(%s,%s))" % (
1835
+ self.name(), variable_str)).split(",")
1836
+
1837
+ # Directly treat constants
1838
+ if singular_poly_list[0] in ['1', '(1.000e+00)']:
1839
+ return R(singular_poly_list[1])
1840
+
1841
+ coeff_start = len(singular_poly_list) // 2
1842
+
1843
+ # Singular 4 puts parentheses around floats and sign outside them
1844
+ charstr = self.parent().eval('charstr(basering)').split(',', 1)
1845
+ if charstr[0].startswith('Float') or charstr[0] == 'complex':
1846
+ for i in range(coeff_start, 2 * coeff_start):
1847
+ singular_poly_list[i] = singular_poly_list[i].replace('(', '').replace(')', '')
1848
+
1849
+ if isinstance(R, MPolynomialRing_polydict) and (ring_is_fine or can_convert_to_singular(R)):
1850
+ # we need to lookup the index of a given variable represented
1851
+ # through a string
1852
+ var_dict = dict(zip(R.variable_names(), range(R.ngens())))
1853
+
1854
+ ngens = R.ngens()
1855
+
1856
+ for i in range(coeff_start):
1857
+ exp = dict()
1858
+ monomial = singular_poly_list[i]
1859
+
1860
+ if monomial not in ['1', '(1.000e+00)']:
1861
+ variables = [var.split("^") for var in monomial.split("*")]
1862
+ for e in variables:
1863
+ var = e[0]
1864
+ if len(e) == 2:
1865
+ power = int(e[1])
1866
+ else:
1867
+ power = 1
1868
+ exp[var_dict[var]] = power
1869
+
1870
+ if kcache is None:
1871
+ sage_repr[ETuple(exp, ngens)] = k(singular_poly_list[coeff_start + i])
1872
+ else:
1873
+ elem = singular_poly_list[coeff_start + i]
1874
+ if elem not in kcache:
1875
+ kcache[elem] = k(elem)
1876
+ sage_repr[ETuple(exp, ngens)] = kcache[elem]
1877
+
1878
+ return R(sage_repr)
1879
+
1880
+ elif isinstance(R, PolynomialRing_generic) and (ring_is_fine or can_convert_to_singular(R)):
1881
+
1882
+ sage_repr = [0] * int(self.deg() + 1)
1883
+
1884
+ for i in range(coeff_start):
1885
+ monomial = singular_poly_list[i]
1886
+ exp = 0
1887
+
1888
+ if monomial not in ['1', '(1.000e+00)']:
1889
+ term = monomial.split("^")
1890
+ if len(term) == 2:
1891
+ exp = int(term[1])
1892
+ else:
1893
+ exp = 1
1894
+
1895
+ if kcache is None:
1896
+ sage_repr[exp] = k(singular_poly_list[coeff_start + i])
1897
+ else:
1898
+ elem = singular_poly_list[coeff_start + i]
1899
+ if elem not in kcache:
1900
+ kcache[elem] = k(elem)
1901
+ sage_repr[exp] = kcache[elem]
1902
+
1903
+ return R(sage_repr)
1904
+
1905
+ else:
1906
+ raise TypeError("Cannot coerce %s into %s" % (self, R))
1907
+
1908
+ def sage_matrix(self, R, sparse=True):
1909
+ """
1910
+ Return Sage matrix for ``self``.
1911
+
1912
+ INPUT:
1913
+
1914
+ - ``R`` -- (default: ``None``) an optional ring, over which
1915
+ the resulting matrix is going to be defined.
1916
+ By default, the output of :meth:`sage_global_ring` is used.
1917
+
1918
+ - ``sparse`` -- boolean (default: ``True``); whether the
1919
+ resulting matrix is sparse or not
1920
+
1921
+ EXAMPLES::
1922
+
1923
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1924
+ sage: A = singular.matrix(2,2)
1925
+ sage: A.sage_matrix(ZZ)
1926
+ [0 0]
1927
+ [0 0]
1928
+ sage: A.sage_matrix(RDF)
1929
+ [0.0 0.0]
1930
+ [0.0 0.0]
1931
+ """
1932
+ from sage.matrix.constructor import matrix
1933
+ nrows, ncols = int(self.nrows()), int(self.ncols())
1934
+
1935
+ if R is None:
1936
+ R = self.sage_global_ring()
1937
+ A = matrix(R, nrows, ncols, sparse=sparse)
1938
+ # this is slow
1939
+ for x in range(nrows):
1940
+ for y in range(ncols):
1941
+ A[x, y] = self[x + 1, y + 1].sage_poly(R)
1942
+ return A
1943
+
1944
+ A = matrix(R, nrows, ncols, sparse=sparse)
1945
+ # this is slow
1946
+ for x in range(nrows):
1947
+ for y in range(ncols):
1948
+ A[x, y] = R(self[x + 1, y + 1])
1949
+
1950
+ return A
1951
+
1952
+ def _sage_(self, R=None):
1953
+ r"""
1954
+ Convert ``self`` to Sage.
1955
+
1956
+ EXAMPLES::
1957
+
1958
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
1959
+ sage: A = singular.matrix(2,2)
1960
+ sage: A.sage(ZZ) # indirect doctest
1961
+ [0 0]
1962
+ [0 0]
1963
+ sage: A = random_matrix(ZZ,3,3); A # random
1964
+ [ -8 2 0]
1965
+ [ 0 1 -1]
1966
+ [ 2 1 -95]
1967
+ sage: As = singular(A); As # random
1968
+ -8 2 0
1969
+ 0 1 -1
1970
+ 2 1 -95
1971
+ sage: As.sage() == A
1972
+ True
1973
+
1974
+ ::
1975
+
1976
+ sage: singular.eval('ring R = integer, (x,y,z),lp')
1977
+ '// ** redefining R (ring R = integer, (x,y,z),lp;)'
1978
+ sage: I = singular.ideal(['x^2','y*z','z+x'])
1979
+ sage: I.sage()
1980
+ Ideal (x^2, y*z, x + z) of Multivariate Polynomial Ring in x, y, z over Integer Ring
1981
+
1982
+ ::
1983
+
1984
+ sage: singular('ringlist(basering)').sage()
1985
+ [['integer'], ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0)]], Ideal (0) of Multivariate Polynomial Ring in x, y, z over Integer Ring]
1986
+
1987
+ ::
1988
+
1989
+ sage: singular.eval('ring r10 = (9,a), (x,y,z),lp')
1990
+ ''
1991
+ sage: singular.eval('setring R')
1992
+ ''
1993
+ sage: singular('r10').sage()
1994
+ Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 3^2
1995
+
1996
+ Note that the current base ring has not been changed by asking for another ring::
1997
+
1998
+ sage: singular('basering')
1999
+ polynomial ring, over a domain, global ordering
2000
+ // coefficients: ZZ...
2001
+ // number of vars : 3
2002
+ // block 1 : ordering lp
2003
+ // : names x y z
2004
+ // block 2 : ordering C
2005
+
2006
+ ::
2007
+
2008
+ sage: singular.eval('setring r10')
2009
+ ''
2010
+ sage: Q = singular('std(ideal(x^2,x+y^2+z^3))', type='qring')
2011
+ sage: Q.sage()
2012
+ Quotient of Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 3^2 by the ideal (y^4 - y^2*z^3 + z^6, x + y^2 + z^3)
2013
+ sage: singular('x^2+y').sage()
2014
+ y
2015
+ sage: singular('x^2+y').sage().parent()
2016
+ Quotient of Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 3^2 by the ideal (y^4 - y^2*z^3 + z^6, x + y^2 + z^3)
2017
+
2018
+ Test that :issue:`18848` is fixed::
2019
+
2020
+ sage: singular(5).sage()
2021
+ 5
2022
+ sage: type(singular(int(5)).sage())
2023
+ <class 'sage.rings.integer.Integer'>
2024
+
2025
+ Test that bigintvec can be coerced::
2026
+
2027
+ sage: singular('hilb((ideal(x)), 1)').sage()
2028
+ (1, -1, 0, 0, -1, 1, 0)
2029
+ """
2030
+ typ = self.type()
2031
+ if typ == 'poly':
2032
+ return self.sage_poly(R)
2033
+ elif typ == 'int':
2034
+ return sage.rings.integer.Integer(repr(self))
2035
+ elif typ == 'module':
2036
+ return self.sage_matrix(R, sparse=True)
2037
+ elif typ == 'matrix':
2038
+ return self.sage_matrix(R, sparse=False)
2039
+ elif typ == 'list':
2040
+ return [f._sage_(R) for f in self]
2041
+ elif typ == 'intvec':
2042
+ from sage.modules.free_module_element import vector
2043
+ return vector([sage.rings.integer.Integer(str(e)) for e in self])
2044
+ elif typ == 'bigintvec':
2045
+ from sage.modules.free_module_element import vector
2046
+ return vector([sage.rings.rational.Rational(str(e)) for e in self])
2047
+ elif typ == 'intmat':
2048
+ from sage.matrix.constructor import matrix
2049
+ from sage.rings.integer_ring import ZZ
2050
+ A = matrix(ZZ, int(self.nrows()), int(self.ncols()))
2051
+ for i in range(A.nrows()):
2052
+ for j in range(A.ncols()):
2053
+ A[i, j] = sage.rings.integer.Integer(str(self[i + 1, j + 1]))
2054
+ return A
2055
+ elif typ == 'string':
2056
+ return repr(self)
2057
+ elif typ == 'ideal':
2058
+ R = R or self.sage_global_ring()
2059
+ return R.ideal([p.sage_poly(R) for p in self])
2060
+ elif typ in ['ring', 'qring']:
2061
+ br = singular('basering')
2062
+ self.set_ring()
2063
+ R = self.sage_global_ring()
2064
+ br.set_ring()
2065
+ return R
2066
+ raise NotImplementedError("Coercion of this datatype not implemented yet")
2067
+
2068
+ def is_string(self):
2069
+ """
2070
+ Tell whether this element is a string.
2071
+
2072
+ EXAMPLES::
2073
+
2074
+ sage: singular('"abc"').is_string()
2075
+ True
2076
+ sage: singular('1').is_string()
2077
+ False
2078
+ """
2079
+ return self.type() == 'string'
2080
+
2081
+ def set_ring(self):
2082
+ """
2083
+ Set the current ring in Singular to be ``self``.
2084
+
2085
+ EXAMPLES::
2086
+
2087
+ sage: R = singular.ring(7, '(a,b)', 'ds')
2088
+ sage: S = singular.ring('real', '(a,b)', 'lp')
2089
+ sage: singular.current_ring()
2090
+ polynomial ring, over a field, global ordering
2091
+ // coefficients: Float()...
2092
+ // number of vars : 2
2093
+ // block 1 : ordering lp
2094
+ // : names a b
2095
+ // block 2 : ordering C
2096
+ sage: R.set_ring()
2097
+ sage: singular.current_ring()
2098
+ polynomial ring, over a field, local ordering
2099
+ // coefficients: ZZ/7...
2100
+ // number of vars : 2
2101
+ // block 1 : ordering ds
2102
+ // : names a b
2103
+ // block 2 : ordering C
2104
+ """
2105
+ self.parent().set_ring(self)
2106
+
2107
+ def sage_flattened_str_list(self):
2108
+ """
2109
+ EXAMPLES::
2110
+
2111
+ sage: R=singular.ring(0,'(x,y)','dp')
2112
+ sage: RL = R.ringlist()
2113
+ sage: RL.sage_flattened_str_list()
2114
+ ['0', 'x', 'y', 'dp', '1,1', 'C', '0', '_[1]=0']
2115
+ """
2116
+ s = str(self)
2117
+ c = r'\[[0-9]*\]:'
2118
+ r = re.compile(c)
2119
+ s = r.sub('', s).strip()
2120
+ return s.split()
2121
+
2122
+ def sage_structured_str_list(self):
2123
+ r"""
2124
+ If ``self`` is a Singular list of lists of Singular elements, return
2125
+ corresponding Sage list of lists of strings.
2126
+
2127
+ EXAMPLES::
2128
+
2129
+ sage: R=singular.ring(0,'(x,y)','dp')
2130
+ sage: RL=R.ringlist()
2131
+ sage: RL
2132
+ [1]:
2133
+ 0
2134
+ [2]:
2135
+ [1]:
2136
+ x
2137
+ [2]:
2138
+ y
2139
+ [3]:
2140
+ [1]:
2141
+ [1]:
2142
+ dp
2143
+ [2]:
2144
+ 1,1
2145
+ [2]:
2146
+ [1]:
2147
+ C
2148
+ [2]:
2149
+ 0
2150
+ [4]:
2151
+ _[1]=0
2152
+ sage: RL.sage_structured_str_list()
2153
+ ['0', ['x', 'y'], [['dp', '1,\n1'], ['C', '0']], '0']
2154
+ """
2155
+ if self.type() != 'list':
2156
+ return str(self)
2157
+ return [X.sage_structured_str_list() for X in self]
2158
+
2159
+ def _tab_completion(self) -> list:
2160
+ """
2161
+ Return the possible tab-completions for ``self``.
2162
+
2163
+ In this case, we just return all the :kbd:`Tab` completions
2164
+ for the Singular object.
2165
+
2166
+ EXAMPLES::
2167
+
2168
+ sage: R = singular.ring(0,'(x,y)','dp')
2169
+ sage: R._tab_completion()
2170
+ ['exteriorPower',
2171
+ ...
2172
+ 'crossprod']
2173
+ """
2174
+ return self.parent()._tab_completion()
2175
+
2176
+ def type(self):
2177
+ """
2178
+ Return the internal type of this element.
2179
+
2180
+ EXAMPLES::
2181
+
2182
+ sage: R = PolynomialRing(GF(2^8,'a'),2,'x')
2183
+ sage: R._singular_().type()
2184
+ 'ring'
2185
+ sage: fs = singular('x0^2','poly')
2186
+ sage: fs.type()
2187
+ 'poly'
2188
+ """
2189
+ # singular reports // $varname $type $stuff
2190
+ p = re.compile(r"// [\w]+ (\w+) [\w]*")
2191
+ m = p.match(self.parent().eval("type(%s)" % self.name()))
2192
+ return m.group(1)
2193
+
2194
+ def __iter__(self):
2195
+ """
2196
+ EXAMPLES::
2197
+
2198
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
2199
+ sage: A = singular.matrix(2,2)
2200
+ sage: list(iter(A))
2201
+ [[0], [0]]
2202
+ sage: A[1,1] = 1; A[1,2] = 2
2203
+ sage: A[2,1] = 3; A[2,2] = 4
2204
+ sage: list(iter(A))
2205
+ [[1,3], [2,4]]
2206
+ """
2207
+ if self.type() == 'matrix':
2208
+ l = self.ncols()
2209
+ else:
2210
+ l = len(self)
2211
+
2212
+ for i in range(1, int(l + 1)):
2213
+ yield self[i]
2214
+
2215
+ def _singular_(self):
2216
+ """
2217
+ EXAMPLES::
2218
+
2219
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
2220
+ sage: A = singular.matrix(2,2)
2221
+ sage: A._singular_() is A
2222
+ True
2223
+ """
2224
+ return self
2225
+
2226
+ def attrib(self, name, value=None):
2227
+ """
2228
+ Get and set attributes for ``self``.
2229
+
2230
+ INPUT:
2231
+
2232
+ - ``name`` -- string to choose the attribute
2233
+
2234
+ - ``value`` -- boolean value or ``None`` for reading,
2235
+ (default: ``None``)
2236
+
2237
+ VALUES: isSB - the standard basis property is set by all commands
2238
+ computing a standard basis like groebner, std, stdhilb etc.; used
2239
+ by lift, dim, degree, mult, hilb, vdim, kbase isHomog - the weight
2240
+ vector for homogeneous or quasihomogeneous ideals/modules isCI -
2241
+ complete intersection property isCM - Cohen-Macaulay property rank
2242
+ - set the rank of a module (see nrows) withSB - value of type
2243
+ ideal, resp. module, is std withHilb - value of type intvec is
2244
+ hilb(_,1) (see hilb) withRes - value of type list is a free
2245
+ resolution withDim - value of type int is the dimension (see dim)
2246
+ withMult - value of type int is the multiplicity (see mult)
2247
+
2248
+ EXAMPLES::
2249
+
2250
+ sage: P.<x,y,z> = PolynomialRing(QQ)
2251
+ sage: I = Ideal([z^2, y*z, y^2, x*z, x*y, x^2])
2252
+ sage: Ibar = I._singular_()
2253
+ sage: Ibar.attrib('isSB')
2254
+ 0
2255
+ sage: singular.eval('vdim(%s)'%Ibar.name()) # sage7 name is random
2256
+ // ** sage7 is no standard basis
2257
+ 4
2258
+ sage: Ibar.attrib('isSB',1)
2259
+ sage: singular.eval('vdim(%s)'%Ibar.name())
2260
+ '4'
2261
+ """
2262
+ if value is None:
2263
+ return int(self.parent().eval('attrib(%s,"%s")' % (self.name(), name)))
2264
+ else:
2265
+ self.parent().eval('attrib(%s,"%s",%d)' % (self.name(), name, value))
2266
+
2267
+
2268
+ @instancedoc
2269
+ class SingularFunction(ExpectFunction):
2270
+ def _instancedoc_(self):
2271
+ """
2272
+ EXAMPLES::
2273
+
2274
+ sage: 'groebner' in singular.groebner.__doc__ # needs info
2275
+ True
2276
+ """
2277
+
2278
+ prefix = """
2279
+ This function is an automatically generated pexpect wrapper around the Singular
2280
+ function '%s'.
2281
+
2282
+ EXAMPLES::
2283
+
2284
+ sage: groebner = singular.groebner
2285
+ sage: P.<x, y> = PolynomialRing(QQ)
2286
+ sage: I = P.ideal(x^2-y, y+x)
2287
+ sage: groebner(singular(I))
2288
+ x+y,
2289
+ y^2-y
2290
+ """ % (self._name,)
2291
+ return prefix + get_docstring(self._name,
2292
+ prefix=True,
2293
+ code=True)
2294
+
2295
+
2296
+ @instancedoc
2297
+ class SingularFunctionElement(FunctionElement):
2298
+ def _instancedoc_(self):
2299
+ r"""
2300
+ EXAMPLES::
2301
+
2302
+ sage: R = singular.ring(0, '(x,y,z)', 'dp')
2303
+ sage: A = singular.matrix(2,2)
2304
+ sage: 'matrix_expression' in A.nrows.__doc__ # needs info
2305
+ True
2306
+ """
2307
+ return get_docstring(self._name, code=True)
2308
+
2309
+
2310
+ def is_SingularElement(x):
2311
+ r"""
2312
+ Return ``True`` if ``x`` is of type :class:`SingularElement`.
2313
+
2314
+ This function is deprecated; use :func:`isinstance`
2315
+ (of :class:`sage.interfaces.abc.SingularElement`) instead.
2316
+
2317
+ EXAMPLES::
2318
+
2319
+ sage: from sage.interfaces.singular import is_SingularElement
2320
+ sage: is_SingularElement(singular(2))
2321
+ doctest:...: DeprecationWarning: the function is_SingularElement is deprecated; use isinstance(x, sage.interfaces.abc.SingularElement) instead
2322
+ See https://github.com/sagemath/sage/issues/34804 for details.
2323
+ True
2324
+ sage: is_SingularElement(2)
2325
+ False
2326
+ """
2327
+ from sage.misc.superseded import deprecation
2328
+ deprecation(34804, "the function is_SingularElement is deprecated; use isinstance(x, sage.interfaces.abc.SingularElement) instead")
2329
+
2330
+ return isinstance(x, SingularElement)
2331
+
2332
+
2333
+ def get_docstring(name, prefix=False, code=False):
2334
+ """
2335
+ Return the docstring for the function ``name``.
2336
+
2337
+ INPUT:
2338
+
2339
+ - ``name`` -- a Singular function name
2340
+ - ``prefix`` -- boolean (default: ``False``); whether or not to
2341
+ include the prefix stating that what follows is from the
2342
+ Singular documentation.
2343
+ - ``code`` -- boolean (default: ``False``); whether or not to
2344
+ format the result as a reStructuredText code block. This is
2345
+ intended to support the feature requested in :issue:`11268`.
2346
+
2347
+ OUTPUT:
2348
+
2349
+ A string describing the Singular function ``name``. A
2350
+ :class:`KeyError` is raised if the function was not found in the
2351
+ Singular documentation. If the "info" is not on the user's
2352
+ ``PATH``, an :class:`OSError` will be raised. If "info" was found
2353
+ but failed to execute, a :class:`subprocess.CalledProcessError`
2354
+ will be raised instead.
2355
+
2356
+ EXAMPLES::
2357
+
2358
+ sage: from sage.interfaces.singular import get_docstring
2359
+ sage: 'groebner' in get_docstring('groebner') # needs_info
2360
+ True
2361
+ sage: 'standard.lib' in get_docstring('groebner') # needs info
2362
+ True
2363
+
2364
+ The ``prefix=True`` form is used in Sage's generated docstrings::
2365
+
2366
+ sage: from sage.interfaces.singular import get_docstring
2367
+ sage: print(get_docstring("factorize", prefix=True)) # needs info
2368
+ The Singular documentation for "factorize" is given below.
2369
+ ...
2370
+
2371
+ TESTS:
2372
+
2373
+ Non-existent functions raise a :class:`KeyError`::
2374
+
2375
+ sage: from sage.interfaces.singular import get_docstring
2376
+ sage: get_docstring("mysql_real_escape_string") # needs info
2377
+ Traceback (most recent call last):
2378
+ ...
2379
+ KeyError: 'mysql_real_escape_string'
2380
+
2381
+ This is true also for nodes that exist in the documentation but
2382
+ are not function nodes::
2383
+
2384
+ sage: from sage.interfaces.singular import get_docstring
2385
+ sage: get_docstring("Preface") # needs info
2386
+ Traceback (most recent call last):
2387
+ ...
2388
+ KeyError: 'Preface'
2389
+
2390
+ If GNU Info is not installed, we politely decline to do anything::
2391
+
2392
+ sage: from sage.interfaces.singular import get_docstring
2393
+ sage: from sage.features.info import Info
2394
+ sage: Info().hide()
2395
+ sage: get_docstring('groebner')
2396
+ Traceback (most recent call last):
2397
+ ...
2398
+ OSError: GNU Info is not installed. Singular's documentation
2399
+ will not be available.
2400
+ sage: Info().unhide()
2401
+ """
2402
+ from sage.features.info import Info
2403
+
2404
+ if not Info().is_present():
2405
+ raise OSError("GNU Info is not installed. Singular's "
2406
+ "documentation will not be available.")
2407
+ import subprocess
2408
+ cmd_and_args = ["info", f"--node={name}", "singular"]
2409
+ try:
2410
+ result = subprocess.run(cmd_and_args,
2411
+ capture_output=True,
2412
+ check=True,
2413
+ text=True)
2414
+ except subprocess.CalledProcessError as e:
2415
+ # Before Texinfo v7.0.0, the "info" program would exit
2416
+ # successfully even if the desired node was not found.
2417
+ if e.returncode == 1:
2418
+ raise KeyError(name) from e
2419
+ else:
2420
+ # Something else bad happened
2421
+ raise e
2422
+
2423
+ # The subprocess call can succeed if the given node exists but is
2424
+ # not a function node (example: "Preface"). All function nodes
2425
+ # should live in the "Functions" section, and we can determine the
2426
+ # current section by the presence of "Up: <section>" on the first
2427
+ # line of the output, in the navigation header.
2428
+ #
2429
+ # There is a small risk of ambiguity here if there are two
2430
+ # sections with the same name, but it's a trade-off: specifying
2431
+ # the full path down to the intended function would be much more
2432
+ # fragile; it would break whenever a subsection name was tweaked
2433
+ # upstream.
2434
+ offset = result.stdout.find("\n")
2435
+ line0 = result.stdout[:offset]
2436
+ if "Up: Functions" not in line0:
2437
+ raise KeyError(name)
2438
+
2439
+ # If the first line was the navigation header, the second line should
2440
+ # be blank; by incrementing the offset by two, we're skipping over it.
2441
+ offset += 2
2442
+ result = result.stdout[offset:]
2443
+
2444
+ if code:
2445
+ result = "::\n\n " + "\n ".join(result.split('\n'))
2446
+
2447
+ if prefix:
2448
+ result = (f'The Singular documentation for "{name}" is given below.'
2449
+ + "\n\n" + result)
2450
+
2451
+ return result
2452
+
2453
+
2454
+ singular = Singular()
2455
+
2456
+
2457
+ def reduce_load_Singular():
2458
+ """
2459
+ EXAMPLES::
2460
+
2461
+ sage: from sage.interfaces.singular import reduce_load_Singular
2462
+ sage: reduce_load_Singular()
2463
+ Singular
2464
+ """
2465
+ return singular
2466
+
2467
+
2468
+ def singular_console():
2469
+ r"""
2470
+ Spawn a new Singular command-line session.
2471
+
2472
+ EXAMPLES::
2473
+
2474
+ sage: singular_console() #not tested
2475
+ SINGULAR / Development
2476
+ A Computer Algebra System for Polynomial Computations / version 3-0-4
2477
+ 0<
2478
+ by: G.-M. Greuel, G. Pfister, H. Schoenemann \ Nov 2007
2479
+ FB Mathematik der Universitaet, D-67653 Kaiserslautern \
2480
+ """
2481
+ from sage.repl.rich_output.display_manager import get_display_manager
2482
+ if not get_display_manager().is_in_terminal():
2483
+ raise RuntimeError('Can use the console only in the terminal. Try %%singular magics instead.')
2484
+ os.system(sage.features.singular.Singular().absolute_filename())
2485
+
2486
+
2487
+ def singular_version():
2488
+ """
2489
+ Return the version of Singular being used.
2490
+
2491
+ EXAMPLES::
2492
+
2493
+ sage: singular.version()
2494
+ "Singular ... version 4...
2495
+ """
2496
+ return singular.eval('system("--version");')
2497
+
2498
+
2499
+ class SingularGBLogPrettyPrinter:
2500
+ """
2501
+ A device which prints Singular Groebner basis computation logs
2502
+ more verbatim.
2503
+ """
2504
+ rng_chng = re.compile(r"\[\d+:\d+\]")
2505
+ # [m:n] internal ring change to
2506
+ # poly representation with
2507
+ # exponent bound m and n words in
2508
+ # exponent vector
2509
+
2510
+ new_elem = re.compile("s") # found a new element of the standard basis
2511
+ red_zero = re.compile("-") # reduced a pair/S-polynomial to 0
2512
+ red_post = re.compile(r"\.") # postponed a reduction of a pair/S-polynomial
2513
+ cri_hilb = re.compile("h") # used Hilbert series criterion
2514
+ hig_corn = re.compile(r"H\(\d+\)") # found a 'highest corner' of degree d, no need to consider higher degrees
2515
+ num_crit = re.compile(r"\(\d+\)") # n critical pairs are still to be reduced
2516
+ red_num = re.compile(r"\(S:\d+\)") # doing complete reduction of n elements
2517
+ deg_lead = re.compile(r"\d+") # the degree of the leading terms is currently d
2518
+
2519
+ # SlimGB
2520
+ red_para = re.compile(r"M\[(\d+),(\d+)\]") # parallel reduction of n elements with m nonzero output elements
2521
+ red_betr = re.compile("b") # exchange of a reductor by a 'better' one
2522
+ non_mini = re.compile("e") # a new reductor with non-minimal leading term
2523
+
2524
+ crt_lne1 = re.compile(r"product criterion:(\d+) chain criterion:(\d+)")
2525
+ crt_lne2 = re.compile(r"NF:(\d+) product criterion:(\d+), ext_product criterion:(\d+)")
2526
+
2527
+ pat_sync = re.compile(r"1\+(\d+);")
2528
+
2529
+ global_pattern = re.compile(r"(\[\d+:\d+\]|s|-|\.|h|H\(\d+\)|\(\d+\)|\(S:\d+\)|\d+|M\[\d+,[b,e]*\d+\]|b|e).*")
2530
+
2531
+ def __init__(self, verbosity=1):
2532
+ """
2533
+ Construct a new Singular Groebner Basis log pretty printer.
2534
+
2535
+ INPUT:
2536
+
2537
+ - ``verbosity`` -- how much information should be printed
2538
+ (between 0 and 3)
2539
+
2540
+ EXAMPLES::
2541
+
2542
+ sage: from sage.interfaces.singular import SingularGBLogPrettyPrinter
2543
+ sage: s0 = SingularGBLogPrettyPrinter(verbosity=0)
2544
+ sage: s1 = SingularGBLogPrettyPrinter(verbosity=1)
2545
+ sage: s0.write("[1:2]12")
2546
+
2547
+ sage: s1.write("[1:2]12")
2548
+ Leading term degree: 12.
2549
+ """
2550
+ self.verbosity = verbosity
2551
+
2552
+ self.curr_deg = 0 # current degree
2553
+ self.max_deg = 0 # maximal degree in total
2554
+
2555
+ self.nf = 0 # number of normal forms computed (SlimGB only)
2556
+ self.prod = 0 # number of S-polynomials discarded using product criterion
2557
+ self.ext_prod = 0 # number of S-polynomials discarded using extended product criterion
2558
+ self.chain = 0 # number of S-polynomials discarded using chain criterion
2559
+
2560
+ self.storage = "" # stores incomplete strings
2561
+ self.sync = None # should we expect a sync integer?
2562
+
2563
+ def write(self, s):
2564
+ """
2565
+ EXAMPLES::
2566
+
2567
+ sage: from sage.interfaces.singular import SingularGBLogPrettyPrinter
2568
+ sage: s3 = SingularGBLogPrettyPrinter(verbosity=3)
2569
+ sage: s3.write("(S:1337)")
2570
+ Performing complete reduction of 1337 elements.
2571
+ sage: s3.write("M[389,12]")
2572
+ Parallel reduction of 389 elements with 12 nonzero output elements.
2573
+ """
2574
+ verbosity = self.verbosity
2575
+
2576
+ if self.storage:
2577
+ s = self.storage + s
2578
+ self.storage = ""
2579
+
2580
+ for line in s.splitlines():
2581
+ # deal with the Sage <-> Singular syncing code
2582
+ match = re.match(SingularGBLogPrettyPrinter.pat_sync, line)
2583
+ if match:
2584
+ self.sync = int(match.groups()[0])
2585
+ continue
2586
+
2587
+ if self.sync and line == "%d" % (self.sync + 1):
2588
+ self.sync = None
2589
+ continue
2590
+
2591
+ if line.endswith(";"):
2592
+ continue
2593
+ if line.startswith(">"):
2594
+ continue
2595
+
2596
+ if line.startswith("std") or line.startswith("slimgb"):
2597
+ continue
2598
+
2599
+ # collect stats returned about avoided reductions to zero
2600
+ match = re.match(SingularGBLogPrettyPrinter.crt_lne1, line)
2601
+ if match:
2602
+ self.prod, self.chain = map(int, re.match(SingularGBLogPrettyPrinter.crt_lne1, line).groups())
2603
+ self.storage = ""
2604
+ continue
2605
+ match = re.match(SingularGBLogPrettyPrinter.crt_lne2, line)
2606
+ if match:
2607
+ self.nf, self.prod, self.ext_prod = map(int, re.match(SingularGBLogPrettyPrinter.crt_lne2, line).groups())
2608
+ self.storage = ""
2609
+ continue
2610
+
2611
+ while line:
2612
+ match = re.match(SingularGBLogPrettyPrinter.global_pattern, line)
2613
+ if not match:
2614
+ self.storage = line
2615
+ line = None
2616
+ continue
2617
+
2618
+ token, = match.groups()
2619
+ line = line[len(token):]
2620
+
2621
+ if re.match(SingularGBLogPrettyPrinter.rng_chng, token):
2622
+ continue
2623
+
2624
+ elif re.match(SingularGBLogPrettyPrinter.new_elem, token) and verbosity >= 3:
2625
+ print("New element found.")
2626
+
2627
+ elif re.match(SingularGBLogPrettyPrinter.red_zero, token) and verbosity >= 2:
2628
+ print("Reduction to zero.")
2629
+
2630
+ elif re.match(SingularGBLogPrettyPrinter.red_post, token) and verbosity >= 2:
2631
+ print("Reduction postponed.")
2632
+
2633
+ elif re.match(SingularGBLogPrettyPrinter.cri_hilb, token) and verbosity >= 2:
2634
+ print("Hilber series criterion applied.")
2635
+
2636
+ elif re.match(SingularGBLogPrettyPrinter.hig_corn, token) and verbosity >= 1:
2637
+ print("Maximal degree found: %s" % token)
2638
+
2639
+ elif re.match(SingularGBLogPrettyPrinter.num_crit, token) and verbosity >= 1:
2640
+ print("Leading term degree: %2d. Critical pairs: %s." % (self.curr_deg, token[1:-1]))
2641
+
2642
+ elif re.match(SingularGBLogPrettyPrinter.red_num, token) and verbosity >= 3:
2643
+ print("Performing complete reduction of %s elements." % token[3:-1])
2644
+
2645
+ elif re.match(SingularGBLogPrettyPrinter.deg_lead, token):
2646
+ if verbosity >= 1:
2647
+ print("Leading term degree: %2d." % int(token))
2648
+ self.curr_deg = int(token)
2649
+ self.max_deg = max(self.max_deg, self.curr_deg)
2650
+
2651
+ elif re.match(SingularGBLogPrettyPrinter.red_para, token) and verbosity >= 3:
2652
+ m, n = re.match(SingularGBLogPrettyPrinter.red_para, token).groups()
2653
+ print("Parallel reduction of %s elements with %s nonzero output elements." % (m, n))
2654
+
2655
+ elif re.match(SingularGBLogPrettyPrinter.red_betr, token) and verbosity >= 3:
2656
+ print("Replaced reductor by 'better' one.")
2657
+
2658
+ elif re.match(SingularGBLogPrettyPrinter.non_mini, token) and verbosity >= 2:
2659
+ print("New reductor with non-minimal leading term found.")
2660
+
2661
+ def flush(self):
2662
+ """
2663
+ EXAMPLES::
2664
+
2665
+ sage: from sage.interfaces.singular import SingularGBLogPrettyPrinter
2666
+ sage: s3 = SingularGBLogPrettyPrinter(verbosity=3)
2667
+ sage: s3.flush()
2668
+ """
2669
+ sys.stdout.flush()
2670
+
2671
+
2672
+ class SingularGBDefaultContext:
2673
+ """
2674
+ Within this context all Singular Groebner basis calculations are
2675
+ reduced automatically.
2676
+
2677
+ AUTHORS:
2678
+
2679
+ - Martin Albrecht
2680
+ - Simon King
2681
+ """
2682
+ def __init__(self, singular=None):
2683
+ """
2684
+ Within this context all Singular Groebner basis calculations
2685
+ are reduced automatically.
2686
+
2687
+ INPUT:
2688
+
2689
+ - ``singular`` -- Singular instance (default: default instance)
2690
+
2691
+ EXAMPLES::
2692
+
2693
+ sage: from sage.interfaces.singular import SingularGBDefaultContext
2694
+ sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
2695
+ sage: I = sage.rings.ideal.Katsura(P,3)
2696
+ sage: singular.option('noredTail')
2697
+ sage: singular.option('noredThrough')
2698
+ sage: Is = I._singular_()
2699
+ sage: gb = Is.groebner()
2700
+ sage: gb
2701
+ 84*c^4-40*c^3+c^2+c,
2702
+ 7*b+210*c^3-79*c^2+3*c,
2703
+ a+2*b+2*c-1
2704
+
2705
+ ::
2706
+
2707
+ sage: with SingularGBDefaultContext(): rgb = Is.groebner()
2708
+ sage: rgb
2709
+ 84*c^4-40*c^3+c^2+c,
2710
+ 7*b+210*c^3-79*c^2+3*c,
2711
+ 7*a-420*c^3+158*c^2+8*c-7
2712
+
2713
+ Note that both bases are Groebner bases because they have
2714
+ pairwise prime leading monomials but that the monic version of
2715
+ the last element in ``rgb`` is smaller than the last element
2716
+ of ``gb`` with respect to the lexicographical term ordering. ::
2717
+
2718
+ sage: (7*a-420*c^3+158*c^2+8*c-7)/7 < (a+2*b+2*c-1)
2719
+ True
2720
+
2721
+ .. NOTE::
2722
+
2723
+ This context is used automatically internally whenever a
2724
+ Groebner basis is computed so the user does not need to use
2725
+ it manually.
2726
+ """
2727
+ if singular is None:
2728
+ from sage.interfaces.singular import singular as singular_default
2729
+ singular = singular_default
2730
+ self.singular = singular
2731
+
2732
+ def __enter__(self):
2733
+ """
2734
+ EXAMPLES::
2735
+
2736
+ sage: from sage.interfaces.singular import SingularGBDefaultContext
2737
+ sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
2738
+ sage: I = sage.rings.ideal.Katsura(P,3)
2739
+ sage: singular.option('noredTail')
2740
+ sage: singular.option('noredThrough')
2741
+ sage: Is = I._singular_()
2742
+ sage: with SingularGBDefaultContext(): rgb = Is.groebner()
2743
+ sage: rgb
2744
+ 84*c^4-40*c^3+c^2+c,
2745
+ 7*b+210*c^3-79*c^2+3*c,
2746
+ 7*a-420*c^3+158*c^2+8*c-7
2747
+ """
2748
+ try:
2749
+ self.bck_degBound = int(self.singular.eval('degBound'))
2750
+ except SingularError:
2751
+ self.bck_degBound = 0
2752
+ try:
2753
+ self.bck_multBound = int(self.singular.eval('multBound'))
2754
+ except SingularError:
2755
+ self.bck_multBound = 0
2756
+ self.o = self.singular.option("get")
2757
+ self.singular.option('set', self.singular._saved_options)
2758
+ self.singular.option("redSB")
2759
+ self.singular.option("redTail")
2760
+ try:
2761
+ self.singular.eval('degBound=0')
2762
+ except SingularError:
2763
+ pass
2764
+ try:
2765
+ self.singular.eval('multBound=0')
2766
+ except SingularError:
2767
+ pass
2768
+
2769
+ def __exit__(self, typ, value, tb):
2770
+ """
2771
+ EXAMPLES::
2772
+
2773
+ sage: from sage.interfaces.singular import SingularGBDefaultContext
2774
+ sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
2775
+ sage: I = sage.rings.ideal.Katsura(P,3)
2776
+ sage: singular.option('noredTail')
2777
+ sage: singular.option('noredThrough')
2778
+ sage: Is = I._singular_()
2779
+ sage: with SingularGBDefaultContext(): rgb = Is.groebner()
2780
+ sage: rgb
2781
+ 84*c^4-40*c^3+c^2+c,
2782
+ 7*b+210*c^3-79*c^2+3*c,
2783
+ 7*a-420*c^3+158*c^2+8*c-7
2784
+ """
2785
+ self.singular.option("set", self.o)
2786
+ try:
2787
+ self.singular.eval('degBound=%d' % self.bck_degBound)
2788
+ except SingularError:
2789
+ pass
2790
+ try:
2791
+ self.singular.eval('multBound=%d' % self.bck_multBound)
2792
+ except SingularError:
2793
+ pass
2794
+
2795
+
2796
+ def singular_gb_standard_options(func):
2797
+ r"""
2798
+ Decorator to force a reduced Singular groebner basis.
2799
+
2800
+ TESTS::
2801
+
2802
+ sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
2803
+ sage: J = sage.rings.ideal.Cyclic(P).homogenize()
2804
+ sage: from sage.misc.sageinspect import sage_getsource
2805
+ sage: "basis" in sage_getsource(J.interreduced_basis) #indirect doctest
2806
+ True
2807
+
2808
+ The following tests against a bug that was fixed in :issue:`11298`::
2809
+
2810
+ sage: from sage.misc.sageinspect import sage_getsourcelines, sage_getargspec
2811
+ sage: P.<x,y> = QQ[]
2812
+ sage: I = P*[x,y]
2813
+ sage: sage_getargspec(I.interreduced_basis)
2814
+ FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None,
2815
+ kwonlyargs=[], kwonlydefaults=None, annotations={})
2816
+ sage: sage_getsourcelines(I.interreduced_basis)
2817
+ ([' @handle_AA_and_QQbar\n',
2818
+ ' @singular_gb_standard_options\n',
2819
+ ' @libsingular_gb_standard_options\n',
2820
+ ' def interreduced_basis(self):\n', '
2821
+ ...
2822
+ ' return self.basis.reduced()\n'], ...)
2823
+
2824
+ .. NOTE::
2825
+
2826
+ This decorator is used automatically internally so the user
2827
+ does not need to use it manually.
2828
+ """
2829
+ from sage.misc.decorators import sage_wraps
2830
+
2831
+ @sage_wraps(func)
2832
+ def wrapper(*args, **kwds):
2833
+ with SingularGBDefaultContext():
2834
+ return func(*args, **kwds)
2835
+ return wrapper