22 K =
P->getCoefficientRing();
31 for (i = 0; i <= LengthLimit; i++) resn.push_back(
new res_level);
38 for (i = 1; i < mat->
n_rows(); i++)
45 for (i = 0; i < mat->
n_cols(); i++)
56 for (i = 0; i < mat->
n_rows(); i++)
61 p->minimal_me =
p->me;
67 p->base_monom =
M->make_one();
73 base_components.push_back(
p);
89 for (i = 0; i < mat->
n_cols(); i++)
90 if ((*mat)[i] !=
nullptr)
105 for (i = 0; i < base_components.size(); i++)
127 for (i = 0; i < search_mi.size(); i++)
delete search_mi[i];
139 if (
p ==
nullptr)
return;
142 R->remove(
p->stripped_syz);
143 M->remove(
p->base_monom);
149 if (
p ==
nullptr)
return;
150 while (
p->first !=
nullptr)
153 p->first = tmp->
next;
161 if (lev ==
nullptr)
return;
163 for (i = 0; i < lev->bin.size(); i++)
180 if (level >= resn.size())
183 for (i = resn.size(); i <= level; i++) resn.push_back(
new res_level);
189 if (deg >= lev->bin.size())
192 for (i = lev->bin.size(); i <= deg; i++)
197 return lev->bin[deg];
203 if (level < 0 || level >= resn.size())
return nullptr;
206 if (d < 0 || d >= lev->bin.size())
return nullptr;
215 result->base_monom =
nullptr;
219 result->base_comp =
nullptr;
222 result->next_mi =
nullptr;
225 result->pivot_term =
nullptr;
226 result->stripped_syz =
nullptr;
234 result->base_monom =
M->make_one();
238 result->syz_type = syztype;
250 p->base_monom =
M->make_new(
p->syz->monom);
251 p->base_comp =
p->syz->comp;
252 p->first =
p->base_comp;
263 p->syz_type = syztype;
265 p->base_monom =
M->make_new(f->
monom);
275 int result =
M->primary_degree(
p->base_monom);
283 M->multi_degree(
p->base_monom, deg);
284 M->degree_monoid()->mult(
299 resn[level]->npairs++;
300 resn[level]->nleft++;
309 M->to_varpower(
p->syz->monom, vp);
310 search_mi[
p->syz->comp->me]->insert_minimal(
new Bag(
p, vp));
334 for (i = 0; i <
M->n_vars(); i++)
336 if (EXP1[i] < EXP2[i])
return -1;
337 if (EXP1[i] > EXP2[i])
return 1;
347 for (i = 0; i <
M->n_vars(); i++)
349 if (EXP1[i] < EXP2[i])
return 1;
350 if (EXP1[i] > EXP2[i])
return -1;
360 for (i =
M->n_vars() - 1; i >= 0; i--)
362 if (EXP1[i] < EXP2[i])
return -1;
363 if (EXP1[i] > EXP2[i])
return 1;
373 for (i =
M->n_vars() - 1; i >= 0; i--)
375 if (EXP1[i] < EXP2[i])
return 1;
376 if (EXP1[i] > EXP2[i])
return -1;
385 if (df > dg)
return -1;
386 if (df < dg)
return 1;
388 if (cmp != 0)
return cmp;
390 if (cmp < 0)
return 1;
391 if (cmp > 0)
return -1;
395 if (cmp != 0)
return cmp;
397 if (cmp < 0)
return 1;
398 if (cmp > 0)
return -1;
406 if (g ==
nullptr)
return f;
407 if (f ==
nullptr)
return g;
441 if (
p ==
nullptr ||
p->next ==
nullptr)
return;
451 if (
p ==
nullptr)
break;
466 M->to_expvector(
p->base_monom, REDUCE_exp);
472 if (mypairs ==
nullptr)
return;
474 if (
p ==
nullptr ||
p->next ==
nullptr)
return;
484 if (mypairs ==
nullptr)
return;
503 if (cmp < 0)
return 1;
504 if (cmp > 0)
return -1;
506 if (cmp < 0)
return 1;
507 if (cmp > 0)
return -1;
513 if (g ==
nullptr)
return f;
514 if (f ==
nullptr)
return g;
547 if (
p ==
nullptr ||
p->next_compare ==
nullptr)
return;
557 if (
p ==
nullptr)
break;
574 if (level == 0)
return;
585 if (mypairs ==
nullptr)
return;
589 for (
p = mypairs->
first;
p !=
nullptr;
p =
p->next)
591 p->next_compare =
p->next;
595 resn[level]->compare_num_list =
599 for (
p = resn[level]->compare_num_list;
p !=
nullptr;
p =
p->next_compare)
600 p->compare_num = next++;
623 o <<
"Computing pairs with first = " <<
p->me <<
newline;
626 M->divide(
p->base_monom,
p->first->base_monom, PAIRS_mon);
627 M->to_varpower(PAIRS_mon, vp);
632 if (
P->is_skew_commutative())
637 int nskew =
P->n_skew_commutative_vars();
638 for (
int v = 0; v < nskew; v++)
640 int w =
P->skew_variable(v);
645 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
654 if (
P->is_quotient_ring())
657 for (
Bag& a : *Rideal)
666 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
674 for (
Bag& a : *mi_orig)
676 Bag *b =
new Bag(a.basis_ptr());
689 for (
auto& b : rejects)
715 if (!
P->is_quotient_ring())
return 0;
717 if (!
P->get_quotient_monomials()->search_expvector(exp, b))
return 0;
727 p->syz =
R->new_term(
K->from_long(1),
p->base_monom,
p->first);
729 M->divide(
p->base_monom,
p->first->base_monom, si);
732 if (
p->second !=
nullptr)
734 p->syz->next =
R->new_term(
K->from_long(-1),
p->base_monom,
p->second);
735 M->divide(
p->base_monom,
p->second->base_monom, si);
736 R->subtract_multiple_to(
result, one, si,
p->second->syz);
762 M->to_expvector(REDUCE_mon, REDUCE_exp);
768 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
774 lastterm = lastterm->
next;
778 R->subtract_multiple_to(f, f->
coeff, REDUCE_mon, q->
syz);
786 lastterm = lastterm->
next;
812 M->to_expvector(REDUCE_mon, REDUCE_exp);
818 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
820 else if (search_mi[f->
comp->
me]->search_expvector(REDUCE_exp, b))
824 lastterm = lastterm->
next;
828 R->subtract_multiple_to(f, f->
coeff, REDUCE_mon, q->
syz);
836 lastterm = lastterm->
next;
856 M->to_expvector(REDUCE_mon, REDUCE_exp);
862 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
864 else if (search_mi[f->
comp->
me]->search_expvector(REDUCE_exp, b))
868 R->subtract_multiple_to(f, f->
coeff, REDUCE_mon, q->
syz);
881 if (
stop_.length_limit !=
nullptr &&
stop_.length_limit->len > 0)
885 ERROR(
"resolution: cannot increase maximum level");
900 enum ComputationStatusCode result = CALL; \
901 if (result != COMP_COMPUTING) \
903 set_status(result); \
969 o <<
"gens(" << deg <<
")" <<
newline;
975 if (mypairs !=
nullptr)
977 while ((
p = mypairs->
next_gen) !=
nullptr)
1006 o <<
"pairs(" << level <<
", " << deg <<
")" <<
newline;
1012 if (mypairs !=
nullptr)
1030 o <<
"reductions(" << level <<
", " << deg <<
")" <<
newline;
1035 if (mypairs !=
nullptr)
1042 resn[level]->nleft--;
1056 if (
p->syz !=
nullptr)
1058 R->make_monic(
p->syz);
1059 M->copy(
p->syz->monom,
p->base_monom);
1060 p->first =
p->syz->comp;
1061 p->second =
nullptr;
1063 p->base_comp =
p->syz->comp->base_comp;
1065 p->minimal_me = resn[1]->nminimal++;
1084 q =
reduce(f,
p->syz,
p->pivot_term);
1090 p->minimal_me = resn[
n_level]->nminimal++;
1138 if (
p ==
nullptr)
return 0;
1145 if (
p ==
nullptr)
return 0;
1148 for (
res_pair *q =
p->first; q !=
nullptr; q = q->next)
1157 if (
p ==
nullptr)
return 0;
1159 for (
res_pair *q =
p->first; q !=
nullptr; q = q->next)
1168 if (
p ==
nullptr)
return 0;
1170 for (
res_pair *q =
p->first; q !=
nullptr; q = q->next)
1188 for (
int d = lo; d <= hi; d++)
1189 for (
int lev = 0; lev <= len; lev++)
1208 "cannot use Minimize=>true unless "
1209 "res(...,FastNonminimal=>true) was used");
1215 bettis[lev + (len + 1) * (d - lo)] = val;
1241 o <<
p->compare_num <<
' ';
1243 switch (
p->syz_type)
1267 o <<
"[mi: " <<
p->mi->size() <<
"]";
1277 M->elem_text_out(o,
p->base_monom);
1282 R->elem_text_out(o,
p->syz);
1303 o <<
"--- The total number of pairs in each level/slanted degree -----"
1307 o <<
"--- The number of pairs left to compute ------------------------"
1311 o <<
"--- (Lower bounds of) the minimal betti numbers ----------" <<
newline;
1316 o <<
"--- Number of monomials ---------------------------------"
1324 for (
int lev = 0; lev < resn.size(); lev++)
1326 o <<
"---- level " << lev <<
" ----" <<
newline;
1327 for (
int i = 0; i < resn[lev]->bin.size(); i++)
1330 if (mypairs ==
nullptr)
continue;
1344 result =
P->make_Schreyer_FreeModule();
1345 if (i < 0 || i >= resn.size())
return result;
1346 monomial deg =
P->degree_monoid()->make_one();
1349 for (
int j = 0; j < lev->bin.size(); j++)
1355 result->append_schreyer(deg,
p->base_monom,
p->compare_num);
1356 p->minimal_me = n++;
1359 P->degree_monoid()->remove(deg);
1367 result =
P->make_FreeModule();
1369 monomial deg =
P->degree_monoid()->make_one();
1372 for (
int j = 0; j < lev->bin.size(); j++)
1380 p->minimal_me = nminimals++;
1383 P->degree_monoid()->remove(deg);
1395 if (
G ==
nullptr)
return result.to_matrix();
1397 for (
int j = 0; j < lev->bin.size(); j++)
1401 result.set_column(n++,
R->to_vector(
p->syz, F));
1403 return result.to_matrix();
1419 for (
int i =
x - 1; i >= 0; i--)
1423 while ((tm =
R->component_occurs_in(
p->pivot_term->comp, f)) !=
nullptr)
1429 K->divide(tm->
coeff,
p->pivot_term->coeff);
1431 M->divide(tm->
monom,
p->pivot_term->monom, MINIMAL_mon);
1432 if (
p->stripped_syz ==
nullptr)
p->stripped_syz =
R->strip(
p->syz);
1433 R->subtract_multiple_to(f, c, MINIMAL_mon,
p->stripped_syz);
1447 for (
int j = 0; j < lev->bin.size(); j++)
1448 for (
res_pair *
p = lev->bin[j]->first;
p !=
nullptr;
p =
p->next)
1452 for (
int x = 0;
x < elems.size();
x++)
1457 if (
p->stripped_syz ==
nullptr)
1459 p->stripped_syz =
R->strip(
p->syz);
1462 result.set_column(thisx++,
R->to_vector(
p->stripped_syz, F, 1));
1465 return result.to_matrix();
1477 for (
auto p = base_components.rbegin();
p != base_components.rend(); ++
p)
1482 reslevel.push_back(pp);
1493 reslevel.push_back(pp);
1509 o <<
"Computing pairs with first = " <<
p->me <<
newline;
1512 M->divide(
p->base_monom,
p->first->base_monom, PAIRS_mon);
1513 M->to_varpower(PAIRS_mon, vp);
1518 if (
P->is_skew_commutative())
1524 int nskew =
P->n_skew_commutative_vars();
1525 for (
int v = 0; v < nskew; v++)
1527 int w =
P->skew_variable(v);
1532 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
1541 if (
P->is_quotient_ring())
1544 for (
Bag& a : *Rideal)
1553 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
1562 for (
Bag& a : *mi_orig)
1564 Bag *b =
new Bag(a.basis_ptr());
1584 M->from_varpower(a.monom().data(), q->
base_monom);
1596 for (
int level = 0; level < reslevel.size(); level++)
1598 for (
res_pair *
p = reslevel[level];
p !=
nullptr;
p =
p->next)
1611 int maxlevel = reslevel.size() - 1;
1614 for (level = 0; level < reslevel.size(); level++)
1616 for (
res_pair *
p = reslevel[level];
p !=
nullptr;
p =
p->next)
1621 bettis[level + (maxlevel + 1) * d] += 1;
1629 int totallen = 3 + (hi - lo + 1) * (len + 1);
1632 betti->array[0] = lo;
1633 betti->array[1] = hi;
1634 betti->array[2] = len;
1637 for (
int d = 0; d <= maxdegree -
lodegree; d++)
1638 for (level = 0; level <= maxlevel; level++)
1639 betti->array[next++] = bettis[level + (maxlevel + 1) * d];
1644 for (level = 0; level <= maxlevel; level++)
1646 o <<
"---- level " << level <<
" ----" <<
newline;
1647 for (
res_pair *
p = reslevel[level];
p !=
nullptr;
p =
p->next)
1671 for (level = 1; level < reslevel.size(); level++)
1675 if (pp ==
nullptr)
break;
1679 reslevel[level] = pp;
1684 head.
next =
nullptr;
1687 reslevel.push_back(head.
next);
exponents::ConstExponents const_exponents
exponents::Exponents exponents_t
Dense exponent-vector template [e_0, ..., e_{nvars-1}] for monomial operations.
enum ComputationStatusCode status() const
enum ComputationStatusCode set_status(enum ComputationStatusCode)
static void quotient(ConstExponents a, ConstExponents b, Vector &result)
static bool is_equal(ConstExponents a, ConstExponents b)
static void to_expvector(int n, ConstExponents a, exponents::Exponents result)
static void var(Exponent v, Exponent e, Vector &result)
static Exponent weight(int nvars, ConstExponents a, const std::vector< Exponent > &wts)
int primary_degree(int i) const
const SchreyerOrder * get_schreyer_order() const
Engine-side free module R^n over a Ring.
const Ring * get_ring() const
const FreeModule * rows() const
const FreeModule * cols() const
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
int search_expvector(const_exponents m, Bag *&b) const
void insert_minimal(Bag *b)
void debug_out(int disp=1) const
Engine-side monomial ideal: a decision tree of Nmi_nodes storing the (typically minimal) generators b...
Internal tree node of the MonomialIdeal decision tree.
Abstract base for the engine's polynomial-ring hierarchy.
static void betti_display(buffer &o, M2_arrayint a)
static void betti_init(int lo, int hi, int len, int *&bettis)
static M2_arrayint betti_make(int lo, int hi, int len, int *bettis)
virtual const PolynomialRing * cast_to_PolynomialRing() const
const_monomial base_monom(int i) const
Per-component tie-breaker data for a Schreyer monomial order on a FreeModule.
gc_vector< int > & monom()
M2_arrayint betti_remaining() const
Matrix * make_minimal(int i) const
void remove_res_level(res_level *lev)
int n_left(int lev, int d) const
int degree(const res_pair *q) const
void sort_compares(res_pair *&p) const
res_degree * make_degree_set(int level, int deg)
void sort_pairs(int level, int deg)
int n_monoms(int lev, int d) const
resterm * s_pair(res_pair *fsyz) const
enum ComputationStatusCode reductions(int level, int deg)
int compare_compares(res_pair *f, res_pair *g) const
void skeleton_stats(const VECTOR(res_pair *)&reslevel)
enum ComputationStatusCode pairs(int level, int deg)
void reduce_gen(resterm *&f) const
void skeleton_init(VECTOR(res_pair *)&reslevel)
enum ComputationStatusCode gens(int deg)
M2_arrayint get_betti(int type) const
res_pair * reduce_level_one(resterm *&f, resterm *&fsyz, resterm *&pivot)
const Matrix * generator_matrix
void sort_gens(res_degree *pairs)
void multi_degree(const res_pair *q, monomial result) const
int compare_res_pairs(res_pair *f, res_pair *g) const
int complete_thru_degree() const
int n_pairs(int lev, int d) const
void skeleton_pairs(res_pair *&result, res_pair *p)
res_comp(const Matrix *m, int LengthLimit, int strategy)
int find_ring_divisor(const_exponents exp, ring_elem &result) const
int sort_value(res_pair *p, const std::vector< int > sort_order) const
void remove_res_degree(res_degree *p)
void skeleton(int strategy)
const FreeModule * free_of(int i) const
void remove_res_pair(res_pair *p)
res_pair * new_res_pair()
void sort_res_pairs(res_pair *&p) const
void new_pairs(res_pair *p)
Matrix * make(int i) const
int n_minimal(int lev, int d) const
M2_arrayint betti_minimal() const
res_pair * merge_res_pairs(res_pair *f, res_pair *g) const
void text_out(const res_pair *p) const
res_pair * reduce(resterm *&f, resterm *&fsyz, resterm *&pivot)
void set_compare_nums(int level, int deg)
void initialize(const Matrix *mat, int LengthLimit, int strategy)
res_degree * get_degree_set(int level, int d) const
M2_arrayint betti_nmonoms() const
const FreeModule * minimal_free_of(int i) const
void reduce_minimal(int x, resterm *&f, VECTOR(res_pair *)&elems) const
void handle_pair(res_pair *p)
int skeleton_maxdegree(const VECTOR(res_pair *)&reslevel)
void insert_res_pair(int level, res_pair *p)
void handle_gen(res_pair *p)
M2_arrayint betti_skeleton() const
res_pair * merge_compares(res_pair *f, res_pair *g) const
bool stop_conditions_ok()
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
VALGRIND_MAKE_MEM_DEFINED & result(result)
M2_arrayint M2_makearrayint(int n)
MatrixConstructor — the mutable builder that produces an immutable Matrix.
#define MONOMIAL_BYTE_SIZE(mon_size)
#define ALLOCATE_EXPONENTS(byte_len)
#define EXPONENT_BYTE_SIZE(nvars)
#define ALLOCATE_MONOMIAL(byte_len)
#define newarray_atomic_clear(T, len)
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
#define newarray_atomic(T, len)
Singly linked-list node carrying one term of a polynomial-ring element.
void emit_wrapped(const char *s)
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.