3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 17:44:08 +00:00

fix divergence reported by Guido Martinez

This commit is contained in:
Nikolaj Bjorner 2023-12-07 13:34:35 -08:00
parent 6afed0819c
commit 4d1d067d42
4 changed files with 22 additions and 0 deletions

View file

@ -611,4 +611,19 @@ void emonics::set_propagated(monic const& m) {
m_u_f_stack.push(set_unpropagated(*this, m.var()));
}
void emonics::set_bound_propagated(monic const& m) {
struct set_bound_unpropagated : public trail {
emonics& em;
unsigned var;
public:
set_bound_unpropagated(emonics& em, unsigned var): em(em), var(var) {}
void undo() override {
em[var].set_bound_propagated(false);
}
};
SASSERT(!m.is_bound_propagated());
(*this)[m.var()].set_bound_propagated(true);
m_u_f_stack.push(set_bound_unpropagated(*this, m.var()));
}
}

View file

@ -143,6 +143,7 @@ public:
void after_merge_eh(unsigned r2, unsigned r1, unsigned v2, unsigned v1) {}
void set_propagated(monic const& m);
void set_bound_propagated(monic const& m);
// this method is required by union_find
trail_stack & get_trail_stack() { return m_u_f_stack; }

View file

@ -59,6 +59,7 @@ class monic: public mon_eq {
bool m_rsign;
mutable unsigned m_visited;
bool m_propagated = false;
bool m_bound_propagated = false;
public:
// constructors
monic(lpvar v, unsigned sz, lpvar const* vs, unsigned idx):
@ -77,6 +78,8 @@ public:
void sort_rvars() { std::sort(m_rvars.begin(), m_rvars.end()); }
void set_propagated(bool p) { m_propagated = p; }
bool is_propagated() const { return m_propagated; }
void set_bound_propagated(bool p) { m_bound_propagated = p; }
bool is_bound_propagated() const { return m_bound_propagated; }
svector<lpvar>::const_iterator begin() const { return vars().begin(); }
svector<lpvar>::const_iterator end() const { return vars().end(); }

View file

@ -1517,6 +1517,9 @@ void core::add_bounds() {
for (lpvar j : m.vars()) {
if (!var_is_free(j))
continue;
if (m.is_bound_propagated())
continue;
m_emons.set_bound_propagated(m);
// split the free variable (j <= 0, or j > 0), and return
m_literals.push_back(ineq(j, lp::lconstraint_kind::EQ, rational::zero()));
TRACE("nla_solver", print_ineq(m_literals.back(), tout) << "\n");