3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

port Grobner

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-10-16 15:34:58 -07:00
parent e987479e8a
commit 35c4b07bc4
2 changed files with 31 additions and 30 deletions

View file

@ -493,11 +493,14 @@ void grobner::simplify_eq(equation * eq) {
/**
\brief Return true if monomial m1 is (* c1 M) and m2 is (* c2 M M').
Store M' in rest.
Store M' in m_tmp_vars1.
\remark This method assumes the variables of m1 and m2 are sorted.
*/
bool grobner::is_subset(monomial const * m1, monomial const * m2, ptr_vector<expr> & rest) const {
bool grobner::divide_ignore_coeffs(monomial const * m2, monomial const * m1) {
SASSERT(m1 != m2);
ptr_vector<expr> & rest = m_tmp_vars1;
rest.reset();
unsigned i1 = 0;
unsigned i2 = 0;
unsigned sz1 = m1->m_vars.size();
@ -538,12 +541,11 @@ bool grobner::is_subset(monomial const * m1, monomial const * m2, ptr_vector<exp
}
/**
\brief Multiply the monomials of source starting at position start_idx by (coeff * vars), and store the resultant monomials
at result.
\brief Multiply the monomials of source starting at position start_idx by (coeff * vars), and store the resultant monomials in m_tmp_monomials
*/
void grobner::mul_append(unsigned start_idx, equation const * source, rational const & coeff, ptr_vector<expr> const & vars, ptr_vector<monomial> & result) {
void grobner::mul_append_skip_first(equation const * source, rational const & coeff, ptr_vector<expr> const & vars) {
unsigned sz = source->get_num_monomials();
for (unsigned i = start_idx; i < sz; i++) {
for (unsigned i = 1; i < sz; i++) {
monomial const * m = source->get_monomial(i);
monomial * new_m = alloc(monomial);
new_m->m_coeff = m->m_coeff;
@ -553,7 +555,7 @@ void grobner::mul_append(unsigned start_idx, equation const * source, rational c
for (expr* e : new_m->m_vars)
m_manager.inc_ref(e);
std::stable_sort(new_m->m_vars.begin(), new_m->m_vars.end(), m_var_lt);
result.push_back(new_m);
m_tmp_monomials.push_back(new_m);
}
}
@ -581,39 +583,38 @@ grobner::equation * grobner::copy_equation(equation const * eq) {
return r;
}
// source 3f + k = 0, so f = -k/3
// target 2fg + e = 0
// target is replaced by 2(-k/3)g + e = -2/3kg + e
unsigned grobner::simplify_loop_on_target_monomials(equation const * source, equation * target, bool & result) {
unsigned i = 0;
unsigned n_sz = 0;
unsigned new_target_sz = 0;
unsigned sz = target->m_monomials.size();
monomial const * LT = source->get_monomial(0);
ptr_vector<monomial> & new_monomials = m_tmp_monomials;
new_monomials.reset();
ptr_vector<expr> & rest = m_tmp_vars1;
m_tmp_monomials.reset();
for (; i < sz; i++) {
monomial * curr = target->m_monomials[i];
rest.reset();
if (is_subset(LT, curr, rest)) {
monomial * targ_i = target->m_monomials[i];
if (divide_ignore_coeffs(targ_i, LT)) {
if (i == 0)
m_changed_leading_term = true;
if (!result) {
// first time that source is being applied.
if (!result) { // first time that source is being applied.
target->m_dep = m_dep_manager.mk_join(target->m_dep, source->m_dep);
result = true;
}
result = true;
rational coeff = curr->m_coeff;
coeff /= LT->m_coeff;
coeff.neg();
if (!rest.empty())
rational coeff = - targ_i->m_coeff / (LT->m_coeff);
if (!m_tmp_vars1.empty())
target->m_lc = false;
mul_append(1, source, coeff, rest, new_monomials);
del_monomial(curr);
mul_append_skip_first(source, coeff, m_tmp_vars1);
del_monomial(targ_i);
}
else {
target->m_monomials[n_sz++] = curr;
if (i != new_target_sz) {
target->m_monomials[new_target_sz] = targ_i;
}
new_target_sz++;
}
}
return n_sz;
return new_target_sz;
}
/**
@ -848,10 +849,10 @@ void grobner::superpose(equation * eq1, equation * eq2) {
tout << "rest2: "; display_vars(tout, rest2.size(), rest2.c_ptr()); tout << "\n";);
ptr_vector<monomial> & new_monomials = m_tmp_monomials;
new_monomials.reset();
mul_append(1, eq1, eq2->m_monomials[0]->m_coeff, rest2, new_monomials);
mul_append_skip_first(eq1, eq2->m_monomials[0]->m_coeff, rest2);
rational c = eq1->m_monomials[0]->m_coeff;
c.neg();
mul_append(1, eq2, c, rest1, new_monomials);
mul_append_skip_first(eq2, c, rest1);
simplify_ptr_monomials(new_monomials);
TRACE("grobner", tout << "resulting monomials: "; display_monomials(tout, new_monomials.size(), new_monomials.c_ptr()); tout << "\n";);
if (new_monomials.empty())

View file

@ -157,9 +157,9 @@ protected:
void simplify_eq(equation * eq);
bool is_subset(monomial const * m1, monomial const * m2, ptr_vector<expr> & rest) const;
bool divide_ignore_coeffs(monomial const * m1, monomial const * m2);
void mul_append(unsigned start_idx, equation const * source, rational const & coeff, ptr_vector<expr> const & vars, ptr_vector<monomial> & result);
void mul_append_skip_first(equation const * source, rational const & coeff, ptr_vector<expr> const & vars);
monomial * copy_monomial(monomial const * m);