3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-25 01:55:32 +00:00

find_upper_bound

This commit is contained in:
Jakob Rath 2021-09-08 18:40:29 +02:00
parent 64ce6cb5c1
commit 18411afda2
3 changed files with 29 additions and 12 deletions

View file

@ -65,25 +65,26 @@ namespace polysat {
push_c(core, c, reason);
}
#if 0
bool find_upper_bound(pvar x, signed_constraint& c, rational& bound) {
auto & bounds = s().cjust[x];
rational best_bound = -1;
/// Find smallest upper bound for the variable x, i.e., a constraint 'x <= bound' where the rhs is constant.
bool inf_saturate::find_upper_bound(pvar x, signed_constraint& c, rational& bound) {
auto& bounds = s().m_cjust[x];
rational best_bound(-1);
pdd y = s().var(x);
for (auto& b : bounds) {
inequality bound = b.as_inequality();
if (is_x_l_Y(x, bound, y) && y.is_value()) {
if (y.value() < best_bound) {
if (bound.is_strict)
value = y.value() - 1;
if (is_x_l_Y(x, bound, y) && y.is_val()) {
rational value = y.val();
if (bound.is_strict && value > 0) // TODO: should we return something for "x < 0"? (is always false, should lead to conflict earlier)
value = value - 1;
if (value < best_bound) {
best_bound = value;
c = bound;
c = b;
}
}
}
return best_bound != -1;
}
#endif
/// Add Ω*(x, y) to the conflict state.
///
/// @param[in] p bit width
@ -171,6 +172,14 @@ namespace polysat {
return i.lhs == s().var(v);
}
/*
* Match [x] x <= y
*/
bool inf_saturate::is_x_l_Y(pvar x, inequality const& c, pdd& y) {
y = c.rhs;
return is_g_v(x, c);
}
/*
* Match [x] y <= a*x
*/

View file

@ -36,6 +36,8 @@ namespace polysat {
};
class inf_saturate : public inference_engine {
bool find_upper_bound(pvar x, signed_constraint& c, rational& bound);
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);
@ -59,6 +61,9 @@ namespace polysat {
// c := v ~ rhs
bool is_g_v(pvar v, inequality const& c);
// c := x ~ Y
bool is_x_l_Y(pvar x, inequality const& c, pdd& y);
// c := X*y ~ X*Z
bool is_Xy_l_XZ(pvar y, inequality const& c, pdd& x, pdd& z);
bool verify_Xy_l_XZ(pvar y, inequality const& c, pdd const& x, pdd const& z);

View file

@ -90,8 +90,11 @@ namespace polysat {
// TODO: other conditions (e.g. when forbidden interval would be full)
if (is_positive)
return lhs.is_val() && rhs.is_val() && lhs.val() > rhs.val();
else
else {
if (lhs.is_zero())
return true; // 0 > ... is always false
return (lhs.is_val() && rhs.is_val() && lhs.val() <= rhs.val()) || (lhs == rhs);
}
}
bool ule_constraint::is_always_false(bool is_positive) {