3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-20 07:24:40 +00:00

allow gomory cut for a row with free non-basic vars

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2018-09-06 16:47:25 -07:00
parent de4a2b3ea7
commit 064cf9e983
5 changed files with 81 additions and 54 deletions

View file

@ -104,11 +104,10 @@ bool int_solver::is_gomory_cut_target(const row_strip<mpq>& row) {
j = p.var();
if (!is_base(j) && (!at_bound(j) || !is_zero(get_value(j).y))) {
TRACE("gomory_cut", tout << "row is not gomory cut target:\n";
display_column(tout, j);
tout << "infinitesimal: " << !is_zero(get_value(j).y) << "\n";);
display_column(tout, j););
return false;
}
}
}
return true;
}
@ -122,7 +121,6 @@ constraint_index int_solver::column_lower_bound_constraint(unsigned j) const {
return m_lar_solver->get_column_lower_bound_witness(j);
}
bool int_solver::current_solution_is_inf_on_cut() const {
const auto & x = m_lar_solver->m_mpq_lar_core_solver.m_r_x;
impq v = m_t.apply(x);
@ -150,6 +148,7 @@ lia_move int_solver::proceed_with_gomory_cut(unsigned j) {
return create_branch_on_column(j);
m_upper = true;
return mk_gomory_cut(j, row);
}
@ -377,10 +376,17 @@ lia_move int_solver::make_hnf_cut() {
#endif
lia_move r = m_hnf_cutter.create_cut(m_t, m_k, m_ex, m_upper, x0);
if (r == lia_move::cut) {
m_lemma->clear();
m_lemma->push_back(ineq());
ineq & f_in = first_in();
mpq k;
bool upper;
lia_move r = m_hnf_cutter.create_cut(f_in.m_term, k, *m_ex, upper, x0);
if (r == lia_move::cut) {
f_in.m_term.m_v = -k;
f_in.m_cmp = upper? lconstraint_kind::LE : GE;
TRACE("hnf_cut",
m_lar_solver->print_term(m_t, tout << "cut:");
tout << " <= " << m_k << std::endl;
print_ineq(f_in, tout << "cut:");
for (unsigned i : m_hnf_cutter.constraints_for_explanation()) {
m_lar_solver->print_constraint(i, tout);
}
@ -861,7 +867,7 @@ bool int_solver::at_bound(unsigned j) const {
case column_type::upper_bound:
return mpq_solver.m_upper_bounds[j] == get_value(j);
default:
return false;
return true; // a free var is always at a bound
}
}
@ -999,7 +1005,7 @@ lia_move int_solver::create_branch_on_column(int j) {
TRACE("check_main_int", tout << "branching" << std::endl;);
lp_assert(m_t.is_empty());
lp_assert(j != -1);
m_t->add_coeff_var(mpq(1), m_lar_solver->adjust_column_index_to_term_index(j));
first_in().add_coeff_var(mpq(1), m_lar_solver->adjust_column_index_to_term_index(j));
if (is_free(j)) {
m_upper = true;
m_k = mpq(0);