3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

fix wrong simplex backtracking

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-05-09 08:51:07 -07:00
parent d2db8007d8
commit 05a39cb2cf
11 changed files with 231 additions and 56 deletions

View file

@ -126,7 +126,7 @@ namespace simplex {
row get_infeasible_row();
var_t get_base_var(row const& r) const { return m_row2base[r.id()]; }
numeral const& get_base_coeff(row const& r) const { return m_vars[m_row2base[r.id()]].m_base_coeff; }
void del_row(row const& r);
void del_row(var_t base_var);
void set_lower(var_t var, eps_numeral const& b);
void set_upper(var_t var, eps_numeral const& b);
void get_lower(var_t var, scoped_eps_numeral& b) const { b = m_vars[var].m_lower; }
@ -157,6 +157,7 @@ namespace simplex {
private:
void del_row(row const& r);
var_t select_var_to_fix();
pivot_strategy_t pivot_strategy();
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }

View file

@ -114,6 +114,7 @@ namespace simplex {
em.set(m_vars[base_var].m_value, value);
add_patch(base_var);
SASSERT(well_formed_row(r));
SASSERT(well_formed());
return r;
}
@ -135,10 +136,51 @@ namespace simplex {
template<typename Ext>
void simplex<Ext>::del_row(row const& r) {
TRACE("simplex", tout << r.id() << "\n";);
m_vars[m_row2base[r.id()]].m_is_base = false;
var_t var = m_row2base[r.id()];
m_vars[var].m_is_base = false;
m_vars[var].m_lower_valid = false;
m_vars[var].m_upper_valid = false;
m_row2base[r.id()] = null_var;
M.del(r);
SASSERT(M.col_begin(var) == M.col_end(var));
SASSERT(well_formed());
}
template<typename Ext>
void simplex<Ext>::del_row(var_t var) {
TRACE("simplex", tout << var << "\n";);
row r;
if (is_base(var)) {
r = row(m_vars[var].m_base2row);
}
else {
col_iterator it = M.col_begin(var), end = M.col_end(var);
if (it == end) {
return;
}
typename matrix::row_entry const& re = it.get_row_entry();
r = it.get_row();
var_t old_base = m_row2base[r.id()];
scoped_eps_numeral new_value(em);
var_info& vi = m_vars[old_base];
if (below_lower(old_base)) {
new_value = vi.m_lower;
}
else if (above_upper(old_base)) {
new_value = vi.m_upper;
}
else {
new_value = vi.m_value;
}
// need to move var such that old_base comes in bound.
update_and_pivot(old_base, var, re.m_coeff, new_value);
SASSERT(is_base(var));
SASSERT(m_vars[var].m_base2row == r.id());
SASSERT(!below_lower(old_base) && !above_upper(old_base));
}
del_row(r);
TRACE("simplex", display(tout););
SASSERT(well_formed());
}
template<typename Ext>
@ -164,6 +206,7 @@ namespace simplex {
em.sub(b, vi.m_value, delta);
update_value(var, delta);
}
SASSERT(well_formed());
}
template<typename Ext>
@ -177,6 +220,7 @@ namespace simplex {
em.sub(b, vi.m_value, delta);
update_value(var, delta);
}
SASSERT(well_formed());
}
template<typename Ext>
@ -194,6 +238,7 @@ namespace simplex {
scoped_eps_numeral delta(em);
em.sub(b, m_vars[var].m_value, delta);
update_value(var, delta);
SASSERT(well_formed());
}
template<typename Ext>
@ -345,6 +390,7 @@ namespace simplex {
SASSERT(well_formed_row(row(r_k)));
}
}
SASSERT(well_formed());
}
template<typename Ext>
@ -883,7 +929,13 @@ namespace simplex {
var_t s = m_row2base[i];
if (s == null_var) continue;
SASSERT(i == m_vars[s].m_base2row);
SASSERT(well_formed_row(row(i)));
VERIFY(well_formed_row(row(i)));
}
for (unsigned i = 0; i < m_vars.size(); ++i) {
if (!is_base(i)) {
SASSERT(!above_upper(i));
SASSERT(!below_lower(i));
}
}
return true;
}
@ -909,7 +961,11 @@ namespace simplex {
sum += tmp;
SASSERT(s != it->m_var || m.eq(m_vars[s].m_base_coeff, it->m_coeff));
}
SASSERT(em.is_zero(sum));
if (!em.is_zero(sum)) {
IF_VERBOSE(0, M.display_row(verbose_stream(), r););
TRACE("pb", display(tout << "non-well formed row\n"); M.display_row(tout << "row: ", r););
throw default_exception("non-well formed row");
}
return true;
}