Skip to content

Commit

Permalink
enable propagate-linear-equations and extend to monomials
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolajBjorner committed Oct 22, 2023
1 parent 53ce18e commit c9d298e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 31 deletions.
68 changes: 37 additions & 31 deletions src/math/lp/nla_grobner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace nla {
if (propagate_factorization())
return;

if (false && propagate_linear_equations())
if (propagate_linear_equations())
return;
}
catch (...) {
Expand All @@ -81,6 +81,8 @@ namespace nla {

// DEBUG_CODE(for (auto e : m_solver.equations()) check_missing_propagation(*e););

// for (auto e : m_solver.equations()) check_missing_propagation(*e);

++m_delay_base;
if (m_quota > 0)
--m_quota;
Expand Down Expand Up @@ -383,6 +385,9 @@ namespace nla {

bool grobner::propagate_linear_equations() {
unsigned changed = 0;
m_mon2var.clear();
for (auto const& m : c().emons())
m_mon2var[m.vars()] = m.var();
for (auto eq : m_solver.equations())
if (propagate_linear_equations(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
return true;
Expand All @@ -392,40 +397,40 @@ namespace nla {
bool grobner::propagate_linear_equations(dd::solver::equation const& e) {
if (equation_is_true(e))
return false;
if (!e.poly().is_linear())
rational value(0);
for (auto const& [coeff, vars] : e.poly()) {
if (vars.empty())
value += coeff;
else if (vars.size() == 1)
value += coeff*val(vars[0]);
else if (m_mon2var.find(vars) == m_mon2var.end())
return false;
else
value += coeff*val(m_mon2var.find(vars)->second);
}
if (value == 0)
return false;

rational lc(1);
for (auto const& [coeff, vars] : e.poly())
for (auto const& [coeff, vars] : e.poly())
lc = lcm(denominator(coeff), lc);
auto q = e.poly();


#if 1
vector<std::pair<lp::mpq, unsigned>> coeffs;
while (!q.is_val()) {
coeffs.push_back({lc*q.hi().val(), q.var()});
q = q.lo();
}
vector<std::pair<lp::mpq, unsigned>> coeffs;
rational offset(0);

for (auto const& [coeff, vars] : e.poly()) {
if (vars.size() == 0)
offset -= lc*coeff;
else if (vars.size() == 1)
coeffs.push_back({lc*coeff, vars[0]});
else
coeffs.push_back({lc*coeff, m_mon2var.find(vars)->second});
}

lp::lpvar term_index = c().lra.add_term(coeffs, UINT_MAX);
term_index = c().lra.map_term_index_to_column_index(term_index);
c().lra.update_column_type_and_bound(term_index, lp::lconstraint_kind::EQ, -lc*q.val(), e.dep());
c().lra.update_column_type_and_bound(term_index, lp::lconstraint_kind::EQ, offset, e.dep());
c().m_check_feasible = true;
#else
new_lemma lemma(m_core,"nla-linear");
lp::explanation exp;
explain(e, exp);
lemma &= exp;
term t;
while (!q.is_val()) {
t.add_monomial(lc*q.hi().val(), q.var());
q = q.lo();
}
lemma |= ineq(t, llc::EQ, -lc*q.val());
#endif

return true;
}

Expand Down Expand Up @@ -690,12 +695,11 @@ namespace nla {

auto dep = eq.dep();
cross_nested cn(
[this, dep](const nex* n) { bool r = c().m_intervals.check_nex(n, dep); TRACE("grobner", tout << "check " << r << " " << *n << "\n"); return r; },
[this, dep](const nex* n) { return c().m_intervals.check_nex(n, dep); },
[this](unsigned j) { return c().var_is_fixed(j); },
[this]() { return c().random(); }, nc);
cn.run(to_sum(e));
bool ret = cn.done();
TRACE("grobner", tout << "Horner " << ret << " " << eq.poly() << "\n");
return ret;
}

Expand All @@ -714,10 +718,12 @@ namespace nla {
void grobner::check_missing_propagation(const dd::solver::equation& e) {
bool is_confl = is_nla_conflict(e);
CTRACE("grobner", is_confl, m_solver.display(tout << "missed conflict ", e););
if (is_confl)
if (is_confl) {
IF_VERBOSE(2, verbose_stream() << "missed conflict\n");
return;
lbool r = c().m_nra.check_tight(e.poly());
CTRACE("grobner", r == l_false, m_solver.display(tout << "tight equality ", e););
}
//lbool r = c().m_nra.check_tight(e.poly());
//CTRACE("grobner", r == l_false, m_solver.display(tout << "tight equality ", e););
}


Expand Down
1 change: 1 addition & 0 deletions src/math/lp/nla_grobner.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace nla {
unsigned m_quota = 0;
unsigned m_delay_base = 0;
unsigned m_delay = 0;
std::unordered_map<unsigned_vector, lpvar, hash_svector> m_mon2var;

lp::lp_settings& lp_settings();

Expand Down

0 comments on commit c9d298e

Please sign in to comment.