This illustrates how to compute a Göbner basis of an arbitrary polynomial ideal (within the bounds this system can handle). The program is suitable for running stand-alone, as it prompts the user for all information, but it is probably better to pipe as input a file formatted similarly to those in the directory example_systems_for_user_interface
. The basic format is:
#include <list>
#include <string>
#include <iostream>
using std::list;
using std::string;
using std::cin; using std::cout; using std::endl;
#include "system_constants.hpp"
#include "monomial.hpp"
#include "dynamic_engine.hpp"
#include "polynomial_array.hpp"
#include "algorithm_buchberger_dynamic.hpp"
UCOEF_TYPE p;
cout << "prime number for base field: ";
cin >> p;
NVAR_TYPE n;
cout << "number of indeterminates: ";
cin >> n;
char specify_names;
cout << "do you want to specify the indeterminates' names? (y/n) ";
cin >> specify_names;
string * names = new string[n];
if (not specify_names) {
cout << "indeterminate names are: ";
for (NVAR_TYPE i = 0; i < n; ++i) {
}
} else {
for (NVAR_TYPE i = 0; i < n; ++i)
cin >> names[i];
}
unsigned m;
cout << "number of polynomials: ";
cin >> m;
cin.ignore();
list<Abstract_Polynomial *> I;
for (unsigned np = 0; np < m; ++np) {
cout << "please enter polynomial #" << np << ": (use spaces to separate factors) ";
string inpoly;
getline(cin, inpoly);
list<Monomial> M;
list<Prime_Field_Element> A;
unsigned nt = 0;
unsigned i = 0;
while (i < inpoly.size()) {
bool reading_term = true;
COEF_TYPE a = 1;
EXP_TYPE exp[n];
for (NVAR_TYPE i = 0; i < n; ++i) exp[i] = 0;
bool positive = true;
while (inpoly[i] == ' ') ++i;
while (reading_term and i < inpoly.size()) {
unsigned j = i;
if (
inpoly[i] == '+' or inpoly[i] == '-' or
(inpoly[i] >= '0' and inpoly[i] <= '9')
) {
bool positive = true;
if (inpoly[i] == '-') positive = false;
if (inpoly[i] == '+' or inpoly[i] == '-') ++i;
while (inpoly[i] == ' ') ++i;
if (inpoly[i] >= '0' and inpoly[i] <= '9') {
j = i;
while (inpoly[j] >= '0' and inpoly[j] <= '9') ++j;
a *= stol(inpoly.substr(i, j - i));
if (not positive) a *= -1;
i = j;
}
}
else if (inpoly[i] == '*')
++i;
else if (inpoly[i] == '\0')
++i;
else {
unsigned j = i;
while ((inpoly[j] >= 'a' and inpoly[j] <= 'z') or
(inpoly[j] >= 'A' and inpoly[j] <= 'Z') or
(inpoly[j] >= '0' and inpoly[j] <= '9'))
++j;
string var_name = inpoly.substr(i, j - i);
bool found = false;
unsigned k = 0;
for (; not found and k < n; ++k)
if (var_name.compare(names[k]) == 0) {
found = true;
--k;
}
i = j;
while (inpoly[i] == ' ') ++i;
if (inpoly[i] != '^')
exp[k] += 1;
else {
++i;
while (inpoly[i] == ' ') ++i;
unsigned j = i;
while (inpoly[j] >= '0' and inpoly[j] <= '9') ++j;
exp[k] += stol(inpoly.substr(i, j - i));
i = j;
}
}
while (inpoly[i] == ' ') ++i;
if (inpoly[i] == '+' or inpoly[i] == '-') reading_term = false;
}
++nt;
if (not positive) a *= -1;
M.push_back(t);
A.emplace_back(a, &F);
}
cout << "read " << *p << endl;
I.push_back(p);
}
string computation;
while (
computation.compare("s") and computation.compare("d")
and computation.compare("static") and computation.compare("dynamic")
) {
cout << "static (s) or dynamic (d) computation? ";
getline(cin, computation);
}
list<Constant_Polynomial *> B;
bool dynamic = not (computation.compare("d") and computation.compare("dynamic"));
if (not dynamic) {
} else {
string solver_choice;
while (
solver_choice.compare("skel") and solver_choice.compare("glpk")
and solver_choice.compare("ppl") and solver_choice.compare("skeleton")
) {
cout << "which solver? ([skel]eton, glpk, ppl) ";
getline(cin, solver_choice);
}
if (not solver_choice.compare("skel") or not solver_choice.compare("skeleton"))
solver = SKELETON_SOLVER;
else if (not solver_choice.compare("glpk"))
solver = GLPK_SOLVER;
else if (not solver_choice.compare("ppl"))
solver = PPL_SOLVER;
string heur_choice;
while (
heur_choice.compare("h") and heur_choice.compare("gh")
and heur_choice.compare("b") and heur_choice.compare("bb")
and heur_choice.compare("gb") and heur_choice.compare("c")
and heur_choice.compare("d")
) {
cout << "available heuristics are\n";
cout << "\t h = hilbert with standard grading\n";
cout << "\tgh = hilbert with order-based grading\n";
cout << "\t b = betti with standard grading\n";
cout << "\tbb = \"big\" betti with standard grading\n";
cout << "\tgb = betti with order-based grading\n";
cout << "\t c = minimal number of critical pairs\n";
cout << "\t d = minimal degree, ties broken by hilbert\n";
cout << "which heuristic would you like? ";
getline(cin, heur_choice);
}
if (not heur_choice.compare( "h")) heuristic = DynamicHeuristic::ORD_HILBERT_THEN_DEG;
else if (not heur_choice.compare("gh")) heuristic = DynamicHeuristic::GRAD_HILB_THEN_DEG;
else if (not heur_choice.compare( "b")) heuristic = DynamicHeuristic::BETTI_HILBERT_DEG;
else if (not heur_choice.compare("bb")) heuristic = DynamicHeuristic::BIG_BETTI_HILBERT_DEG;
else if (not heur_choice.compare("gb")) heuristic = DynamicHeuristic::GRAD_BETTI_HILBERT_DEG;
else if (not heur_choice.compare( "c")) heuristic = DynamicHeuristic::MIN_CRIT_PAIRS;
else if (not heur_choice.compare( "d")) heuristic = DynamicHeuristic::DEG_THEN_ORD_HILBERT;
string whether_analysis;
bool analyze_first = false;
while (whether_analysis.compare("y") and whether_analysis.compare("n")) {
cout << "perform global analysis at the outset? (y or n) ";
cin >> whether_analysis;
}
if (not whether_analysis.compare("y")) analyze_first = true;
I, SPolyCreationFlags::GEOBUCKETS, StrategyFlags::SUGAR_STRATEGY,
nullptr, heuristic, solver, analyze_first
);
}
cout << "have basis with " << B.size() << " elements:\n";
for (auto b : B) {
cout << b->leading_monomial() << ", ";
delete b;
}
cout << endl;
for (auto p : I) delete p;
delete P;
delete [] names;
}
int main() {
}