From 3fcc5a222754ca1c07312ec28fd3bdfeb9a22850 Mon Sep 17 00:00:00 2001 From: Lev Nachmanson Date: Sun, 3 Nov 2024 16:01:12 -0800 Subject: [PATCH] fixes in tigthening Signed-off-by: Lev Nachmanson --- src/math/lp/dioph_eq.cpp | 115 ++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/src/math/lp/dioph_eq.cpp b/src/math/lp/dioph_eq.cpp index 9e36744ef..acf575506 100644 --- a/src/math/lp/dioph_eq.cpp +++ b/src/math/lp/dioph_eq.cpp @@ -4,6 +4,7 @@ #include "math/lp/lp_utils.h" #include #include +unsigned glb=0; namespace lp { // This class represents a term with an added constant number c, in form sum {x_i*a_i} + c. class dioph_eq::imp { @@ -85,7 +86,7 @@ namespace lp { std::ostream& print_S(std::ostream & out) { out << "S:\n"; for (unsigned i : m_s) { - print_eprime_entry(i, out); + print_entry(i, out); } return out; } @@ -156,14 +157,14 @@ namespace lp { S, NO_S_NO_F }; - struct eprime_entry { + struct entry { unsigned m_row_index; // the index of the row in the constraint matrix that m_e corresponds to // originally m_l is the column defining the term m_e was constructed from lar_term m_l; mpq m_c; // the constant of the term entry_status m_entry_status; }; - std_vector m_eprime; + std_vector m_eprime; // the terms are stored in m_A and m_c static_matrix m_e_matrix; // the rows of the matrix are the terms, without the constant part int_solver& lia; @@ -183,11 +184,11 @@ namespace lp { // suppose e.m_l = sum {coeff*k}, then subst(e.m_e) = fix_var(sum {coeff*lar.get_term(k)}) std_vector m_k2s; - + std_vector m_fresh_definitions; // seems only needed in the debug version in remove_fresh_vars unsigned m_conflict_index = -1; // m_eprime[m_conflict_index] gives the conflict public: imp(int_solver& lia, lar_solver& lra): lia(lia), lra(lra) {} - term_o get_term_from_e_matrix(unsigned i) const { + term_o get_term_from_entry(unsigned i) const { term_o t; for (const auto & p: m_e_matrix.m_rows[i]) { t.add_monomial(p.coeff(), p.var()); @@ -197,13 +198,13 @@ namespace lp { } // the term has form sum(a_i*x_i) - t.j() = 0, // i is the index of the term in the lra.m_terms - void fill_eprime_entry(const lar_term& t) { + void fill_entry(const lar_term& t) { TRACE("dioph_eq", print_lar_term_L(t, tout) << std::endl;); unsigned i = static_cast(m_eprime.size()); - eprime_entry te = {i, lar_term(t.j()), mpq(0), entry_status::NO_S_NO_F}; + entry te = {i, lar_term(t.j()), mpq(0), entry_status::NO_S_NO_F}; m_f.push_back(te.m_row_index); m_eprime.push_back(te); - eprime_entry& e = m_eprime.back(); + entry& e = m_eprime.back(); m_e_matrix.add_row(); SASSERT(m_e_matrix.row_count() == m_eprime.size()); // this invariant is going to be broken @@ -226,7 +227,7 @@ namespace lp { m_e_matrix.add_new_element(e.m_row_index, j, - mpq(1)); } e.m_entry_status = entry_status::F; - TRACE("dioph_eq", print_eprime_entry(e, tout);); + TRACE("dioph_eq", print_entry(e, tout);); SASSERT(entry_invariant(e)); } @@ -256,7 +257,7 @@ namespace lp { TRACE("dioph_eq", tout << "not all vars are int and small\n";); continue; } - fill_eprime_entry(t); + fill_entry(t); } } @@ -301,7 +302,7 @@ namespace lp { return false; } - void prepare_lia_branch_report(const eprime_entry & e, const mpq& g, const mpq new_c) { + void prepare_lia_branch_report(const entry & e, const mpq& g, const mpq new_c) { /* We have ep.m_e/g = 0, or sum((coff_i/g)*x_i) + new_c = 0, or sum((coeff_i/g)*x_i) = -new_c, where new_c is not an integer Then sum((coeff_i/g)*x_i) <= floor(-new_c) or sum((coeff_i/g)*x_i) >= ceil(-new_c) @@ -321,8 +322,8 @@ namespace lp { // it is needed by the next steps // the conflict can be used to report "cuts from proofs" bool normalize_e_by_gcd(unsigned row_index) { - eprime_entry& e = m_eprime[row_index]; - TRACE("dioph_eq", print_eprime_entry(e, tout) << std::endl;); + entry& e = m_eprime[row_index]; + TRACE("dioph_eq", print_entry(e, tout) << std::endl;); mpq g = gcd_of_coeffs(m_e_matrix.m_rows[row_index]); if (g.is_zero() || g.is_one()) { SASSERT(g.is_one() || e.m_c.is_zero()); @@ -336,7 +337,7 @@ namespace lp { } m_eprime[row_index].m_c = c_g; e.m_l *= (1/g); - TRACE("dioph_eq", tout << "ep_m_e:"; print_eprime_entry(e, tout) << std::endl;); + TRACE("dioph_eq", tout << "ep_m_e:"; print_entry(e, tout) << std::endl;); SASSERT(entry_invariant(e)); return true; } @@ -373,9 +374,9 @@ namespace lp { void subs_front_in_indexed_vector(std::queue & q) { unsigned k = pop_front(q); if (m_indexed_work_vector[k].is_zero()) return; - const eprime_entry& e = entry_for_subs(k); + const entry& e = entry_for_subs(k); TRACE("dioph_eq", tout << "k:" << k << ", in "; print_term_o(create_term_from_ind_c(), tout) << std::endl; - tout << "subs with e:"; print_eprime_entry(e, tout) << std::endl;); + tout << "subs with e:"; print_entry(e, tout) << std::endl;); mpq coeff = m_indexed_work_vector[k]; // need to copy since it will be zeroed m_indexed_work_vector.erase(k); // m_indexed_work_vector[k] = 0; @@ -427,7 +428,7 @@ namespace lp { } return ret; } - const eprime_entry& entry_for_subs(unsigned k) const { + const entry& entry_for_subs(unsigned k) const { return m_eprime[m_k2s[k]]; } @@ -601,7 +602,7 @@ namespace lp { tout << "new " << (upper? "upper":"lower" ) << " bound:" << bound << std::endl; ); - SASSERT(upper && bound < lra.get_upper_bound(j).x || !upper && bound > lra.get_lower_bound(j).x); + SASSERT((upper && bound < lra.get_upper_bound(j).x) || (!upper && bound > lra.get_lower_bound(j).x)); lconstraint_kind kind = upper? lconstraint_kind::LE: lconstraint_kind::GE; u_dependency* dep = prev_dep; dep = lra.mk_join(dep, explain_fixed_in_meta_term(m_tmp_l)); @@ -668,8 +669,6 @@ public: lia_move ret = tighten_with_S(); if (ret == lia_move::conflict) { lra.settings().stats().m_dio_conflicts++; - enable_trace("arith"); - enable_trace("dioph_eq"); return lia_move::conflict; } return lia_move::undef; @@ -718,13 +717,12 @@ public: } std::ostream& print_e_row(unsigned i, std::ostream& out) { - return print_term_o(get_term_from_e_matrix(i), out); + return print_term_o(get_term_from_entry(i), out); } // j is the variable to eliminate, it appears in row e.m_e_matrix with // a coefficient equal to +-1 - void eliminate_var_in_f(eprime_entry& e, unsigned j, int j_sign) { - TRACE("dioph_eq", tout << "eliminate var:" << j << " by using:"; print_eprime_entry(e.m_row_index, tout) << std::endl;); - SASSERT(entry_invariant(e)); + void eliminate_var_in_f(entry& e, unsigned j, int j_sign) { + TRACE("dioph_eq", tout << "eliminate var:" << j << " by using:"; print_entry(e.m_row_index, tout) << std::endl;); unsigned piv_row_index = e.m_row_index; auto &column = m_e_matrix.m_columns[j]; int pivot_col_cell_index = -1; @@ -756,16 +754,16 @@ public: SASSERT(c.var() != piv_row_index && entry_invariant(m_eprime[c.var()])); mpq coeff = m_e_matrix.get_val(c); unsigned i = c.var(); - TRACE("dioph_eq", tout << "before pivot entry :"; print_eprime_entry(i, tout) << std::endl;); + TRACE("dioph_eq", tout << "before pivot entry :"; print_entry(i, tout) << std::endl;); m_eprime[i].m_c -= j_sign * coeff*e.m_c; m_e_matrix.pivot_row_to_row_given_cell_with_sign(piv_row_index, c, j, j_sign); m_eprime[i].m_l -= j_sign * coeff * e.m_l; - TRACE("dioph_eq", tout << "after pivoting c_row:"; print_eprime_entry(i, tout);); + TRACE("dioph_eq", tout << "after pivoting c_row:"; print_entry(i, tout);); CTRACE("dioph_eq", !entry_invariant(m_eprime[i]), tout << "invariant delta:"; { const auto& e = m_eprime[i]; - print_term_o(get_term_from_e_matrix(e.m_row_index) - fix_vars(open_ml(e.m_l)), tout) << std::endl; + print_term_o(get_term_from_entry(e.m_row_index) - fix_vars(open_ml(e.m_l)), tout) << std::endl; } ); SASSERT(entry_invariant(m_eprime[i])); @@ -773,8 +771,18 @@ public: } } - bool entry_invariant(const eprime_entry& e) const { - return remove_fresh_vars(get_term_from_e_matrix(e.m_row_index)) == fix_vars(open_ml(e.m_l)); + bool entry_invariant(const entry& e) const { + bool ret = remove_fresh_vars(get_term_from_entry(e.m_row_index)) == fix_vars(open_ml(e.m_l)); + if (ret) return true; + TRACE("dioph_eq", + tout << "get_term_from_entry("<