mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
bug fixes to min-max, and experiments with hsmax
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
2071029bb3
commit
57fc0f3f55
4 changed files with 124 additions and 29 deletions
|
@ -857,7 +857,7 @@ namespace smt {
|
|||
void add_tmp_row(row & r1, numeral const & coeff, row const & r2);
|
||||
theory_var pick_var_to_leave(bool has_int, theory_var x_j, bool inc, numeral & a_ij, inf_numeral & gain, bool& skiped_row);
|
||||
bool is_safe_to_leave(theory_var x, bool& has_int);
|
||||
void move_to_bound(theory_var x_i, bool inc);
|
||||
bool move_to_bound(theory_var x_i, bool inc);
|
||||
template<bool invert>
|
||||
void add_tmp_row_entry(row & r, numeral const & coeff, theory_var v);
|
||||
enum max_min_t { UNBOUNDED, AT_BOUND, OPTIMIZED, BEST_EFFORT};
|
||||
|
@ -1061,6 +1061,7 @@ namespace smt {
|
|||
bool valid_row_assignment() const;
|
||||
bool valid_row_assignment(row const & r) const;
|
||||
bool satisfy_bounds() const;
|
||||
bool satisfy_integrality() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1069,7 +1069,7 @@ namespace smt {
|
|||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_arith<Ext>::maximize(theory_var v, expr_ref& blocker) {
|
||||
TRACE("opt", tout << "data-size: " << m_data.size() << "\n";);
|
||||
TRACE("bound_bug", display_var(tout, v); display(tout););
|
||||
max_min_t r = max_min(v, true);
|
||||
if (r == UNBOUNDED) {
|
||||
blocker = get_manager().mk_false();
|
||||
|
@ -1361,7 +1361,8 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
TRACE("opt", tout << "after traversing row:\nx_i: v" << x_i << ", x_j: v" << x_j << ", gain: " << gain << "\n";
|
||||
tout << "skipped row: " << (skipped_row?"yes":"no") << "\n";);
|
||||
tout << "skipped row: " << (skipped_row?"yes":"no") << "\n";
|
||||
display(tout););
|
||||
|
||||
if (x_j == null_theory_var) {
|
||||
TRACE("opt", tout << "row is " << (max ? "maximized" : "minimized") << "\n";);
|
||||
|
@ -1378,6 +1379,7 @@ namespace smt {
|
|||
TRACE("opt", tout << "moved v" << x_j << " to upper bound\n";);
|
||||
SASSERT(valid_row_assignment());
|
||||
SASSERT(satisfy_bounds());
|
||||
SASSERT(satisfy_integrality());
|
||||
continue;
|
||||
}
|
||||
if (!inc && lower(x_j)) {
|
||||
|
@ -1385,13 +1387,14 @@ namespace smt {
|
|||
TRACE("opt", tout << "moved v" << x_j << " to lower bound\n";);
|
||||
SASSERT(valid_row_assignment());
|
||||
SASSERT(satisfy_bounds());
|
||||
SASSERT(satisfy_integrality());
|
||||
continue;
|
||||
}
|
||||
result = skipped_row?BEST_EFFORT:UNBOUNDED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_fixed(x_j) && is_bounded(x_j) && (upper_bound(x_j) - lower_bound(x_j) <= gain)) {
|
||||
if (!is_fixed(x_j) && is_bounded(x_j) && !skipped_row && (upper_bound(x_j) - lower_bound(x_j) <= gain)) {
|
||||
// can increase/decrease x_j up to upper/lower bound.
|
||||
if (inc) {
|
||||
update_value(x_j, upper_bound(x_j) - get_value(x_j));
|
||||
|
@ -1403,6 +1406,7 @@ namespace smt {
|
|||
}
|
||||
SASSERT(valid_row_assignment());
|
||||
SASSERT(satisfy_bounds());
|
||||
SASSERT(satisfy_integrality());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1429,10 @@ namespace smt {
|
|||
move_xi_to_lower = a_ij.is_pos();
|
||||
else
|
||||
move_xi_to_lower = a_ij.is_neg();
|
||||
move_to_bound(x_i, move_xi_to_lower);
|
||||
if (!move_to_bound(x_i, move_xi_to_lower)) {
|
||||
result = BEST_EFFORT;
|
||||
break;
|
||||
}
|
||||
|
||||
row & r2 = m_rows[get_var_row(x_j)];
|
||||
coeff.neg();
|
||||
|
@ -1433,6 +1440,7 @@ namespace smt {
|
|||
SASSERT(r.get_idx_of(x_j) == -1);
|
||||
SASSERT(valid_row_assignment());
|
||||
SASSERT(satisfy_bounds());
|
||||
SASSERT(satisfy_integrality());
|
||||
}
|
||||
TRACE("opt", display(tout););
|
||||
return result;
|
||||
|
@ -1444,7 +1452,7 @@ namespace smt {
|
|||
*/
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::move_to_bound(theory_var x_i, bool move_to_lower) {
|
||||
bool theory_arith<Ext>::move_to_bound(theory_var x_i, bool move_to_lower) {
|
||||
inf_numeral delta, delta_abs;
|
||||
|
||||
if (move_to_lower) {
|
||||
|
@ -1484,6 +1492,9 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
if (is_int(x_i)) {
|
||||
delta_abs = floor(delta_abs);
|
||||
}
|
||||
|
||||
if (move_to_lower) {
|
||||
delta = -delta_abs;
|
||||
|
@ -1493,8 +1504,8 @@ namespace smt {
|
|||
}
|
||||
|
||||
TRACE("opt", tout << "Safe delta: " << delta << "\n";);
|
||||
|
||||
update_value(x_i, delta);
|
||||
return !delta.is_zero();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -199,6 +199,18 @@ namespace smt {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
bool theory_arith<Ext>::satisfy_integrality() const {
|
||||
int num = get_num_vars();
|
||||
for (theory_var v = 0; v < num; v++) {
|
||||
if (!(is_int(v) && get_value(v).is_int())) {
|
||||
TRACE("bound_bug", display_var(tout, v); display(tout););
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue