mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 11:25:51 +00:00
running updates to bv_solver (#4674)
* na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * dbg Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * bv Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * drat and fresh Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * move ackerman functionality Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * towards debugability Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * missing file Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove csp Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
4d1a2a2784
commit
d02b0cde7a
63 changed files with 3060 additions and 3095 deletions
153
src/sat/smt/bv_ackerman.cpp
Normal file
153
src/sat/smt/bv_ackerman.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*++
|
||||
Copyright (c) 2020 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
bv_ackerman.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Ackerman reduction plugin for bit-vectors
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2020-08-28
|
||||
|
||||
--*/
|
||||
|
||||
#include "sat/smt/bv_solver.h"
|
||||
#include "sat/smt/bv_ackerman.h"
|
||||
|
||||
namespace bv {
|
||||
|
||||
ackerman::ackerman(solver& s): s(s) {
|
||||
new_tmp();
|
||||
m_propagate_low_watermark = s.get_config().m_dack_threshold;
|
||||
}
|
||||
|
||||
ackerman::~ackerman() {
|
||||
reset();
|
||||
dealloc(m_tmp_vv);
|
||||
}
|
||||
|
||||
void ackerman::reset() {
|
||||
m_table.reset();
|
||||
m_queue = nullptr;
|
||||
}
|
||||
|
||||
void ackerman::used_eq_eh(euf::theory_var v1, euf::theory_var v2) {
|
||||
if (v1 == v2)
|
||||
return;
|
||||
if (v1 > v2)
|
||||
std::swap(v1, v2);
|
||||
vv* n = m_tmp_vv;
|
||||
n->v1 = v1;
|
||||
n->v2 = v2;
|
||||
vv* other = m_table.insert_if_not_there(n);
|
||||
other->m_count++;
|
||||
update_glue(*other);
|
||||
if (other->m_count > m_propagate_high_watermark || other->m_glue == 0)
|
||||
s.s().set_should_simplify();
|
||||
vv::push_to_front(m_queue, other);
|
||||
if (other == n) {
|
||||
new_tmp();
|
||||
gc();
|
||||
}
|
||||
}
|
||||
|
||||
void ackerman::update_glue(vv& v) {
|
||||
unsigned sz = s.m_bits[v.v1].size();
|
||||
m_diff_levels.reserve(s.s().scope_lvl() + 1, false);
|
||||
unsigned glue = 0;
|
||||
unsigned max_glue = v.m_glue;
|
||||
auto const& bitsa = s.m_bits[v.v1];
|
||||
auto const& bitsb = s.m_bits[v.v2];
|
||||
unsigned i = 0;
|
||||
for (; i < sz && i < max_glue; ++i) {
|
||||
sat::literal a = bitsa[i];
|
||||
sat::literal b = bitsb[i];
|
||||
if (a == b)
|
||||
continue;
|
||||
SASSERT(s.s().value(a) != l_undef);
|
||||
SASSERT(s.s().value(b) == s.s().value(a));
|
||||
unsigned lvl_a = s.s().lvl(a);
|
||||
unsigned lvl_b = s.s().lvl(b);
|
||||
if (!m_diff_levels[lvl_a]) {
|
||||
m_diff_levels[lvl_a] = true;
|
||||
++glue;
|
||||
}
|
||||
if (!m_diff_levels[lvl_b]) {
|
||||
m_diff_levels[lvl_b] = true;
|
||||
++glue;
|
||||
}
|
||||
}
|
||||
for (; i-- > 0; ) {
|
||||
sat::literal a = bitsa[i];
|
||||
sat::literal b = bitsb[i];
|
||||
if (a != b) {
|
||||
m_diff_levels[s.s().lvl(a)] = false;
|
||||
m_diff_levels[s.s().lvl(b)] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (glue < max_glue)
|
||||
v.m_glue = glue <= sz ? 0 : glue;
|
||||
}
|
||||
|
||||
void ackerman::remove(vv* p) {
|
||||
vv::remove_from(m_queue, p);
|
||||
m_table.erase(p);
|
||||
dealloc(p);
|
||||
}
|
||||
|
||||
void ackerman::new_tmp() {
|
||||
m_tmp_vv = alloc(vv);
|
||||
m_tmp_vv->init(m_tmp_vv);
|
||||
m_tmp_vv->m_count = 0;
|
||||
m_tmp_vv->m_glue = UINT_MAX;
|
||||
}
|
||||
|
||||
void ackerman::gc() {
|
||||
m_num_propagations_since_last_gc++;
|
||||
if (m_num_propagations_since_last_gc <= s.get_config().m_dack_gc)
|
||||
return;
|
||||
m_num_propagations_since_last_gc = 0;
|
||||
|
||||
while (m_table.size() > m_gc_threshold)
|
||||
remove(m_queue->prev());
|
||||
|
||||
m_gc_threshold *= 110;
|
||||
m_gc_threshold /= 100;
|
||||
m_gc_threshold++;
|
||||
}
|
||||
|
||||
void ackerman::propagate() {
|
||||
SASSERT(s.s().at_base_lvl());
|
||||
auto* n = m_queue;
|
||||
vv* k = nullptr;
|
||||
unsigned num_prop = static_cast<unsigned>(s.s().get_stats().m_conflict * s.get_config().m_dack_factor);
|
||||
num_prop = std::min(num_prop, m_table.size());
|
||||
for (unsigned i = 0; i < num_prop; ++i, n = k) {
|
||||
k = n->next();
|
||||
if (n->m_count < m_propagate_low_watermark && n->m_glue != 0)
|
||||
continue;
|
||||
add_cc(n->v1, n->v2);
|
||||
remove(n);
|
||||
}
|
||||
}
|
||||
|
||||
void ackerman::add_cc(euf::theory_var v1, euf::theory_var v2) {
|
||||
SASSERT(v1 < v2);
|
||||
if (static_cast<unsigned>(v2) >= s.get_num_vars())
|
||||
return;
|
||||
if (!s.var2enode(v1) || !s.var2enode(v2))
|
||||
return;
|
||||
sort* s1 = s.m.get_sort(s.var2expr(v1));
|
||||
sort* s2 = s.m.get_sort(s.var2expr(v2));
|
||||
if (s1 != s2 || !s.bv.is_bv_sort(s1))
|
||||
return;
|
||||
IF_VERBOSE(0, verbose_stream() << "assert ackerman " << v1 << " " << v2 << "\n");
|
||||
s.assert_ackerman(v1, v2);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue