3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-10 21:20:52 +00:00

disable throttle on unbounded objectives in shared theories. It may violate an interface equality, to fix issue #120

Signed-off-by: Nikolaj Bjorner <nbjorner@hotmail.com>
This commit is contained in:
Nikolaj Bjorner 2015-06-02 11:14:59 -07:00
parent 171ef5c8e3
commit 9734407cde
2 changed files with 31 additions and 1 deletions

View file

@ -885,6 +885,7 @@ namespace smt {
void add_tmp_row_entry(row & r, numeral const & coeff, theory_var v); void add_tmp_row_entry(row & r, numeral const & coeff, theory_var v);
enum max_min_t { UNBOUNDED, AT_BOUND, OPTIMIZED, BEST_EFFORT}; enum max_min_t { UNBOUNDED, AT_BOUND, OPTIMIZED, BEST_EFFORT};
max_min_t max_min(theory_var v, bool max, bool maintain_integrality, bool& has_shared); max_min_t max_min(theory_var v, bool max, bool maintain_integrality, bool& has_shared);
bool has_interface_equality(theory_var v);
bool max_min(svector<theory_var> const & vars); bool max_min(svector<theory_var> const & vars);
max_min_t max_min(row& r, bool max, bool maintain_integrality, bool& has_shared); max_min_t max_min(row& r, bool max, bool maintain_integrality, bool& has_shared);

View file

@ -1545,6 +1545,25 @@ namespace smt {
return is_tighter; return is_tighter;
} }
/**
\brief Check if bound change affects interface equality.
*/
template<typename Ext>
bool theory_arith<Ext>::has_interface_equality(theory_var x) {
theory_var num = get_num_vars();
context& ctx = get_context();
enode* r = get_enode(x)->get_root();
for (theory_var v = 0; v < num; v++) {
if (v == x) continue;
enode* n = get_enode(v);
if (ctx.is_shared(n) && n->get_root() == r) {
return true;
}
}
return false;
}
/** /**
\brief Maximize (Minimize) the given temporary row. \brief Maximize (Minimize) the given temporary row.
Return true if succeeded. Return true if succeeded.
@ -1660,13 +1679,23 @@ namespace smt {
SASSERT(!maintain_integrality || valid_assignment()); SASSERT(!maintain_integrality || valid_assignment());
continue; continue;
} }
if (ctx.is_shared(get_enode(x_j))) { #if 0
if (ctx.is_shared(get_enode(x_j)) && has_interface_equality(x_j)) {
++best_efforts; ++best_efforts;
} }
else { else {
SASSERT(unbounded_gain(max_gain)); SASSERT(unbounded_gain(max_gain));
has_shared = false;
best_efforts = 0; best_efforts = 0;
} }
#endif
//
// NB. As it stands this is a possibly unsound conclusion for shared theories.
// the tradeoff is non-termination for unbounded objectives in the
// presence of sharing.
//
has_shared = false;
best_efforts = 0;
result = UNBOUNDED; result = UNBOUNDED;
break; break;
} }