mirror of
https://github.com/Z3Prover/z3
synced 2025-08-04 10:20:23 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
c9f5ce43b2
commit
5708de4301
3 changed files with 68 additions and 23 deletions
|
@ -33,34 +33,45 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void viable2::intersect(pvar v, signed_constraint const& c) {
|
void viable2::intersect(pvar v, signed_constraint const& c) {
|
||||||
|
entry* e = m_viable[v];
|
||||||
|
if (e && e->interval.is_full())
|
||||||
|
return;
|
||||||
|
|
||||||
auto& fi = s.m_forbidden_intervals;
|
auto& fi = s.m_forbidden_intervals;
|
||||||
fi_record r = { eval_interval::full(), {}, c };
|
fi_record r = { eval_interval::full(), {}, c };
|
||||||
if (!fi.get_interval(c, v, r.interval, r.side_cond))
|
if (!fi.get_interval(c, v, r.interval, r.side_cond))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
entry* ne = alloc(entry);
|
auto create_entry = [&]() {
|
||||||
*static_cast<fi_record*>(ne) = r;
|
entry* ne = alloc(entry);
|
||||||
ne->init(ne);
|
*static_cast<fi_record*>(ne) = r;
|
||||||
m_trail.push_back({ v, ne });
|
ne->init(ne);
|
||||||
s.m_trail.push_back(trail_instr_t::viable_i);
|
m_trail.push_back({ v, ne });
|
||||||
|
s.m_trail.push_back(trail_instr_t::viable_i);
|
||||||
|
return ne;
|
||||||
|
};
|
||||||
|
|
||||||
entry* e = m_viable[v];
|
|
||||||
if (!e)
|
if (!e)
|
||||||
m_viable[v] = ne;
|
m_viable[v] = create_entry();
|
||||||
else {
|
else {
|
||||||
entry* first = e;
|
entry* first = e;
|
||||||
do {
|
do {
|
||||||
// TODO: keep track of subsumption
|
if (e->interval.lo_val() == r.interval.lo_val() &&
|
||||||
|
e->interval.current_len() >= r.interval.current_len())
|
||||||
|
return;
|
||||||
if (e->interval.lo_val() >= r.interval.lo_val()) {
|
if (e->interval.lo_val() >= r.interval.lo_val()) {
|
||||||
e->insert(ne);
|
e->insert_before(create_entry());
|
||||||
|
if (e == first)
|
||||||
|
m_viable[v] = e->prev();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
while (e != first);
|
while (e != first);
|
||||||
|
// otherwise, append to end of list
|
||||||
|
first->insert_before(create_entry());
|
||||||
}
|
}
|
||||||
// otherwise, append to end of list
|
SASSERT(is_sorted(m_viable[v]));
|
||||||
e->prev()->insert(ne);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool viable2::has_viable(pvar v) {
|
bool viable2::has_viable(pvar v) {
|
||||||
|
@ -70,15 +81,17 @@ namespace polysat {
|
||||||
entry* first = e;
|
entry* first = e;
|
||||||
rational lo(0);
|
rational lo(0);
|
||||||
do {
|
do {
|
||||||
if (e->interval.lo_val() <= lo && lo < e->interval.hi_val()) {
|
if (e->interval.is_full())
|
||||||
lo = e->interval.hi_val();
|
return false;
|
||||||
e = e->next();
|
if (!e->interval.currently_contains(lo))
|
||||||
continue;
|
return true;
|
||||||
}
|
lo = e->interval.hi_val();
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
while (e != first);
|
while (e != first);
|
||||||
return true;
|
// ???
|
||||||
|
return !first->prev()->interval.currently_contains(lo) &&
|
||||||
|
first->interval.hi_val() <= lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool viable2::is_viable(pvar v, rational const& val) {
|
bool viable2::is_viable(pvar v, rational const& val) {
|
||||||
|
@ -113,7 +126,7 @@ namespace polysat {
|
||||||
if (!e)
|
if (!e)
|
||||||
return dd::find_t::multiple;
|
return dd::find_t::multiple;
|
||||||
|
|
||||||
|
// TODO
|
||||||
entry* first = e;
|
entry* first = e;
|
||||||
do {
|
do {
|
||||||
if (e->interval.is_full())
|
if (e->interval.is_full())
|
||||||
|
@ -129,10 +142,14 @@ namespace polysat {
|
||||||
|
|
||||||
void viable2::log(pvar v) {
|
void viable2::log(pvar v) {
|
||||||
auto* e = m_viable[v];
|
auto* e = m_viable[v];
|
||||||
#if 0
|
if (!e)
|
||||||
for (auto const& [i, conds, c] : *s)
|
return;
|
||||||
LOG("v" << v << ": " << i);
|
entry* first = e;
|
||||||
#endif
|
do {
|
||||||
|
LOG("v" << v << ": " << e->interval << " " << e->side_cond << " " << e->src);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
while (e != first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void viable2::log() {
|
void viable2::log() {
|
||||||
|
@ -140,6 +157,24 @@ namespace polysat {
|
||||||
log(v);
|
log(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool viable2::is_sorted(entry* e) {
|
||||||
|
entry* first = e;
|
||||||
|
while (true) {
|
||||||
|
if (e->interval.is_full())
|
||||||
|
return true;
|
||||||
|
auto* n = e->next();
|
||||||
|
if (n == first)
|
||||||
|
break;
|
||||||
|
if (e->interval.lo_val() > n->interval.lo_val())
|
||||||
|
return false;
|
||||||
|
if (e->interval.lo_val() == n->interval.lo_val() &&
|
||||||
|
e->interval.current_len() > n->interval.current_len())
|
||||||
|
return false;
|
||||||
|
e = n;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ namespace polysat {
|
||||||
ptr_vector<entry> m_viable; // set of viable values.
|
ptr_vector<entry> m_viable; // set of viable values.
|
||||||
svector<std::pair<pvar, entry*>> m_trail; // undo stack
|
svector<std::pair<pvar, entry*>> m_trail; // undo stack
|
||||||
|
|
||||||
|
bool is_sorted(entry* e);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
viable2(solver& s);
|
viable2(solver& s);
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,21 @@ public:
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(T* elem) {
|
void insert_after(T* elem) {
|
||||||
T* next = this->m_next;
|
T* next = this->m_next;
|
||||||
elem->m_prev = next->m_prev;
|
elem->m_prev = next->m_prev;
|
||||||
elem->m_next = next;
|
elem->m_next = next;
|
||||||
this->m_next = elem;
|
this->m_next = elem;
|
||||||
next->m_prev = elem;
|
next->m_prev = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void insert_before(T* elem) {
|
||||||
|
T* prev = this->m_prev;
|
||||||
|
elem->m_next = prev->m_next;
|
||||||
|
elem->m_prev = prev;
|
||||||
|
prev->m_next = elem;
|
||||||
|
this->m_prev = elem;
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_from(T*& list, T* elem) {
|
static void remove_from(T*& list, T* elem) {
|
||||||
if (list->m_next == list) {
|
if (list->m_next == list) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue