3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-08 00:05:46 +00:00

push outline of using cjust for overflow premise

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-09-09 09:56:00 +02:00
parent a5b7f9d77b
commit 611c28fc47
8 changed files with 101 additions and 15 deletions

View file

@ -87,6 +87,7 @@ namespace polysat {
return best_bound != -1;
}
/// Add Ω*(x, y) to the conflict state.
///
/// @param[in] p bit width
@ -160,6 +161,37 @@ namespace polysat {
return true;
}
// special case viable sets.
bool inf_saturate::push_omega_viable(conflict_core& core, clause_builder& reason, unsigned level, pdd const& px, pdd const& py) {
if (!px.is_var() || !py.is_var())
return false;
pvar x = px.var();
pvar y = py.var();
rational x_max = s().m_viable.max_viable(x);
rational y_max = s().m_viable.max_viable(y);
auto& pddm = px.manager();
unsigned bit_size = pddm.power_of_2();
if (x_max * y_max < rational::power_of_two(bit_size)) {
// max values don't overflow, we can justify no-overflow using cjust for x, y
for (auto c : s().m_cjust[x])
reason.push(c);
for (auto c : s().m_cjust[y])
reason.push(c);
return true;
}
rational x_val = s().get_value(x);
rational y_val = s().get_value(y);
if (x_val * y_val >= rational::power_of_two(bit_size))
return false;
// TODO: try bisection approach to find values between x_val and y_val and x_max, y_max
// find x_mid, y_mid that doesn't overflow.
return false;
}
/*
* Match [v] .. <= v
*/

View file

@ -38,6 +38,7 @@ namespace polysat {
class inf_saturate : public inference_engine {
bool find_upper_bound(pvar x, signed_constraint& c, rational& bound);
bool push_omega_viable(conflict_core& core, clause_builder& reason, unsigned level, pdd const& x, pdd const& y);
bool push_omega_mul(conflict_core& core, clause_builder& reason, unsigned level, pdd const& x, pdd const& y);
signed_constraint ineq(unsigned level, bool strict, pdd const& lhs, pdd const& rhs);
void push_c(conflict_core& core, signed_constraint const& c, clause_builder& reason);

View file

@ -228,6 +228,8 @@ namespace polysat {
void new_constraint(signed_constraint c, unsigned dep, bool activate);
static void insert_constraint(signed_constraints& cs, signed_constraint c);
viable& get_viable() { return m_viable; }
bool invariant();
static bool invariant(signed_constraints const& cs);
bool wlist_invariant();

View file

@ -241,6 +241,14 @@ namespace polysat {
#endif
}
rational viable::min_viable(pvar v) {
return var2bits(v).min(m_viable[v]);
}
rational viable::max_viable(pvar v) {
return var2bits(v).max(m_viable[v]);
}
dd::fdd const& viable::sz2bits(unsigned sz) {
m_bits.reserve(sz + 1);
auto* bits = m_bits[sz];

View file

@ -180,6 +180,12 @@ namespace polysat {
*/
void add_non_viable(pvar v, rational const& val);
/*
* Extract min and max viable values for v
*/
rational min_viable(pvar v);
rational max_viable(pvar v);
/**
* Find a next viable value for variable.