mirror of
https://github.com/Z3Prover/z3
synced 2025-06-21 05:13:39 +00:00
interval
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
adf41c5d02
commit
a4e29ecd7e
4 changed files with 35 additions and 32 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue