3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-12 14:10:54 +00:00

backtrack

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-10-10 18:23:25 -07:00
parent a50cecaefa
commit 4c81f8676c

View file

@ -13,11 +13,6 @@ Author:
Jakob Rath 2021-04-6 Jakob Rath 2021-04-6
TODO:
compute forbidden interval coefficients a1, a2 modulo current assignment to handle pseudo-linear cases.
test_mont_bounds(8) produces constraint 13 <= v1*v2, where v2 = 1, then v1 is linear and is constrained above 13.
--*/ --*/
#include "math/polysat/forbidden_intervals.h" #include "math/polysat/forbidden_intervals.h"
@ -175,6 +170,7 @@ namespace polysat {
} }
/** Precondition: all variables other than v are assigned. /** Precondition: all variables other than v are assigned.
* *
* \param[out] out_interval The forbidden interval for this constraint * \param[out] out_interval The forbidden interval for this constraint
@ -186,6 +182,20 @@ namespace polysat {
{ {
if (!c->is_ule()) if (!c->is_ule())
return false; return false;
struct backtrack {
bool released = false;
vector<signed_constraint>& side_cond;
unsigned sz;
backtrack(vector<signed_constraint>& s):side_cond(s), sz(s.size()) {}
~backtrack() {
if (!released)
side_cond.shrink(sz);
}
};
backtrack _backtrack(out_side_cond);
// Current only works when degree(v) is at most one on both sides // Current only works when degree(v) is at most one on both sides
pdd lhs = c->to_ule().lhs(); pdd lhs = c->to_ule().lhs();
pdd rhs = c->to_ule().rhs(); pdd rhs = c->to_ule().rhs();
@ -206,6 +216,16 @@ namespace polysat {
rational const pow2 = rational::power_of_two(sz); rational const pow2 = rational::power_of_two(sz);
rational const minus_one = pow2 - 1; rational const minus_one = pow2 - 1;
/**
* TODO: to express the interval for coefficient 2^i symbolically,
* we need right-shift/upper-bits-extract in the language.
* So currently we can only do it if the coefficient is 1 or -1.
*/
auto coefficient_is_handled = [&](rational const& r) {
return r.is_zero() || r.is_one() || r == minus_one;
};
pdd p1 = m.zero(); pdd p1 = m.zero();
pdd e1 = m.zero(); pdd e1 = m.zero();
if (deg1 == 0) if (deg1 == 0)
@ -247,13 +267,13 @@ namespace polysat {
} }
rational a1 = p1.val(); rational a1 = p1.val();
rational a2 = p2.val(); rational a2 = p2.val();
// TODO: to express the interval for coefficient 2^i symbolically, we need right-shift/upper-bits-extract in the language.
// So currently we can only do it if the coefficient is 1 or -1.
LOG("values " << a1 << " " << a2); LOG("values " << a1 << " " << a2);
if (!a1.is_zero() && !a1.is_one() && a1 != minus_one) if (!coefficient_is_handled(a1))
return false; return false;
if (!a2.is_zero() && !a2.is_one() && a2 != minus_one) if (!coefficient_is_handled(a2))
return false; return false;
/* /*
unsigned j1 = 0; unsigned j1 = 0;
unsigned j2 = 0; unsigned j2 = 0;
@ -269,7 +289,9 @@ namespace polysat {
// Concrete values of evaluable terms // Concrete values of evaluable terms
auto e1s = e1.subst_val(s.assignment()); auto e1s = e1.subst_val(s.assignment());
auto e2s = e2.subst_val(s.assignment()); auto e2s = e2.subst_val(s.assignment());
// TODO: this is not always true! cjust[v]/conflict may contain unassigned variables (they're coming from a previous conflict, but together they lead to a conflict. need something else to handle that.) // TODO: this is not always true! cjust[v]/conflict may contain unassigned variables
// (they're coming from a previous conflict, but together they lead to a conflict.
// need something else to handle that.)
if (!e1s.is_val()) if (!e1s.is_val())
return false; return false;
if (!e2s.is_val()) if (!e2s.is_val())
@ -280,9 +302,9 @@ namespace polysat {
bool is_trivial; bool is_trivial;
pdd condition_body = m.zero(); pdd condition_body = m.zero();
pdd lo = m.zero(); pdd lo = m.zero();
rational lo_val = rational::zero(); rational lo_val(0);
pdd hi = m.zero(); pdd hi = m.zero();
rational hi_val = rational::zero(); rational hi_val(0);
if (a2.is_zero()) { if (a2.is_zero()) {
SASSERT(!a1.is_zero()); SASSERT(!a1.is_zero());
@ -326,6 +348,8 @@ namespace polysat {
} }
} }
_backtrack.released = true;
if (condition_body.is_val()) { if (condition_body.is_val()) {
// Condition is trivial; no need to create a constraint for that. // Condition is trivial; no need to create a constraint for that.
SASSERT(is_trivial == condition_body.is_zero()); SASSERT(is_trivial == condition_body.is_zero());