using JLD function GAP_code(group_code, dir, R; maxeqns=10_000, infolevel=2) code = """ LogTo("$(dir)/GAP.log"); RequirePackage("kbmag"); SetInfoLevel(InfoRWS, $infolevel); MetricBalls := function(rws, R) local l, basis, sizes, i; l := EnumerateReducedWords(rws, 0, R);; SortBy(l, Length); sizes := [1..R]; Apply(sizes, i -> Number(l, w -> Length(w) <= i)); return [l, sizes]; end;; ProductMatrix := function(rws, basis, len) local result, dict, g, tmpList, t; result := []; dict := NewDictionary(basis[1], true); t := Runtime(); for g in [1..Length(basis)] do; AddDictionary(dict, basis[g], g); od; Print("Creating dictionary: \t\t", StringTime(Runtime()-t), "\\n"); for g in basis{[1..len]} do; tmpList := List(Inverse(g)*basis{[1..len]}, w->ReducedForm(rws, w)); #t := Runtime(); tmpList := List(tmpList, x -> LookupDictionary(dict, x)); #Print(Runtime()-t, "\\n"); Assert(1, ForAll(tmpList, x -> x <> fail)); Add(result, tmpList); od; return result; end;; SaveCSV := function(fname, pm) local file, i, j, k; file := OutputTextFile(fname, false);; for i in pm do; k := 1; for j in i do; if k < Length(i) then AppendTo(file, j, ", "); else AppendTo(file, j, "\\n"); fi; k := k+1; od; od; CloseStream(file); end;; $group_code # G:= SimplifiedFpGroup(G); RWS := KBMAGRewritingSystem(G); # ResetRewritingSystem(RWS); O:=OptionsRecordOfKBMAGRewritingSystem(RWS);; O.maxeqns := $maxeqns; O.maxstates := 1000*$maxeqns; #O.maxstoredlen := [100,100]; before := Runtimes();; KnuthBendix(RWS); after := Runtimes();; delta := after.user_time_children - before.user_time_children;; Print("Knuth-Bendix completion: \t", StringTime(delta), "\\n"); t := Runtime(); res := MetricBalls(RWS,$(2*R));; Print("Metric-Balls generation: \t", StringTime(Runtime()-t), "\\n"); B := res[1];; sizes := res[2];; Print("Sizes of generated Balls: \t", sizes, "\\n"); t := Runtime(); pm := ProductMatrix(RWS, B, sizes[$R]);; Print("Computing ProductMatrix: \t", StringTime(Runtime()-t), "\\n"); S := EnumerateReducedWords(RWS, 1, 1); S := List(S, s -> Position(B,s)); SaveCSV("$(dir)/pm.csv", pm); SaveCSV("$(dir)/S.csv", [S]); SaveCSV("$(dir)/sizes.csv", [sizes]); Print("DONE!\\n"); quit;"""; return code end function GAP_groupcode(S, rels) F = "FreeGroup("*join(["\"$v\""for v in S], ", ") *");" m = match(r".*(\[.*\])$", string(rels)) rels = replace(m.captures[1], " ", "\n") code = """ F := $F; AssignGeneratorVariables(F);; relations := $rels;; G := F/relations; """ return code end function GAP_execute(gap_code, dir) isdir(dir) || mkdir(dir) GAP_file = joinpath(dir, "GAP_code.g") @show dir @show GAP_file; open(GAP_file, "w") do io write(io, gap_code) end run(pipeline(`cat $(GAP_file)`, `gap -q`)) end function prepare_pm_delta_csv(name, group_code, R; maxeqns=10_000, infolevel=2) info("Preparing multiplication table using GAP (via kbmag)") gap_code = GAP_code(group_code, name, R, maxeqns=maxeqns, infolevel=infolevel) GAP_execute(gap_code, name) end function prepare_pm_delta(name, group_code, R; maxeqns=100_000, infolevel=2) pm_fname = joinpath(name, "pm.csv") S_fname = joinpath(name, "S.csv") sizes_fname = joinpath(name, "sizes.csv") delta_fname = joinpath(name, "delta.jld") if !isfile(pm_fname) || !isfile(S_fname) || !isfile(sizes_fname) prepare_pm_delta_csv(name, group_code, R, maxeqns=maxeqns, infolevel=infolevel) end if isfile(sizes_fname) sizes = readcsv(sizes_fname, Int)[1,:] if 2R > length(sizes) prepare_pm_delta_csv(name, group_code, R, maxeqns=maxeqns, infolevel=infolevel) end end pm = readcsv(pm_fname, Int) S = readcsv(S_fname, Int)[1,:] sizes = readcsv(sizes_fname, Int)[1,:] Δ = spzeros(sizes[2R]) Δ[S] .= -1 Δ[1] = length(S) pm = pm[1:sizes[R], 1:sizes[R]] save(joinpath(name, "pm.jld"), "pm", pm) save(joinpath(name, "delta.jld"), "Δ", Δ) end