17 if (
stop_.length_limit !=
nullptr &&
stop_.length_limit->len > 0)
27 int len = resn.size() - 1;
28 for (
int lev = 0; lev <= len; lev++)
30 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
47 if (resn[level]->next_pair ==
nullptr)
51 for (
p = resn[level]->pairs;
p !=
nullptr;
p =
p->next)
56 resn[level]->next_pair = resn[level]->pairs;
62 p = resn[level]->next_pair;
63 if (
p ==
nullptr)
break;
64 resn[level]->next_pair =
p->next;
77 for (
int i = resn.size(); i <= newmax + 2; i++)
81 p->next_pair =
nullptr;
98 if (level < resn.size() && (resn[level]->next_pair ==
nullptr ||
99 degree < resn[level]->next_pair->degree))
118 p = resn[level]->next_pair;
120 while (
p !=
nullptr &&
p->degree == degree)
129 o <<
"[" << degree <<
" " << level <<
" " << nelems <<
"]";
133 for (
p = resn[level]->next_pair;
p !=
nullptr;
p =
p->next)
135 if (
p->degree != degree)
break;
136 resn[level]->next_pair =
p->next;
159 int nelems = resn[level]->nleft;
163 o <<
"[lev " << nelems <<
']';
167 for (
p = resn[level]->next_pair;
p !=
nullptr;
p =
p->next)
169 resn[level]->next_pair =
p->next;
185 for (
p = resn[level]->pairs;
p !=
nullptr;
p =
p->next)
190 for (f =
p->syz; f !=
nullptr; f = f->
next)
202 p->pivot_term = head.
next;
207 o <<
"[kept " << nmonoms <<
" killed " << nkilled <<
"]";
223 p = resn[level]->next_pair;
225 while (
p !=
nullptr &&
p->degree == degree)
233 o <<
'[' << nelems <<
']';
237 for (
p = resn[level]->next_pair;
p !=
nullptr;
p =
p->next)
239 if (
p->degree != degree)
break;
240 resn[level]->next_pair =
p->next;
258 enum ComputationStatusCode result = CALL; \
259 if (result != COMP_COMPUTING) \
261 set_status(result); \
274 if (
stop_.length_limit->len > 0)
289 o <<
"--- The total number of pairs in each level/slanted degree -----"
314 for (n = 0,
p = resn[level]->pairs;
p !=
nullptr;
p =
p->next, n++)
317 for (n = 0,
p = resn[level]->pairs;
p !=
nullptr;
p =
p->next, n++)
321 resn[level]->next_pair = resn[level]->pairs;
326 resn[level]->next_pair = resn[level]->pairs;
347 for (
int deg = 0; deg <=
hidegree; deg++)
349 if (
stop_.stop_after_degree &&
370 for (
int deg = 0; deg <=
hidegree; deg++)
372 if (
stop_.stop_after_degree &&
423 int SlantedDegreeLimit,
431 K =
P->getCoefficientRing();
450 for (
auto i = 1; i < mat->
n_rows(); i++)
458 for (
auto i = 0; i < mat->
n_cols(); i++)
478 for (
auto i = 0; i < mat->
n_rows(); i++)
481 base_components.push_back(
p);
483 for (
auto p = base_components.rbegin();
p != base_components.rend(); ++
p)
516 o <<
"computing resolution level by level" <<
newline;
520 o <<
"computing resolution degree by slanted degree" <<
newline;
522 o <<
"skeleton order = ";
524 o <<
"reduction sort = ";
551 if (sortval &
FLAGS_DEGREE) o <<
" (ascending degree first)";
564 int SlantedDegreeLimit,
567 initialize(m, LengthLimit, UseDegreeLimit, SlantedDegreeLimit, SortStrategy);
572 if (
p ==
nullptr)
return;
580 if (lev ==
nullptr)
return;
581 while (lev->
pairs !=
nullptr)
612 p->level = (
unsigned char)(first->
level + 1);
613 p->degree = (
short unsigned int)(
M->primary_degree(basemon) + first->
degree -
614 M->primary_degree(first->
syz->
monom) - 1);
616 p->syz =
R->new_term(
K->from_long(1), basemon, first);
622 p->pivot_term =
nullptr;
639 p->syz =
R->new_term(
K->from_long(1), m,
p);
642 p->pivot_term =
nullptr;
659 p->pivot_term =
nullptr;
674 resn[q->
level]->nthrown++;
686 resn[q->
level]->pairs = q;
688 resn[q->
level]->npairs++;
692 resn[q->
level]->nleft++;
697 resn[q->
level]->nminimal++;
704 M->multi_degree(
p->syz->monom, deg);
726 if (df > dg)
return -1;
727 if (df < dg)
return 1;
734 if (cmp < 0)
return 1;
738 if (cmp < 0)
return 1;
739 if (cmp > 0)
return -1;
748 for (
int i =
M->n_vars() - 1; i >= 0; i--)
756 for (
int i = 0; i <
M->n_vars(); i++)
773 while (f->
level >= 1)
779 for (
int i =
M->n_vars() - 1; i >= 0; i--)
787 for (
int i = 0; i <
M->n_vars(); i++)
807 for (
int i =
M->n_vars() - 1; i >= 0; i--)
815 for (
int i = 0; i <
M->n_vars(); i++)
821 while (f->
level >= 1)
832 for (
int i =
M->n_vars() - 1; i >= 0; i--)
834 if (EXP1[i] - EXP3[i] < EXP2[i] - EXP4[i])
836 if (EXP1[i] - EXP3[i] > EXP2[i] - EXP4[i])
842 for (
int i = 0; i <
M->n_vars(); i++)
844 if (EXP1[i] - EXP3[i] < EXP2[i] - EXP4[i])
846 if (EXP1[i] - EXP3[i] > EXP2[i] - EXP4[i])
859 if (g ==
nullptr)
return f;
860 if (f ==
nullptr)
return g;
894 if (
p ==
nullptr ||
p->next ==
nullptr)
return;
904 if (
p ==
nullptr)
break;
943 M->to_expvector(
p->syz->monom, REDUCE_exp);
964 o <<
"Computing pairs with first = " <<
p->pair_num <<
newline;
967 M->divide(
p->syz->monom,
p->syz->comp->syz->monom, PAIRS_mon);
968 M->to_varpower(PAIRS_mon, vp);
973 if (
P->is_skew_commutative())
978 int nskew =
P->n_skew_commutative_vars();
979 for (
int v = 0; v < nskew; v++)
981 int w =
P->skew_variable(v);
986 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
995 if (
P->is_quotient_ring())
998 for (
Bag& a : *Rideal)
1007 Bag *b =
new Bag(
static_cast<void *
>(
nullptr), thisvp);
1016 for (
Bag& a : *mi_orig)
1018 Bag *b =
new Bag(a.basis_ptr());
1037 M->from_varpower(a.monom().data(), m);
1038 M->mult(m,
p->syz->monom, m);
1053 if (!
P->is_quotient_ring())
return 0;
1055 if (!
P->get_quotient_monomials()->search_expvector(exp, b))
return 0;
1068 if (bb.size() == 0)
return 0;
1075 o <<
":" << mi->
size() <<
"." << bb.size() <<
":";
1080 if (mi->
size() == 1)
1089 unsigned int lowest =
result->pair_num;
1090 for (
int i = 1; i < bb.size(); i++)
1092 p =
reinterpret_cast<res2_pair *
>(bb[i]->basis_ptr());
1093 if (
p->pair_num < lowest)
1095 lowest =
p->pair_num;
1114 while (f !=
nullptr)
1148 while (f !=
nullptr)
1151 M->to_expvector(REDUCE_mon, REDUCE_exp);
1157 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
1166 lastterm = lastterm->
next;
1179 R->subtract_multiple_to(f, f->
coeff, REDUCE_mon, q->
syz);
1187 tmp->
next =
nullptr;
1224 while (f !=
nullptr)
1227 M->to_expvector(REDUCE_mon, REDUCE_exp);
1233 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
1245 lastterm = lastterm->
next;
1262 au->
p = pivot->
comp;
1263 au->
pivot = lastterm;
1281 lastterm = lastterm->
next;
1283 R->subtract_multiple_to(f, f->
coeff, REDUCE_mon, q->
syz);
1295 red->
next =
nullptr;
1340 M->to_expvector(REDUCE_mon, REDUCE_exp);
1348 R->ring_mult_by_term(r->
next, c, REDUCE_mon, lead->
comp);
1364 lastterm = lastterm->
next;
1377 lastterm->
next =
R->new_term(c, lead->
monom, q);
1378 lastterm = lastterm->
next;
1391 red->
next =
nullptr;
1417 while (lastterm->
next !=
nullptr) lastterm = lastterm->
next;
1428 while (f !=
nullptr)
1432 lead->
next =
nullptr;
1434 M->to_expvector(REDUCE_mon, REDUCE_exp);
1442 R->ring_mult_by_term(r->
next, c, REDUCE_mon, lead->
comp);
1450 if (q->
degree ==
p->degree + 1)
1455 lastterm = lastterm->
next;
1473 lastterm->
next =
R->new_term(c, lead->
monom, q);
1474 lastterm = lastterm->
next;
1486 red->
next =
nullptr;
1515 while (f !=
nullptr)
1518 M->to_expvector(REDUCE_mon, REDUCE_exp);
1524 R->ring_subtract_multiple_to(f, f->
coeff, REDUCE_mon, f->
comp, rg);
1531 lastterm = lastterm->
next;
1541 tmp->
next =
nullptr;
1575 M->to_expvector(REDUCE_mon, REDUCE_exp);
1583 R->ring_mult_by_term(r->
next, c, REDUCE_mon, lead->
comp);
1595 lastterm->
next =
R->new_term(c, lead->
monom, q);
1596 lastterm = lastterm->
next;
1625 while (au !=
nullptr)
1629 o <<
"auto reduction: " <<
newline <<
" ";
1630 R->elem_text_out(
p->syz);
1632 R->elem_text_out(a->
p->
syz);
1633 o <<
newline <<
" by coeff = ";
1636 res2term *h =
R->mult_by_coefficient(
p->syz, c);
1638 R->add_to(a->
p->
syz, h);
1640 R->elem_text_out(a->
p->
syz);
1650 resn[
p->level]->nleft--;
1674 q =
reduce(f,
p->syz,
p->pivot_term,
p);
1730 resn[
p->level]->nleft--;
1760 o <<
"handle pair: should not be here!";
1762 R->elem_text_out(o,
p->syz);
1770 resn[
p->level]->nleft--;
1797 resn[
p->level]->nminimal++;
1820 int len = resn.size() - 1;
1823 for (
int lev = 0; lev <= len; lev++)
1825 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
1838 int len = resn.size() - 1;
1841 for (
int lev = 0; lev <= len; lev++)
1843 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
1847 bettis[lev + (len + 1) * d]++;
1860 int len = resn.size() - 1;
1863 for (
int lev = 0; lev <= len; lev++)
1865 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
1869 bettis[lev + (len + 1) * d]++;
1881 int len = resn.size() - 1;
1884 for (
int lev = 0; lev <= len; lev++)
1886 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
1889 bettis[lev + (len + 1) * d] +=
R->n_terms(
p->syz);
1911 "cannot use Minimize=>true unless res(...,FastNonminimal=>true) "
1915 ERROR(
"received unknown betti type");
1930 if (
p->syz->next ==
nullptr)
1933 b =
p->syz->next->comp;
1936 o <<
p->level <<
' ' <<
p->degree <<
' ';
1946 o <<
p->compare_num <<
' ';
1948 switch (
p->syz_type)
1958 o <<
"(pivot " <<
p->pivot_term->comp->me <<
")";
1970 o <<
"[mi: " <<
p->mi->size() <<
"]";
1980 M->elem_text_out(o,
p->syz->monom);
1981 o <<
" [" <<
R->n_terms(
p->syz) <<
"] ";
1986 R->elem_text_out(o,
p->syz);
2000 o <<
"--- The total number of pairs in each level/slanted degree -----"
2009 o <<
"--- (Lower bounds of) the minimal betti numbers ----------" <<
newline;
2017 o <<
"--- Number of monomials ---------------------------------"
2025 for (
int lev = 0; lev < resn.size(); lev++)
2027 if (resn[lev]->pairs ==
nullptr)
continue;
2028 o <<
"---- level " << lev <<
" ----" <<
newline;
2029 for (
res2_pair *
p = resn[lev]->pairs;
p !=
nullptr;
p =
p->next)
2037 result =
P->make_Schreyer_FreeModule();
2038 if (i < 0 || i >= resn.size())
return result;
2043 for (
res2_pair *
p = resn[i]->pairs;
p !=
nullptr;
p =
p->next)
2046 result->append_schreyer(deg,
p->syz->monom,
p->compare_num);
2055 result =
P->make_Schreyer_FreeModule();
2056 if (i < 0 || i >= resn.size() - 1)
return result;
2062 for (
res2_pair *
p = resn[i]->pairs;
p !=
nullptr;
p =
p->next)
2066 result->append_schreyer(deg,
p->syz->monom,
p->compare_num);
2081 if (
G->rank() == 0)
return result.to_matrix();
2082 for (
res2_pair *
p = resn[level]->pairs;
p !=
nullptr;
p =
p->next)
2083 result.set_column(n++,
R->to_vector(
p->syz, F));
2084 return result.to_matrix();
2100 for (
int i =
x - 1; i >= 0; i--)
2104 while ((tm =
R->component_occurs_in(
p->pivot_term->comp, f)) !=
nullptr)
2110 K->divide(tm->
coeff,
p->pivot_term->coeff);
2112 M->divide(tm->
monom,
p->pivot_term->monom, MINIMAL_mon);
2113 if (stripped[
p->me] ==
nullptr) stripped[
p->me] =
R->strip(
p->syz);
2114 R->subtract_multiple_to(f, c, MINIMAL_mon, stripped[
p->me]);
2124 if (i <= 0 || i >= resn.size() - 1)
return result.to_matrix();
2131 for (
res2_pair *
p = resn[i]->pairs;
p !=
nullptr;
p =
p->next)
2135 stripped.push_back(
static_cast<res2term *
>(
nullptr));
2139 for (
int x = 0;
x < elems.size();
x++)
2144 if (stripped[
p->me] ==
nullptr)
2146 stripped[
p->me] =
R->strip(
p->syz);
2149 result.set_column(thisx++,
R->to_vector(stripped[
p->me], F, 1));
2153 return result.to_matrix();
exponents::Exponents exponents_t
Dense exponent-vector template [e_0, ..., e_{nvars-1}] for monomial operations.
BettiDisplay — engine-side container and renderer for the Betti table of a free resolution.
Append-only GC-backed byte buffer used throughout the engine for text output.
M2_arrayint getBetti() const
int & entry(int deg, int lev)
Engine-side Betti table: a (degree, homological level) rectangle of integers.
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
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.
void mult(const_monomial m, const_monomial n, monomial result) const
void insert_minimal(Bag *b)
void debug_out(int disp=1) const
void find_all_divisors(const_exponents exp, VECTOR(Bag *)&b) 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 Monoid * degree_monoid() const
VECTYPE remove_lead_term()
gc_vector< int > & monom()
res2_pair * reduce(res2term *&f, res2term *&fsyz, res2term *&pivot, res2_pair *p)
int compare_res2_pairs(res2_pair *f, res2_pair *g) const
unsigned char do_by_degree
void remove_res2_pair(res2_pair *p)
void remove_res2_level(res2_level *lev)
res2_pair * new_res2_pair(int i)
FreeModule * free_of(int i) const
const Ring * get_ring() const
int complete_thru_degree() const
void sort_res2_pairs(res2_pair *&p) const
res2term * s_pair(res2term *fsyz) const
enum ComputationStatusCode do_pairs_by_degree(int level, int degree)
void handle_pair_by_level(res2_pair *p)
void new_pairs(res2_pair *p)
int compare_use_descending
res2_pair * reduce_heap_by_level(res2term *&f, res2term *&fsyz)
enum ComputationStatusCode do_pairs_by_level(int level)
res2_pair * reduce4(res2term *&f, res2term *&fsyz, res2term *&pivot, res2_pair *p)
Matrix * make(int i) const
void text_out(const res2_pair *p) const
const Matrix * generator_matrix
res2_pair * new_base_res2_pair(int i)
void increase_level(int newmax)
void insert_pair(res2_pair *p)
void handle_pair(res2_pair *p)
FreeModule * minimal_free_of(int i) const
M2_arrayint get_betti(int type) const
void sort_reduction(res2_pair *&p)
int find_ring_divisor(const int *exp, ring_elem &result) const
void initialize(const Matrix *mat, int LengthLimit, bool UseDegreeLimit, int SlantedDegreeLimit, int SortStrategy)
void display_order(buffer &o, int sortval) const
void sort_skeleton(res2_pair *&p)
res2_pair * reduce3(res2term *&f, res2term *&fsyz, res2term *&pivot, res2_pair *p)
int find_divisor(const MonomialIdeal *mi, const int *exp, res2_pair *&result)
M2_arrayint betti_skeleton() const
int sort_value(res2_pair *p, const std::vector< int > sort_order) const
void do_auto_reductions(res2_pair *p, auto_reduce_node *au)
unsigned char use_respolyHeaps
res2_pair * reduce_by_level(res2term *&f, res2term *&fsyz)
M2_arrayint betti_remaining() const
res2_pair * reduce2(res2term *&f, res2term *&fsyz, res2term *&pivot, res2_pair *p)
void reduce_minimal(int x, res2term *&f, VECTOR(res2_pair *)&elems, VECTOR(res2term *)&stripped) const
res2_comp(const Matrix *m, int LengthLimit, bool UseDegreeLimit, int SlantedDegreeLimit, int SortStrategy)
enum ComputationStatusCode do_pairs(int level, int degree)
void handle_pair_by_degree(res2_pair *p)
enum ComputationStatusCode skeleton(int level)
unsigned char do_by_level
void multi_degree(const res2_pair *q, int *result) const
enum ComputationStatusCode do_all_pairs(int level, int degree)
M2_arrayint betti_minimal() const
bool stop_conditions_ok()
M2_arrayint betti_nmonoms() const
res2_pair * merge_res2_pairs(res2_pair *f, res2_pair *g) const
Matrix * make_minimal(int i) const
void sort_monorder(res2_pair *&p)
geobucket<FREEMODULETYPE, VECTYPE> — size-quadrupling bucket accumulator for fast polynomial sums.
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
VALGRIND_MAKE_MEM_DEFINED & result(result)
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)
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)
static gmp_randstate_t state
geobucket< const res2_poly, res2term * > respolyHeap
const int COMPARE_MONORDER
const int COMPARE_LEX_EXTENDED
const int COMPUTE_MONOMIAL_RES
const int COMPUTE_SKELETON
const int COMPARE_LEX_EXTENDED2
const int FLAGS_DEGREELEVEL
const int FLAGS_LEVEL_STRIP
res2_comp — original (1996) free-resolution engine using explicit pair processing.
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.