Skip to content

Commit e72afd6

Browse files
committed
Add RAGlib wrappers
1 parent 2171d26 commit e72afd6

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

src/AlgebraicSolving.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ include("siggb/siggb.jl")
2222
include("progress/main.jl")
2323
#= interp =#
2424
include("interp/main.jl")
25+
#= rag =#
26+
include("rag/main.jl")
2527
#= examples =#
2628
include("examples/katsura.jl")
2729
include("examples/cyclic.jl")

src/rag/main.jl

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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

Comments
 (0)