3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-21 05:13:39 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-11-25 18:46:43 +01:00
parent adf41c5d02
commit a4e29ecd7e
4 changed files with 35 additions and 32 deletions

View file

@ -40,8 +40,6 @@ namespace polysat {
void set_rule(char const* r) { m_rule = r; } void set_rule(char const* r) { m_rule = r; }
bool find_upper_bound(pvar x, signed_constraint& c, rational& bound);
void push_omega(pdd const& x, pdd const& y); void push_omega(pdd const& x, pdd const& y);
void push_omega_bisect(pdd const& x, rational x_max, pdd const& y, rational y_max); void push_omega_bisect(pdd const& x, rational x_max, pdd const& y, rational y_max);
signed_constraint ineq(bool strict, pdd const& lhs, pdd const& rhs); signed_constraint ineq(bool strict, pdd const& lhs, pdd const& rhs);

View file

@ -134,20 +134,22 @@ namespace polysat {
v = p.var(); v = p.var();
else if (q.is_unilinear()) else if (q.is_unilinear())
v = q.var(); v = q.var();
if (v != null_var) { else
signed_constraint sc(this, is_positive); return;
s.m_viable.intersect(v, sc);
rational val; signed_constraint sc(this, is_positive);
switch (s.m_viable.find_viable(v, val)) { if (!s.m_viable.intersect(v, sc))
case dd::find_t::singleton: return;
s.propagate(v, val, sc); rational val;
break; switch (s.m_viable.find_viable(v, val)) {
case dd::find_t::empty: case dd::find_t::singleton:
s.set_conflict(v); s.propagate(v, val, sc); // TBD why is sc used as justification? It should be all of viable
break; break;
default: case dd::find_t::empty:
break; s.set_conflict(v);
} break;
default:
break;
} }
} }

View file

@ -64,25 +64,29 @@ namespace polysat {
m_trail.pop_back(); m_trail.pop_back();
} }
void viable::intersect(pvar v, signed_constraint const& c) { bool viable::intersect(pvar v, signed_constraint const& c) {
auto& fi = s.m_forbidden_intervals; auto& fi = s.m_forbidden_intervals;
entry* ne = alloc_entry(); entry* ne = alloc_entry();
if (!fi.get_interval(c, v, ne->interval, ne->side_cond) || ne->interval.is_currently_empty()) if (!fi.get_interval(c, v, ne->interval, ne->side_cond) || ne->interval.is_currently_empty()) {
m_alloc.push_back(ne); m_alloc.push_back(ne);
return false;
}
else { else {
ne->src = c; ne->src = c;
intersect(v, ne); return intersect(v, ne);
} }
} }
void viable::intersect(pvar v, entry* ne) { bool viable::intersect(pvar v, entry* ne) {
entry* e = m_viable[v]; entry* e = m_viable[v];
if (e && e->interval.is_full()) if (e && e->interval.is_full()) {
return; m_alloc.push_back(ne);
return false;
}
if (ne->interval.is_currently_empty()) { if (ne->interval.is_currently_empty()) {
m_alloc.push_back(ne); m_alloc.push_back(ne);
return; return false;
} }
auto create_entry = [&]() { auto create_entry = [&]() {
@ -98,8 +102,6 @@ namespace polysat {
e->remove_from(m_viable[v], e); e->remove_from(m_viable[v], e);
}; };
//LOG("intersect " << ne->interval);
if (!e) if (!e)
m_viable[v] = create_entry(); m_viable[v] = create_entry();
else { else {
@ -107,14 +109,14 @@ namespace polysat {
do { do {
if (e->interval.contains(ne->interval)) { if (e->interval.contains(ne->interval)) {
m_alloc.push_back(ne); m_alloc.push_back(ne);
return; return false;
} }
while (ne->interval.contains(e->interval)) { while (ne->interval.contains(e->interval)) {
entry* n = e->next(); entry* n = e->next();
remove_entry(e); remove_entry(e);
if (!m_viable[v]) { if (!m_viable[v]) {
m_viable[v] = create_entry(); m_viable[v] = create_entry();
return; return true;
} }
if (e == first) if (e == first)
first = n; first = n;
@ -124,13 +126,13 @@ namespace polysat {
if (e->interval.lo_val() > ne->interval.lo_val()) { if (e->interval.lo_val() > ne->interval.lo_val()) {
if (first->prev()->interval.contains(ne->interval)) { if (first->prev()->interval.contains(ne->interval)) {
m_alloc.push_back(ne); m_alloc.push_back(ne);
return; return false;
} }
e->insert_before(create_entry()); e->insert_before(create_entry());
if (e == first) if (e == first)
m_viable[v] = e->prev(); m_viable[v] = e->prev();
SASSERT(well_formed(m_viable[v])); SASSERT(well_formed(m_viable[v]));
return; return true;
} }
e = e->next(); e = e->next();
} }
@ -139,6 +141,7 @@ namespace polysat {
first->insert_before(create_entry()); first->insert_before(create_entry());
} }
SASSERT(well_formed(m_viable[v])); SASSERT(well_formed(m_viable[v]));
return true;
} }
bool viable::has_viable(pvar v) { bool viable::has_viable(pvar v) {

View file

@ -44,7 +44,7 @@ namespace polysat {
entry* alloc_entry(); entry* alloc_entry();
void intersect(pvar v, entry* e); bool intersect(pvar v, entry* e);
public: public:
viable(solver& s); viable(solver& s);
@ -64,7 +64,7 @@ namespace polysat {
* update state of viable for pvar v * update state of viable for pvar v
* based on affine constraints * based on affine constraints
*/ */
void intersect(pvar v, signed_constraint const& c); bool intersect(pvar v, signed_constraint const& c);
/** /**
* Check whether variable v has any viable values left according to m_viable. * Check whether variable v has any viable values left according to m_viable.