From 5dde4464578c12ab8ea71011df2080157c32751e Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 02:00:16 +0200 Subject: [PATCH 01/10] added top-level type QQi to Msolve --- M2/Macaulay2/packages/Msolve.m2 | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index ad73febc02..f7bb21afbe 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -168,6 +168,46 @@ addHook((saturate, Ideal, RingElement), Strategy => Msolve, -- msolveSaturate doesn't use any options of saturate, like DegreeLimit, etc. (opts, I, f) -> try ideal msolveSaturate(I, f)) +-------------------------------------------------------------------------------- +-- Rational interval type, constructors, and basic methods +-------------------------------------------------------------------------------- + +QQi = new Ring of List -- TODO: array looks better, but List implements arithmetic by default! +QQi.synonym = "rational interval" + +ring QQi := x -> QQi +precision QQi := x -> infinity + +QQinterval = method(TypicalValue => QQi) +QQinterval VisibleList := bounds -> ( + if #bounds == 2 then QQinterval(bounds#0, bounds#1) + else error "expected a lower bound and upper bound") +QQinterval Number := midpt -> QQinterval(midpt/1, midpt/1) +QQinterval InexactNumber := midpt -> QQinterval lift(midpt, QQ) +QQinterval(InexactNumber, InexactNumber) := (L, R) -> QQinterval(lift(L, QQ), lift(R, QQ)) +QQinterval(Number, Number) := (L, R) -> new QQi from [L/1, R/1] + +-- TODO: these are compiled functions, make them methods and define for QQi +left' = first +right' = last +midpoint' = int -> sum int / 2 +diameter QQi := x -> x#1 - x#0 + +interval QQi := opts -> x -> interval(x#0, x#1, opts) + +QQi == Number := +Number == QQi := (x, y) -> QQinterval x == QQinterval y + +-- ZZ, QQ, RR, RRi +promote(Number, QQi) := (n, QQi) -> QQinterval n + +-- ZZ, QQ +lift(QQi, Number) := o -> (x, R) -> ( + if diameter x == 0 then lift(midpoint' x, R) + else if o.Verify then error "lift: interval has positive diameter") + +-------------------------------------------------------------------------------- + msolveRealSolutions = method(TypicalValue => List, Options => msolveDefaultOptions ++ { "output type" => "rational interval" }) msolveRealSolutions Ideal := opt -> I0 -> ( From 6a72f4d3a1bd0a18e6f4bec08b5cae83103cbfd9 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 00:30:37 +0200 Subject: [PATCH 02/10] improved msolveRealSolutions inputs and outputs --- M2/Macaulay2/packages/Msolve.m2 | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index f7bb21afbe..1d7174118b 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -24,7 +24,8 @@ export{ "msolveEliminate", "msolveRUR", "msolveLeadMonomials", - "msolveRealSolutions" + "msolveRealSolutions", + "QQi", } importFrom_Core { "raw", "rawMatrixReadMsolveFile" } @@ -208,20 +209,25 @@ lift(QQi, Number) := o -> (x, R) -> ( -------------------------------------------------------------------------------- -msolveRealSolutions = method(TypicalValue => List, - Options => msolveDefaultOptions ++ { "output type" => "rational interval" }) -msolveRealSolutions Ideal := opt -> I0 -> ( +msolveRealSolutions = method(TypicalValue => List, Options => msolveDefaultOptions) +msolveRealSolutions Ideal := opt -> I0 -> msolveRealSolutions(I0, QQi, opt) +msolveRealSolutions(Ideal, RingFamily) := opt -> (I0, F) -> msolveRealSolutions(I0, default F, opt) +msolveRealSolutions(Ideal, Ring) := opt -> (I0, F) -> ( + if not any({QQ, QQi, RR_*, RRi_*}, F' -> ancestor(F', F)) + then error "msolveRealSolutions: expected target field to be rationals, reals, or a rational or real interval field"; (S, K, I) := toMsolveRing I0; - mOut := msolve(S, K, I_*, "", opt); -- optional: -p precision + prec := if precision F === infinity then defaultPrecision else precision F; + mOut := msolve(S, K, I_*, "-p " | prec, opt); -- format: [dim, [numlists, [ solution boxes ]]] - solsp := readMsolveList get mOut; - if solsp_0>0 then (error "Input ideal not zero dimensional, no solutions found.";); - if (solsp_1)_0>1 then (print "unexpected msolve output, returning full output"; return solsp;); - sols:=(solsp_1)_1; - if opt#"output type"=="rational interval" then return sols; - if opt#"output type"=="float interval" then return (1.0*sols); - if opt#"output type"=="float middle point" then return (for s in sols list(for s1 in s list sum(s1)/2.0)); - ); + (d, solsp) := toSequence readMsolveList get mOut; + if d =!= 0 then error "msolveRealSolutions: expected zero dimensional system of equations"; + if solsp_0 > 1 then ( + printerr "msolveRealSolutions: unexpected msolve output, returning full output"; return {d, solsp}); + sols := apply(last solsp, sol -> apply(sol, QQinterval)); + if ancestor(QQi, F) then sols else + if ancestor(QQ, F) then apply(sols, sol -> apply(sol, midpoint')) else + if ancestor(RR_*, F) then apply(sols, sol -> apply(sol, midpoint') * 1_F) else + if ancestor(RRi_*, F) then apply(sols, sol -> apply(sol, range -> interval(range, Precision => prec)))) msolveRUR = method(TypicalValue => List, Options => msolveDefaultOptions) msolveRUR Ideal := opt -> I0 ->( From d95165e9a694a45137fca8e692be8b0a750f9f28 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 01:44:46 +0200 Subject: [PATCH 03/10] added tests for new msolveRealSolutions inputs --- M2/Macaulay2/packages/Msolve/tests.m2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/M2/Macaulay2/packages/Msolve/tests.m2 b/M2/Macaulay2/packages/Msolve/tests.m2 index cd5a10819c..0eedb9cc0e 100644 --- a/M2/Macaulay2/packages/Msolve/tests.m2 +++ b/M2/Macaulay2/packages/Msolve/tests.m2 @@ -70,7 +70,10 @@ TEST /// TEST /// R = QQ[x,y]; I = ideal ((x-3)*(x^2+1),y-1); - assert({{3.0, 1.0}} == msolveRealSolutions(I, "output type" => "float middle point")) + assert(msolveRealSolutions I == {{3.0, 1.0}}) + assert(msolveRealSolutions I === msolveRealSolutions(I, QQi)) + scan({QQ, QQi, RR, RR_53, RRi, RR_53}, + F -> assert({{3.0, 1.0}} == msolveRealSolutions(I, F))) /// TEST /// From 6a2f4be50754bd571e77ca3185889583405313fb Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 01:57:17 +0200 Subject: [PATCH 04/10] documented new msolveRealSolutions inputs --- M2/Macaulay2/packages/Msolve.m2 | 63 ++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index 1d7174118b..e9cbfa6564 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -403,58 +403,73 @@ Node degree lm dim lm +Node + Key + QQi + Headline + the class of all rational intervals + Description + Text + This class is similar to the class of @TO2(RRi, "real intervals")@, + except that the boundaries are arbitrary precision rational numbers. + Caveat + Currently this class is not implemented in the interpreter, + which means rings or matrices over rational intervals are not supported, + and many functionalities of @TO RRi@ are not yet available. + Node Key msolveRealSolutions (msolveRealSolutions, Ideal) + (msolveRealSolutions, Ideal, Ring) + (msolveRealSolutions, Ideal, RingFamily) [msolveRealSolutions, Threads] [msolveRealSolutions, Verbosity] Headline compute all real solutions to a zero dimensional system using symbolic methods Usage msolveRealSolutions(I) + msolveRealSolutions(I, K) Inputs I:Ideal which is zero dimensional, in a polynomial ring with coefficients over @TO QQ@ + K:{Ring,RingFamily} + the field to find answers in, which must be one of + @TO QQi@ (default), @TO QQ@, @TO RR@, or @TO RRi@ (possibly with specified precision) Threads => ZZ -- number of processor threads to use Verbosity => ZZ -- level of verbosity between 0, 1, and 2 Outputs - Sols:List - of lists; each entry in the list @TT "Sols"@ consists of a list representing + :List + of lists; each entry in the list consists of a list representing the coordinates of a solution. By default each solution coordinate value is - also represented by a two element list of rational numbers, {a, b}, this means - that that coordinate of the solution has a value greater than or equal to a and - less than or equal to b. This interval is computed symbolically and its correctness - is guaranteed by exact methods. + also represented by a @TO2(QQi, "rational interval")@ consisting of a two element + list of rational numbers, @TT "{a, b}"@, this means that that coordinate of the + solution has a value greater than or equal to @TT "a"@ and less than or equal to @TT "b"@. + This interval is computed symbolically and its correctness is guaranteed by exact methods. Description Text This functions uses the msolve package to compute the real solutions to a zero dimensional polynomial ideal with either integer or rational coefficients. - The output is a list of lists, each entry in the list Sol consists of a list - representing the coordinates of a solution. By default each solution coordinate - value is also represented by a two element list of rational numbers, {a, b}, - this means that that coordinate of the solution has a value greater than or - equal to a and less than or equal to b. This interval is computed symbolically - and its correctness is guaranteed by exact methods. Text - Option "output type" (default = "rational interval") gives alternative ways to provide output - either using @TO RRi@ ("float interval") - or by taking a floating point approximation of the average of the interval endpoints ("float middle point"). - Text - First an example over a finite field + The second input is optional, and indicates the alternative ways to provide output + either using an exact rational interval @TO QQi@, a real interval @TO RRi@, + or by taking a rational or real approximation of the midpoint of the intervals. Example R = QQ[x,y] I = ideal {(x-1)*x, y^2-5} - sols = msolveRealSolutions I - floatSolsInterval = msolveRealSolutions(I,"output type"=>"float interval") - floatAproxSols = msolveRealSolutions(I,"output type"=>"float middle point") + rationalIntervalSols = msolveRealSolutions I + rationalApproxSols = msolveRealSolutions(I, QQ) + floatIntervalSols = msolveRealSolutions(I, RRi) + floatIntervalSols = msolveRealSolutions(I, RRi_10) + floatApproxSols = msolveRealSolutions(I, RR) + floatApproxSols = msolveRealSolutions(I, RR_10) Text Note in cases where solutions have multiplicity this is not reflected in the output. While the solver does not return multiplicities, it reliably outputs the verified isolating intervals for multiple solutions. Example I = ideal {(x-1)*x^3, (y^2-5)^2} - floatAproxSols=msolveRealSolutions(I,"output type"=>"float interval") + floatApproxSols = msolveRealSolutions(I, RRi) Node Key msolveRUR @@ -548,15 +563,15 @@ Node This functions uses the F4SAT algorithm implemented in the msolve library to compute a Groebner basis, in GRevLex order, of $I:f^\infty$, that is of the saturation of the ideal $I$ by the principal ideal generated by the polynomial $f$. - Text - First an example; note the ring must be a polynomial ring over a finite field Example R=ZZ/1073741827[z_1..z_3] I=ideal(z_1*(z_2^2-17*z_1-z_3^3),z_1*z_2) satMsolve=ideal msolveSaturate(I,z_1) satM2=saturate(I,z_1) + Text + Note that the ring must be a polynomial ring over a finite field. Caveat - Currently this algorithm only works over prime fields in characteristic between $2^{16}$ and $2^{31}$. + Currently the F4SAT algorithm is only implemented over prime fields in characteristic between $2^{16}$ and $2^{31}$. Node Key From 0d09d557cb6b6460783a7b9fc390e0e28175a4fe Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 00:35:26 +0200 Subject: [PATCH 05/10] capped msolveDefaultPrecision to 32bits --- M2/Macaulay2/packages/Msolve.m2 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index e9cbfa6564..13bfc365ab 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -209,14 +209,16 @@ lift(QQi, Number) := o -> (x, R) -> ( -------------------------------------------------------------------------------- +msolveDefaultPrecision = 32 -- alternative: defaultPrecision + msolveRealSolutions = method(TypicalValue => List, Options => msolveDefaultOptions) -msolveRealSolutions Ideal := opt -> I0 -> msolveRealSolutions(I0, QQi, opt) -msolveRealSolutions(Ideal, RingFamily) := opt -> (I0, F) -> msolveRealSolutions(I0, default F, opt) +msolveRealSolutions Ideal := opt -> I0 -> msolveRealSolutions(I0, QQi, opt) +msolveRealSolutions(Ideal, RingFamily) := opt -> (I0, F) -> msolveRealSolutions(I0, F_msolveDefaultPrecision, opt) msolveRealSolutions(Ideal, Ring) := opt -> (I0, F) -> ( if not any({QQ, QQi, RR_*, RRi_*}, F' -> ancestor(F', F)) then error "msolveRealSolutions: expected target field to be rationals, reals, or a rational or real interval field"; (S, K, I) := toMsolveRing I0; - prec := if precision F === infinity then defaultPrecision else precision F; + prec := if precision F === infinity then msolveDefaultPrecision else precision F; mOut := msolve(S, K, I_*, "-p " | prec, opt); -- format: [dim, [numlists, [ solution boxes ]]] (d, solsp) := toSequence readMsolveList get mOut; From e0aac34132818f2ba6818350920c5bc71cff66b5 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 02:18:35 +0200 Subject: [PATCH 06/10] bumped up minimum output precision of Msolve to 53 --- M2/Macaulay2/packages/Msolve.m2 | 6 ++++-- M2/Macaulay2/packages/Msolve/tests.m2 | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index 13bfc365ab..d79da07364 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -218,6 +218,7 @@ msolveRealSolutions(Ideal, Ring) := opt -> (I0, F) -> ( if not any({QQ, QQi, RR_*, RRi_*}, F' -> ancestor(F', F)) then error "msolveRealSolutions: expected target field to be rationals, reals, or a rational or real interval field"; (S, K, I) := toMsolveRing I0; + -- if precision is not specified, we want to use msolve's default precision prec := if precision F === infinity then msolveDefaultPrecision else precision F; mOut := msolve(S, K, I_*, "-p " | prec, opt); -- format: [dim, [numlists, [ solution boxes ]]] @@ -225,10 +226,11 @@ msolveRealSolutions(Ideal, Ring) := opt -> (I0, F) -> ( if d =!= 0 then error "msolveRealSolutions: expected zero dimensional system of equations"; if solsp_0 > 1 then ( printerr "msolveRealSolutions: unexpected msolve output, returning full output"; return {d, solsp}); + prec = max(defaultPrecision, prec); -- we want the output precision to be at least defaultPrecision sols := apply(last solsp, sol -> apply(sol, QQinterval)); if ancestor(QQi, F) then sols else - if ancestor(QQ, F) then apply(sols, sol -> apply(sol, midpoint')) else - if ancestor(RR_*, F) then apply(sols, sol -> apply(sol, midpoint') * 1_F) else + if ancestor(QQ, F) then apply(sols, sol -> apply(sol, midpoint')) else + if ancestor(RR_*, F) then apply(sols, sol -> apply(sol, midpoint') * numeric(prec, 1)) else if ancestor(RRi_*, F) then apply(sols, sol -> apply(sol, range -> interval(range, Precision => prec)))) msolveRUR = method(TypicalValue => List, Options => msolveDefaultOptions) diff --git a/M2/Macaulay2/packages/Msolve/tests.m2 b/M2/Macaulay2/packages/Msolve/tests.m2 index 0eedb9cc0e..1dc64e4b77 100644 --- a/M2/Macaulay2/packages/Msolve/tests.m2 +++ b/M2/Macaulay2/packages/Msolve/tests.m2 @@ -74,6 +74,13 @@ TEST /// assert(msolveRealSolutions I === msolveRealSolutions(I, QQi)) scan({QQ, QQi, RR, RR_53, RRi, RR_53}, F -> assert({{3.0, 1.0}} == msolveRealSolutions(I, F))) + assert(precision first first msolveRealSolutions I == infinity) + assert(precision first first msolveRealSolutions(I, RR) == defaultPrecision) + assert(precision first first msolveRealSolutions(I, RR_20) == defaultPrecision) + assert(precision first first msolveRealSolutions(I, RR_100) == 100) + assert(precision first first msolveRealSolutions(I, RRi) == defaultPrecision) + assert(precision first first msolveRealSolutions(I, RRi_20) == defaultPrecision) + assert(precision first first msolveRealSolutions(I, RRi_100) == 100) /// TEST /// From 5dde0d0e591841fb0717d9ce92c1458c2acd70f0 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 02:41:58 +0200 Subject: [PATCH 07/10] fixed a bug in finding older msolve versions --- M2/Macaulay2/packages/Msolve.m2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index d79da07364..80e63b20fa 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -45,8 +45,9 @@ msolveProgram = findProgram("msolve", "msolve --help", if msolveProgram === null then ( if not (options currentPackage).OptionalComponentsPresent then ( printerr "warning: msolve cannot be found; ending"; end ) - else ( printerr "warning: msolve found but its version is older than v" | msolveMinimumVersion; - msolveProgram = findProgram("msolve", "msolve --help", Verbose => debugLevel > 0))) + else ( printerr("warning: msolve found but its version is older than v" | msolveMinimumVersion); + -- note: msolve -h returns status code 1 :/ + msolveProgram = findProgram("msolve", "true", Verbose => debugLevel > 0))) msolveDefaultOptions = new OptionTable from { Threads => allowableThreads, From ca232acdee4b9ebd6ce149681e381fcb5380e313 Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 03:05:12 +0200 Subject: [PATCH 08/10] trimmed comment lines in readMsolveList --- M2/Macaulay2/packages/Msolve.m2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index 80e63b20fa..44c4a85071 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -114,6 +114,8 @@ readMsolveOutputFile(Ring,String) := Matrix => (R,mOut) -> if use'readMsolveOutp ) readMsolveList = mOutStr -> ( + mOutStr = toString stack select(lines mOutStr, + line -> not match("#", line)); mOutStr = replace("\\[", "{", mOutStr); mOutStr = replace("\\]", "}", mOutStr); -- e.g. 'p_0' to "p_0" From 76acbf4b83dd743741c9b1ca0f1965da24fd71bb Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 03:35:09 +0200 Subject: [PATCH 09/10] fixed the top-level version of readMsolveOutputFile --- M2/Macaulay2/packages/Msolve.m2 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/M2/Macaulay2/packages/Msolve.m2 b/M2/Macaulay2/packages/Msolve.m2 index 44c4a85071..e4e81af325 100644 --- a/M2/Macaulay2/packages/Msolve.m2 +++ b/M2/Macaulay2/packages/Msolve.m2 @@ -106,12 +106,10 @@ readMsolveOutputFile(Ring,String) := Matrix => (R,mOut) -> if use'readMsolveOutp -- TODO: this substitution should be unnecessary, -- but without it the result for tower rings is in the wrong order! then substitute(map(R, rawMatrixReadMsolveFile(raw R, mOut)), R) else ( - msolveOut := get mOut; - moutStrL:=separate(",",first separate("[]]",last separate("[[]",msolveOut))); - --the line below should be replaced by a call to the C-function to parse the string - M2Out:=for s in moutStrL list value(s); - matrix {M2Out}; - ) + --the line below should be replaced by a call to the C-function to parse the string + -- this is a hack that has global consequences (e.g. breaks rings with p_i vars) + use newRing(R, Variables => numgens R); + substitute(matrix {value readMsolveList get mOut}, vars R)) readMsolveList = mOutStr -> ( mOutStr = toString stack select(lines mOutStr, @@ -121,7 +119,7 @@ readMsolveList = mOutStr -> ( -- e.g. 'p_0' to "p_0" mOutStr = replace("'", "\"", mOutStr); mOutStr = first separate(":", mOutStr); - value mOutStr) + mOutStr) msolveGB = method(TypicalValue => Matrix, Options => msolveDefaultOptions) msolveGB Ideal := opts -> I0 -> ( @@ -225,7 +223,7 @@ msolveRealSolutions(Ideal, Ring) := opt -> (I0, F) -> ( prec := if precision F === infinity then msolveDefaultPrecision else precision F; mOut := msolve(S, K, I_*, "-p " | prec, opt); -- format: [dim, [numlists, [ solution boxes ]]] - (d, solsp) := toSequence readMsolveList get mOut; + (d, solsp) := toSequence value readMsolveList get mOut; if d =!= 0 then error "msolveRealSolutions: expected zero dimensional system of equations"; if solsp_0 > 1 then ( printerr "msolveRealSolutions: unexpected msolve output, returning full output"; return {d, solsp}); @@ -242,7 +240,7 @@ msolveRUR Ideal := opt -> I0 ->( (S, K, I) := toMsolveRing I0; mOut := msolve(S, K, I_*, "-P 2", opt); -- format: [dim, [char, nvars, deg, vars, form, [1, [lw, lwp, param]]]]: - solsp := readMsolveList get mOut; + solsp := value readMsolveList get mOut; if first solsp != 0 then error "msolveRUR: expected zero dimensional input ideal"; lc:=(solsp_1)_4; l:=sum(numgens S0,i->lc_i*S0_i); From ea5608f77f113a15bd9ce642d995f7e2fc6ed64f Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 8 Aug 2024 03:36:11 +0200 Subject: [PATCH 10/10] added broken test found by Martin --- M2/Macaulay2/packages/Msolve/tests.m2 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/M2/Macaulay2/packages/Msolve/tests.m2 b/M2/Macaulay2/packages/Msolve/tests.m2 index 1dc64e4b77..5392cdd0ea 100644 --- a/M2/Macaulay2/packages/Msolve/tests.m2 +++ b/M2/Macaulay2/packages/Msolve/tests.m2 @@ -105,6 +105,20 @@ TEST /// assert(eM2 == sub(eMsolve, ring eM2)) /// +TEST /// + --restart + debugLevel=1 + needsPackage "Msolve"; + R = QQ[x..z,t] + K = ideal(x^6+y^6+x^4*z*t+z^3,36*x^5+60*y^5+24*x^3*z*t, + -84*x^5+10*x^4*t-56*x^3*z*t+30*z^2,-84*y^5-6*x^4*t-18*z^2, + 48*x^5+10*x^4*z+32*x^3*z*t,48*y^5-6*x^4*z,14*x^4*z+8*x^4*t+24*z^2) + errorDepth=2 + W1 = msolveEliminate(R_0, K, Verbosity => 1) + W2 = eliminate(R_0, K) + sub(W1, R) == W2 +/// + end restart