\[ x_1 + \cdots + x_n,\\ x_1 x_2 + x_2 x_3 + \cdots + x_n x_1,\\ x_1 x_2 x_3 + x_2 x_3 x_4 + \cdots + x_n x_1 x_2,\\ \vdots\\ x_1 \cdots x_{n-1} + x_2 \cdots x_n + \cdots + x_n x_1 \cdots x_{n-2},\\ x_1 \cdots x_n - 1 \]
#include <set>
#include <cstring>
#include <iostream>
using std::set;
using std::cout; using std::endl;
#include "system_constants.hpp"
#include "goda.hpp"
#include "cyclic_n.hpp"
#include "polynomial.hpp"
#include "strategies.hpp"
#include "dynamic_engine.hpp"
#include "monomial_ordering.hpp"
#include "particular_orderings.hpp"
#include "polynomial_linked_list.hpp"
#include "algorithm_buchberger_dynamic.hpp"
bool meaningful_arguments(
);
void give_help();
int main(int argc, char *argv[]) {
bool homog;
int modulus, numvars;
WT_TYPE * grading = nullptr;
if (not meaningful_arguments(
argc, argv, homog, modulus, numvars, method, strategy, heuristic, solver
)) {
give_help();
} else {
int true_numvars = (homog) ? numvars + 1 : numvars;
grading = new WT_TYPE [true_numvars];
for (NVAR_TYPE i = 0; i < true_numvars; ++i) grading[i] = 1;
list<Abstract_Polynomial *> F =
cyclic_n(numvars, FF, homog, mord);
cout << "Computing a Groebner basis for:\n";
cout << '\t' << *f << endl;
cout << "Using ";
switch(solver) {
case GLPK_SOLVER: cout << "GLPK\n"; break;
case SKELETON_SOLVER: cout << "Skeleton\n"; break;
case PPL_SOLVER: cout << "PPL\n"; break;
default: cout << "Unknown solver\n"; break;
}
);
cout << G.size() << " polynomials in basis:\n";
G.front()->monomial_ordering()
);
cout << G.size() << " leading monomials:\n";
cout << g->leading_monomial() << ", ";
delete g;
}
cout << endl;
delete R;
}
if (ford != nullptr) {
delete ford;
}
if (mord != generic_grevlex_ptr) delete mord;
if (goda !=
nullptr)
delete goda;
if (doda !=
nullptr)
delete doda;
if (moda !=
nullptr)
delete moda;
if (monoda !=
nullptr)
delete monoda;
if (monododa !=
nullptr)
delete monododa;
if (woda !=
nullptr)
delete woda;
if (grading != nullptr) delete [] grading;
cout << "bye\n";
}
enum order_flags { GENERIC_GREVLEX = 0, GREVLEX, LEX, WGREVLEX };
bool meaningful_arguments(
int argc, char *argv[],
bool & homogeneous, int & modulus, int & numvars,
) {
modulus = 43;
method = SPolyCreationFlags::GEOBUCKETS;
homogeneous = false;
WT_TYPE * weights = nullptr;
unsigned int order_flag = 0;
bool good_args = (argc > 1);
if (good_args) {
for (int i = 1; good_args and i < argc; ++i) {
if (!strcmp(argv[i],"hom") or !strcmp(argv[i],"homog")
or !strcmp(argv[i],"homogeneous"))
homogeneous = true;
else {
int j = 0;
for (; argv[i][j] != '=' and argv[i][j] != '\0'; ++j) { }
if (argv[i][j] != '=') {
good_args = false;
cout << "Options must have form <option>=<value>.\n";
}
else {
argv[i][j] = '\0';
if (!strcmp(argv[i],"n") or !strcmp(argv[i],"num")
or !strcmp(argv[i],"numvars")) {
numvars = atoi(&(argv[i][j+1]));
if (numvars < 3) {
good_args = false;
cout << "Invalid number of variables: must be at least 3.\n";
}
}
else if (!strcmp(argv[i],"m") or !strcmp(argv[i],"mod")
or !strcmp(argv[i],"modulus"))
{
modulus = atoi(&(argv[i][j+1]));
if (modulus < 2) {
good_args = false;
cout << "Invalid modulus; must be at least 2.\n";
}
}
else if (!strcmp(argv[i],"r") or !strcmp(argv[i],"repr")
or !strcmp(argv[i], "representation"))
{
if (
method <= SPolyCreationFlags::MIN_SPCREATE_FLAG or
method >= SPolyCreationFlags::MAX_SPCREATE_FLAG
) {
good_args = false;
cout << "Invalid method; must be at least 1 and at most 3.\n";
}
}
else if (!strcmp(argv[i], "heur") or !strcmp(argv[i],"heuristic")) {
if (
heuristic <= DynamicHeuristic::MIN_HEURISTIC or
heuristic >= DynamicHeuristic::MAX_HEURISTIC
) {
good_args = false;\
cout << "Invalid method; must be at least 1 and at most 10.\n";
}
}
else if (!strcmp(argv[i],"strat") or !strcmp(argv[i],"strategy")) {
char * request = &(argv[i][j+1]);
if (!strcmp(request, "normal") or !strcmp(request, "norm"))
strategy = StrategyFlags::NORMAL_STRATEGY;
else if (!strcmp(request, "sugar") or !strcmp(request, "sug"))
strategy = StrategyFlags::SUGAR_STRATEGY;
else if (!strcmp(request, "wsugar") or !strcmp(request, "wsug")) {
strategy = StrategyFlags::WSUGAR_STRATEGY;
unsigned n = (homogeneous) ? numvars + 1 : numvars;
}
else {
good_args = false;
cout << "Strategy must be 'normal' or 'sugar' or 'wsugar'.\n";
}
}
else if (!strcmp(argv[i],"solver")) {
char * request = &(argv[i][j+1]);
if (!strcmp(request, "skel") or !strcmp(request, "skeleton"))
solver = SKELETON_SOLVER;
else if (!strcmp(request, "glpk") or !strcmp(request, "GLPK"))
solver = GLPK_SOLVER;
else if (!strcmp(request, "ppl") or !strcmp(request, "PPL"))
solver = PPL_SOLVER;
else {
good_args = false;
cout << "Strategy must be 'skeleton' or 'glpk'.\n";
}
}
else {
cout << "Unrecognized argument.\n"; good_args = false;
}
}
}
}
}
return good_args;
}
void give_help() {
cout << "Call with options n=<num> m=<mod> r=<repr> [hom] heur=<heur>\n";
cout << "You *must* specify <num> vars, an integer greater than 2.\n";
cout << "You can add optional <mod>ulus (please make it prime).\n";
cout << "The option <hom>ogenize will give you a homogenized ideal.\n";
cout << "You can also select the <repr>esentation of s-polynomials:\n";
cout << "\t1) linked lists,\n";
cout << "\t2) geobuckets, or\n";
cout << "\t3) double-buffered polynomials.\n";
cout << "The option <heur>istic allows you to select from the following:\n";
cout << "\t1) Hilbert heuristic w/ties broken by lex ordering,\n";
cout << "\t2) Hilbert heuristic w/ties broken by total degree,\n";
cout << "\t3) total degree w/ties broken by Hilbert heuristic,\n";
cout << "\t4) graded Hilbert heuristic w/ties broken by lex ordering,\n";
cout << "\t5) total degree w/ties broken by graded Hilbert heuristic,\n";
cout << "\t6) aiming for polynomials of smoothest degrees (nearly homogeneous),\n";
cout << "\t7) aiming for a polynomial with the largest maximal component,\n";
cout << "\t8) aiming to minimize the number of new critical pairs at min degree,\n";
cout << "\t9) aiming to minimize the number of new critical pairs at min graded degree,\n";
cout << "\t10) pseudosignature Hilbert heuristic.\n";
cout << "So 'test_cyclicn n=6 m=43 r=2' would compute the Groebner basis\n";
cout << "of the Cyclic-n ideal in 6 variables, modulo 43,";
cout << "using geobuckets.\n";
cout << "You can also specify the strategy ('normal', 'sugar', 'wsugar')\n";
cout << "('wsugar' requires a list of <num> integers, where <num> is as above.";
}