|
| 1 | +module RAG |
| 2 | + |
| 3 | +using Nemo |
| 4 | + |
| 5 | +export has_real_solutions, points_per_components |
| 6 | + |
| 7 | +function _flint_get_str_pretty(p::QQMPolyRingElem)::String |
| 8 | + R = parent(p) |
| 9 | + x = map(var -> Base.unsafe_convert(Cstring, string(var)), gens(R)) |
| 10 | + str = @ccall Nemo.libflint.fmpq_mpoly_get_str_pretty(p::Ref{QQMPolyRingElem}, x::Ptr{Ref{Cstring}}, R::Ref{QQMPolyRing})::Cstring |
| 11 | + unsafe_string(str) |
| 12 | +end |
| 13 | + |
| 14 | +function _get_str(f::Vector{QQMPolyRingElem})::String |
| 15 | + join([_flint_get_str_pretty(p) for p in f], ", ") |
| 16 | +end |
| 17 | + |
| 18 | +function _call_procedure_with_maple( |
| 19 | + procedure::String; |
| 20 | + savelibname::String=joinpath(homedir(), "libs"), |
| 21 | + maple_path::String="maple", |
| 22 | + msolve_path::String="msolve", |
| 23 | +)::String |
| 24 | + if !isfile(joinpath(savelibname, "MSolve.mla")) |
| 25 | + error("Could not find MSolve.mla in $savelibname. Please set savelibname to the correct path.") |
| 26 | + end |
| 27 | + if isnothing(Sys.which(maple_path)) |
| 28 | + error("Could not find Maple executable. Please set maple_path to the correct path.") |
| 29 | + end |
| 30 | + if isnothing(Sys.which(msolve_path)) |
| 31 | + error("Could not find MSolve executable. Please set msolve_path to the correct path.") |
| 32 | + end |
| 33 | + input = tempname() |
| 34 | + output = tempname() |
| 35 | + open(input, "w") do io |
| 36 | + println(io, "savelibname := \"$savelibname\":") |
| 37 | + println(io, "libname := savelibname, libname:") |
| 38 | + println(io, "MSolve:-SetMSolvePath(\"$msolve_path\"):") |
| 39 | + println(io, "f:=proc()") |
| 40 | + println(io, procedure) |
| 41 | + println(io, "end proc:") |
| 42 | + println(io, "fd := fopen(\"$output\", WRITE):") |
| 43 | + println(io, "fprintf(fd, \"%a\\n\", f()):") |
| 44 | + println(io, "fclose(fd):") |
| 45 | + end |
| 46 | + command = Cmd(`$maple_path -q $input`) |
| 47 | + run(command) |
| 48 | + line = open(output, "r") do io |
| 49 | + readline(io) |
| 50 | + end |
| 51 | + line |
| 52 | +end |
| 53 | + |
| 54 | +function has_real_solutions( |
| 55 | + eqs::Vector{QQMPolyRingElem}, |
| 56 | + pos::Vector{QQMPolyRingElem}, |
| 57 | + ineqs::Vector{QQMPolyRingElem}; |
| 58 | + savelibname::String=joinpath(homedir(), "libs"), |
| 59 | + maple_path::String="maple", |
| 60 | + msolve_path::String="msolve", |
| 61 | + info_level::Int=0 |
| 62 | +)::Vector{Vector{Vector{QQFieldElem}}} |
| 63 | + procedure = """ |
| 64 | + local vars, res: |
| 65 | + vars := [$(_get_str(gens(parent([eqs; pos; ineqs][1]))))]: |
| 66 | + res := HasRealSolutions([$(_get_str(eqs))], [$(_get_str(pos))], [$(_get_str(ineqs))], {"verb"=$info_level}): |
| 67 | + return map(point -> subs(point, vars), res): |
| 68 | + """ |
| 69 | + line = _call_procedure_with_maple(procedure; savelibname, maple_path, msolve_path) |
| 70 | + line = replace(line, r"(-?\d+)/(\d+)" => s"QQ(\1)/QQ(\2)") |
| 71 | + line = replace(line, r"(-?\d+)" => s"QQ(\1)") |
| 72 | + res = eval(Meta.parse(line)) |
| 73 | + res |
| 74 | +end |
| 75 | + |
| 76 | +function points_per_components( |
| 77 | + eqs::Vector{QQMPolyRingElem}, |
| 78 | + pos::Vector{QQMPolyRingElem}, |
| 79 | + ineqs::Vector{QQMPolyRingElem}; |
| 80 | + savelibname::String=joinpath(homedir(), "libs"), |
| 81 | + maple_path::String="maple", |
| 82 | + msolve_path::String="msolve", |
| 83 | + info_level::Int=0 |
| 84 | +)::Vector{Vector{Vector{QQFieldElem}}} |
| 85 | + procedure = """ |
| 86 | + local vars, res: |
| 87 | + vars := [$(_get_str(gens(parent([eqs; pos; ineqs][1]))))]: |
| 88 | + res := PointsPerComponents([$(_get_str(eqs))], [$(_get_str(pos))], [$(_get_str(ineqs))], {"verb"=$info_level}): |
| 89 | + return map(point -> subs(point, vars), res): |
| 90 | + """ |
| 91 | + line = _call_procedure_with_maple(procedure; savelibname, maple_path, msolve_path) |
| 92 | + line = replace(line, r"(-?\d+)/(\d+)" => s"QQ(\1)/QQ(\2)") |
| 93 | + line = replace(line, r"(-?\d+)" => s"QQ(\1)") |
| 94 | + res = eval(Meta.parse(line)) |
| 95 | + res |
| 96 | +end |
| 97 | + |
| 98 | +end # module RAG |
0 commit comments