mirror of
https://github.com/Z3Prover/z3
synced 2025-06-27 08:28:44 +00:00
integrate lookahead v1 into repair loop
this ports some functionality from lookahead solver for qfbv-sls into sls-smt.
This commit is contained in:
parent
c58171478f
commit
5eb71c3be6
9 changed files with 214 additions and 104 deletions
|
@ -21,7 +21,6 @@ Notes:
|
||||||
#include "util/stopwatch.h"
|
#include "util/stopwatch.h"
|
||||||
#include "util/lbool.h"
|
#include "util/lbool.h"
|
||||||
#include "ast/converters/model_converter.h"
|
#include "ast/converters/model_converter.h"
|
||||||
|
|
||||||
#include "ast/sls/sls_stats.h"
|
#include "ast/sls/sls_stats.h"
|
||||||
#include "ast/sls/sls_bv_tracker.h"
|
#include "ast/sls/sls_bv_tracker.h"
|
||||||
#include "ast/sls/sls_bv_evaluator.h"
|
#include "ast/sls/sls_bv_evaluator.h"
|
||||||
|
@ -79,8 +78,6 @@ public:
|
||||||
void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted);
|
void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted);
|
||||||
void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped);
|
void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lbool search();
|
lbool search();
|
||||||
|
|
||||||
lbool search_loop();
|
lbool search_loop();
|
||||||
|
|
|
@ -88,7 +88,6 @@ namespace sls {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bv_eval::init_eval_bv(app* e) {
|
void bv_eval::init_eval_bv(app* e) {
|
||||||
if (bv.is_bv(e))
|
if (bv.is_bv(e))
|
||||||
eval(e).commit_eval();
|
eval(e).commit_eval();
|
||||||
|
@ -99,7 +98,7 @@ namespace sls {
|
||||||
if (m.is_eq(e, x, y))
|
if (m.is_eq(e, x, y))
|
||||||
return bv.is_bv(x);
|
return bv.is_bv(x);
|
||||||
if (m.is_ite(e))
|
if (m.is_ite(e))
|
||||||
return bv.is_bv(e->get_arg(0));
|
return bv.is_bv(e->get_arg(1));
|
||||||
if (e->get_family_id() == bv.get_fid()) {
|
if (e->get_family_id() == bv.get_fid()) {
|
||||||
switch (e->get_decl_kind()) {
|
switch (e->get_decl_kind()) {
|
||||||
case OP_BNEG_OVFL:
|
case OP_BNEG_OVFL:
|
||||||
|
@ -680,6 +679,8 @@ namespace sls {
|
||||||
expr* arg = e->get_arg(i);
|
expr* arg = e->get_arg(i);
|
||||||
if (m.is_value(arg))
|
if (m.is_value(arg))
|
||||||
return false;
|
return false;
|
||||||
|
if (m.is_bool(e) && false && m_rand(10) == 0 && m_lookahead.try_repair_down(e))
|
||||||
|
return true;
|
||||||
if (e->get_family_id() == bv.get_family_id() && try_repair_bv(e, i)) {
|
if (e->get_family_id() == bv.get_family_id() && try_repair_bv(e, i)) {
|
||||||
commit_eval(e, to_app(arg));
|
commit_eval(e, to_app(arg));
|
||||||
IF_VERBOSE(11, verbose_stream() << "repair " << mk_bounded_pp(e, m) << " : " << mk_bounded_pp(arg, m) << " := " << wval(arg) << "\n";);
|
IF_VERBOSE(11, verbose_stream() << "repair " << mk_bounded_pp(e, m) << " : " << mk_bounded_pp(arg, m) << " := " << wval(arg) << "\n";);
|
||||||
|
@ -692,9 +693,9 @@ namespace sls {
|
||||||
ctx.new_value_eh(arg);
|
ctx.new_value_eh(arg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (m.is_eq(e) && bv.is_bv(arg)) {
|
if (m.is_bool(e) && m_lookahead.try_repair_down(e))
|
||||||
return try_repair_eq_lookahead(e);
|
return true;
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,37 +883,9 @@ namespace sls {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bv_eval::try_repair_eq_lookahead(app* e) {
|
|
||||||
return m_lookahead.try_repair_down(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bv_eval::try_repair_eq(bool is_true, bvval& a, bvval const& b) {
|
bool bv_eval::try_repair_eq(bool is_true, bvval& a, bvval const& b) {
|
||||||
if (is_true) {
|
if (is_true) {
|
||||||
#if 0
|
return (m_rand(20) != 0 && a.try_set(b.bits())) || a.set_random(m_rand);
|
||||||
if (bv.is_bv_add(t)) {
|
|
||||||
bvval tmp(b);
|
|
||||||
unsigned start = m_rand();
|
|
||||||
unsigned sz = to_app(t)->get_num_args();
|
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
|
||||||
unsigned j = (start + i) % sz;
|
|
||||||
for (unsigned k = 0; k < sz; ++k) {
|
|
||||||
if (k == j)
|
|
||||||
continue;
|
|
||||||
auto& c = wval(to_app(t)->get_arg(k));
|
|
||||||
set_sub(tmp, tmp, c.bits());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& c = wval(to_app(t)->get_arg(j));
|
|
||||||
verbose_stream() << "TRY " << c << " := " << tmp << "\n";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (m_rand(20) != 0 && a.try_set(b.bits()))
|
|
||||||
return true;
|
|
||||||
return a.set_random(m_rand);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bool try_above = m_rand(2) == 0;
|
bool try_above = m_rand(2) == 0;
|
||||||
|
|
|
@ -121,7 +121,6 @@ namespace sls {
|
||||||
bool try_repair_comp(bvect const& e, bvval& a, bvval& b, unsigned i);
|
bool try_repair_comp(bvect const& e, bvval& a, bvval& b, unsigned i);
|
||||||
bool try_repair_eq(bool is_true, bvval& a, bvval const& b);
|
bool try_repair_eq(bool is_true, bvval& a, bvval const& b);
|
||||||
bool try_repair_eq(app* e, unsigned i);
|
bool try_repair_eq(app* e, unsigned i);
|
||||||
bool try_repair_eq_lookahead(app* e);
|
|
||||||
bool try_repair_int2bv(bvect const& e, expr* arg);
|
bool try_repair_int2bv(bvect const& e, expr* arg);
|
||||||
void add_p2_1(bvval const& a, bool use_current, bvect& t) const;
|
void add_p2_1(bvval const& a, bool use_current, bvect& t) const;
|
||||||
|
|
||||||
|
|
|
@ -451,25 +451,34 @@ public:
|
||||||
case OP_BLSHR: {
|
case OP_BLSHR: {
|
||||||
SASSERT(n_args == 2);
|
SASSERT(n_args == 2);
|
||||||
m_mpz_manager.set(result, m_tracker.get_value(args[0]));
|
m_mpz_manager.set(result, m_tracker.get_value(args[0]));
|
||||||
mpz shift; m_mpz_manager.set(shift, m_tracker.get_value(args[1]));
|
auto const& shift = m_tracker.get_value(args[1]);
|
||||||
while (!m_mpz_manager.is_zero(shift)) {
|
if (m_mpz_manager.is_small(shift)) {
|
||||||
m_mpz_manager.machine_div(result, m_two, result);
|
int s = m_mpz_manager.get_int(shift);
|
||||||
m_mpz_manager.dec(shift);
|
SASSERT(s >= 0);
|
||||||
|
m_mpz_manager.machine_div2k(result, s);
|
||||||
}
|
}
|
||||||
m_mpz_manager.del(shift);
|
else
|
||||||
|
m_mpz_manager.set(result, m_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_BSHL: {
|
case OP_BSHL: {
|
||||||
SASSERT(n_args == 2);
|
SASSERT(n_args == 2);
|
||||||
m_mpz_manager.set(result, m_tracker.get_value(args[0]));
|
m_mpz_manager.set(result, m_tracker.get_value(args[0]));
|
||||||
mpz shift; m_mpz_manager.set(shift, m_tracker.get_value(args[1]));
|
auto const& shift = m_tracker.get_value(args[1]);
|
||||||
while (!m_mpz_manager.is_zero(shift)) {
|
if (m_mpz_manager.is_small(shift)) {
|
||||||
m_mpz_manager.mul(result, m_two, result);
|
int s = m_mpz_manager.get_int(shift);
|
||||||
m_mpz_manager.dec(shift);
|
SASSERT(s >= 0);
|
||||||
}
|
int sz = m_bv_util.get_bv_size(n);
|
||||||
const mpz & p = m_powers(m_bv_util.get_bv_size(n));
|
if (s >= sz)
|
||||||
|
m_mpz_manager.set(result, m_zero);
|
||||||
|
else {
|
||||||
|
m_mpz_manager.mul2k(result, s);
|
||||||
|
const mpz& p = m_powers(sz);
|
||||||
m_mpz_manager.rem(result, p, result);
|
m_mpz_manager.rem(result, p, result);
|
||||||
m_mpz_manager.del(shift);
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_mpz_manager.set(result, m_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_SIGN_EXT: {
|
case OP_SIGN_EXT: {
|
||||||
|
|
|
@ -18,45 +18,43 @@ Author:
|
||||||
#include "ast/sls/sls_bv_lookahead.h"
|
#include "ast/sls/sls_bv_lookahead.h"
|
||||||
#include "ast/sls/sls_bv_eval.h"
|
#include "ast/sls/sls_bv_eval.h"
|
||||||
#include "ast/sls/sls_bv_terms.h"
|
#include "ast/sls/sls_bv_terms.h"
|
||||||
|
#include "ast/ast_pp.h"
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
|
|
||||||
bv_lookahead::bv_lookahead(bv_eval& ev) :
|
bv_lookahead::bv_lookahead(bv_eval& ev) :
|
||||||
bv(ev.bv),
|
bv(ev.m),
|
||||||
m_ev(ev),
|
m_ev(ev),
|
||||||
ctx(ev.ctx),
|
ctx(ev.ctx),
|
||||||
m(ev.m) {}
|
m(ev.m) {}
|
||||||
|
|
||||||
bool bv_lookahead::try_repair_down(expr* e) {
|
bool bv_lookahead::try_repair_down(app* e) {
|
||||||
return false;
|
if (!m.is_bool(e))
|
||||||
auto is_true = m_ev.bval0(e);
|
|
||||||
if (!is_true)
|
|
||||||
return false;
|
return false;
|
||||||
|
if (m_ev.bval1(e) == m_ev.bval0(e))
|
||||||
|
return true;
|
||||||
auto const& uninterp = m_ev.terms.uninterp_occurs(e);
|
auto const& uninterp = m_ev.terms.uninterp_occurs(e);
|
||||||
if (uninterp.empty())
|
if (uninterp.empty())
|
||||||
return false;
|
return false;
|
||||||
// for (auto e : uninterp)
|
reset_updates();
|
||||||
// verbose_stream() << mk_bounded_pp(e, m) << " ";
|
|
||||||
// verbose_stream() << "\n";
|
|
||||||
|
|
||||||
expr* t = uninterp[m_ev.m_rand() % uninterp.size()];
|
IF_VERBOSE(4,
|
||||||
|
verbose_stream() << mk_bounded_pp(e, m) << "\n";
|
||||||
|
for (auto e : uninterp)
|
||||||
|
verbose_stream() << mk_bounded_pp(e, m) << " ";
|
||||||
|
verbose_stream() << "\n");
|
||||||
|
|
||||||
auto& v = wval(t);
|
for (auto e : uninterp)
|
||||||
if (v.set_random(m_ev.m_rand)) {
|
add_updates(e);
|
||||||
//verbose_stream() << "set random " << mk_bounded_pp(t, m) << "\n";
|
|
||||||
ctx.new_value_eh(t);
|
#if 0
|
||||||
return true;
|
for (unsigned i = 0; i < m_num_updates; ++i) {
|
||||||
|
auto const& [e, score, new_value] = m_updates[i];
|
||||||
|
verbose_stream() << mk_bounded_pp(e, m) << " " << new_value << " score: " << score << "\n";
|
||||||
}
|
}
|
||||||
return false;
|
#endif
|
||||||
|
|
||||||
|
return apply_update();
|
||||||
for (auto e : uninterp) {
|
|
||||||
auto& v = wval(e);
|
|
||||||
v.get_variant(m_ev.m_tmp, m_ev.m_rand);
|
|
||||||
auto d = lookahead(e, m_ev.m_tmp);
|
|
||||||
//verbose_stream() << mk_bounded_pp(e, m) << " " << d << "\n";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double bv_lookahead::lookahead(expr* e, bvect const& new_value) {
|
double bv_lookahead::lookahead(expr* e, bvect const& new_value) {
|
||||||
|
@ -76,7 +74,7 @@ namespace sls {
|
||||||
unsigned max_depth = get_depth(e);
|
unsigned max_depth = get_depth(e);
|
||||||
for (unsigned depth = max_depth; depth <= max_depth; ++depth) {
|
for (unsigned depth = max_depth; depth <= max_depth; ++depth) {
|
||||||
for (unsigned i = 0; !has_tabu && i < m_update_stack[depth].size(); ++i) {
|
for (unsigned i = 0; !has_tabu && i < m_update_stack[depth].size(); ++i) {
|
||||||
e = m_update_stack[depth][i];
|
auto e = m_update_stack[depth][i];
|
||||||
if (bv.is_bv(e)) {
|
if (bv.is_bv(e)) {
|
||||||
auto& v = m_ev.eval(to_app(e));
|
auto& v = m_ev.eval(to_app(e));
|
||||||
if (insert_update(e)) {
|
if (insert_update(e)) {
|
||||||
|
@ -89,24 +87,133 @@ namespace sls {
|
||||||
has_tabu = true;
|
has_tabu = true;
|
||||||
}
|
}
|
||||||
else if (m.is_bool(e) && m_ev.can_eval1(to_app(e))) {
|
else if (m.is_bool(e) && m_ev.can_eval1(to_app(e))) {
|
||||||
|
if (!ctx.is_relevant(e))
|
||||||
|
continue;
|
||||||
bool is_true = ctx.is_true(e);
|
bool is_true = ctx.is_true(e);
|
||||||
bool is_true_new = m_ev.bval1(to_app(e));
|
bool is_true_new = m_ev.bval1(to_app(e));
|
||||||
bool is_true_old = m_ev.bval1_tmp(to_app(e));
|
bool is_true_old = m_ev.bval1_tmp(to_app(e));
|
||||||
// verbose_stream() << "parent " << mk_bounded_pp(e, m) << " " << is_true << " " << is_true_new << " " << is_true_old << "\n";
|
if (is_true_new == is_true_old)
|
||||||
if (is_true == is_true_new && is_true_new != is_true_old)
|
continue;
|
||||||
|
if (is_true == is_true_new)
|
||||||
++make_count;
|
++make_count;
|
||||||
if (is_true == is_true_old && is_true_new != is_true_old)
|
if (is_true == is_true_old)
|
||||||
++break_count;
|
++break_count;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
IF_VERBOSE(1, verbose_stream() << "skipping " << mk_bounded_pp(e, m) << "\n");
|
||||||
|
has_tabu = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_update_stack[depth].reset();
|
m_update_stack[depth].reset();
|
||||||
}
|
}
|
||||||
restore_lookahead();
|
restore_lookahead();
|
||||||
|
// verbose_stream() << has_tabu << " " << new_value << " " << make_count << " " << break_count << "\n";
|
||||||
|
|
||||||
if (has_tabu)
|
if (has_tabu)
|
||||||
return -10000;
|
return -10000;
|
||||||
return make_count - break_count;
|
return make_count - break_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bv_lookahead::try_set(expr* e, bvect const& new_value) {
|
||||||
|
if (!wval(e).can_set(new_value))
|
||||||
|
return;
|
||||||
|
auto d = lookahead(e, new_value);
|
||||||
|
if (d > 0)
|
||||||
|
add_update(d, e, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bv_lookahead::add_updates(expr* e) {
|
||||||
|
SASSERT(bv.is_bv(e));
|
||||||
|
auto& v = wval(e);
|
||||||
|
double d = 0;
|
||||||
|
while (m_v_saved.size() < v.bits().size()) {
|
||||||
|
m_v_saved.push_back(0);
|
||||||
|
m_v_updated.push_back(0);
|
||||||
|
}
|
||||||
|
m_v_saved.set_bw(v.bw);
|
||||||
|
m_v_updated.set_bw(v.bw);
|
||||||
|
v.bits().copy_to(v.nw, m_v_saved);
|
||||||
|
m_v_saved.copy_to(v.nw, m_v_updated);
|
||||||
|
|
||||||
|
// flip a single bit
|
||||||
|
for (unsigned i = 0; i < v.bw; ++i) {
|
||||||
|
m_v_updated.set(i, !m_v_updated.get(i));
|
||||||
|
try_set(e, m_v_updated);
|
||||||
|
//verbose_stream() << "flip " << d << " " << m_v_updated << "\n";
|
||||||
|
m_v_updated.set(i, !m_v_updated.get(i));
|
||||||
|
}
|
||||||
|
if (v.bw <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// invert
|
||||||
|
for (unsigned i = 0; i < v.nw; ++i)
|
||||||
|
m_v_updated[i] = ~m_v_updated[i];
|
||||||
|
v.clear_overflow_bits(m_v_updated);
|
||||||
|
try_set(e, m_v_updated);
|
||||||
|
|
||||||
|
// increment
|
||||||
|
m_v_saved.copy_to(v.nw, m_v_updated);
|
||||||
|
v.add1(m_v_updated);
|
||||||
|
try_set(e, m_v_updated);
|
||||||
|
|
||||||
|
// decrement
|
||||||
|
m_v_saved.copy_to(v.nw, m_v_updated);
|
||||||
|
v.sub1(m_v_updated);
|
||||||
|
try_set(e, m_v_updated);
|
||||||
|
|
||||||
|
// random
|
||||||
|
v.get_variant(m_v_updated, m_ev.m_rand);
|
||||||
|
try_set(e, m_v_updated);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bv_lookahead::apply_update() {
|
||||||
|
double sum_score = 0;
|
||||||
|
for (unsigned i = 0; i < m_num_updates; ++i)
|
||||||
|
sum_score += m_updates[i].score;
|
||||||
|
double pos = (sum_score * m_ev.m_rand()) / (double)m_ev.m_rand.max_value();
|
||||||
|
for (unsigned i = 0; i < m_num_updates; ++i) {
|
||||||
|
auto const& [e, score, new_value] = m_updates[i];
|
||||||
|
pos -= score;
|
||||||
|
if (pos <= 0) {
|
||||||
|
//verbose_stream() << "apply " << mk_bounded_pp(e, m) << " new value " << new_value << " " << score << "\n";
|
||||||
|
apply_update(e, new_value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bv_lookahead::apply_update(expr* e, bvect const& new_value) {
|
||||||
|
SASSERT(bv.is_bv(e));
|
||||||
|
SASSERT(is_uninterp(e));
|
||||||
|
SASSERT(m_restore.empty());
|
||||||
|
wval(e).eval = new_value;
|
||||||
|
VERIFY(wval(e).commit_eval());
|
||||||
|
insert_update_stack(e);
|
||||||
|
unsigned max_depth = get_depth(e);
|
||||||
|
for (unsigned depth = max_depth; depth <= max_depth; ++depth) {
|
||||||
|
for (unsigned i = 0; i < m_update_stack[depth].size(); ++i) {
|
||||||
|
auto e = m_update_stack[depth][i];
|
||||||
|
if (bv.is_bv(e)) {
|
||||||
|
m_ev.eval(to_app(e)); // updates wval(e).eval
|
||||||
|
VERIFY(wval(e).commit_eval());
|
||||||
|
for (auto p : ctx.parents(e)) {
|
||||||
|
insert_update_stack(p);
|
||||||
|
max_depth = std::max(max_depth, get_depth(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m.is_bool(e) && m_ev.can_eval1(to_app(e))) {
|
||||||
|
VERIFY(m_ev.repair_up(e));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_update_stack[depth].reset();
|
||||||
|
}
|
||||||
|
m_in_update_stack.reset();
|
||||||
|
}
|
||||||
|
|
||||||
bool bv_lookahead::insert_update(expr* e) {
|
bool bv_lookahead::insert_update(expr* e) {
|
||||||
m_restore.push_back(e);
|
m_restore.push_back(e);
|
||||||
m_on_restore.mark(e);
|
m_on_restore.mark(e);
|
||||||
|
@ -118,15 +225,18 @@ namespace sls {
|
||||||
void bv_lookahead::insert_update_stack(expr* e) {
|
void bv_lookahead::insert_update_stack(expr* e) {
|
||||||
unsigned depth = get_depth(e);
|
unsigned depth = get_depth(e);
|
||||||
m_update_stack.reserve(depth + 1);
|
m_update_stack.reserve(depth + 1);
|
||||||
if (!m_update_stack[depth].contains(e))
|
if (!m_in_update_stack.is_marked(e)) {
|
||||||
|
m_in_update_stack.mark(e);
|
||||||
m_update_stack[depth].push_back(e);
|
m_update_stack[depth].push_back(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bv_lookahead::restore_lookahead() {
|
void bv_lookahead::restore_lookahead() {
|
||||||
for (auto e : m_restore)
|
for (auto e : m_restore)
|
||||||
wval(e).restore_value();
|
wval(e).restore_value();
|
||||||
m_restore.reset();
|
m_restore.reset();
|
||||||
m_on_restore.reset();
|
m_on_restore.reset();
|
||||||
|
m_in_update_stack.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
sls::bv_valuation& bv_lookahead::wval(expr* e) const {
|
sls::bv_valuation& bv_lookahead::wval(expr* e) const {
|
||||||
|
|
|
@ -18,36 +18,60 @@ Author:
|
||||||
|
|
||||||
#include "ast/bv_decl_plugin.h"
|
#include "ast/bv_decl_plugin.h"
|
||||||
#include "ast/sls/sls_context.h"
|
#include "ast/sls/sls_context.h"
|
||||||
|
#include "ast/sls/sls_bv_valuation.h"
|
||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
class bv_eval;
|
class bv_eval;
|
||||||
class bv_valuation;
|
|
||||||
class bvect;
|
|
||||||
|
|
||||||
class bv_lookahead {
|
class bv_lookahead {
|
||||||
bv_util bv;
|
bv_util bv;
|
||||||
bv_eval& m_ev;
|
bv_eval& m_ev;
|
||||||
context& ctx;
|
context& ctx;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
|
bvect m_v_saved, m_v_updated;
|
||||||
|
|
||||||
ptr_vector<expr> m_restore;
|
ptr_vector<expr> m_restore;
|
||||||
vector<ptr_vector<expr>> m_update_stack;
|
vector<ptr_vector<expr>> m_update_stack;
|
||||||
expr_mark m_on_restore;
|
expr_mark m_on_restore, m_in_update_stack;
|
||||||
|
struct update {
|
||||||
|
expr* e;
|
||||||
|
double score;
|
||||||
|
bvect value;
|
||||||
|
};
|
||||||
|
vector<update> m_updates;
|
||||||
|
unsigned m_num_updates = 0;
|
||||||
|
void reset_updates() { m_num_updates = 0; }
|
||||||
|
void add_update(double score, expr* e, bvect const& value) {
|
||||||
|
if (m_num_updates == m_updates.size())
|
||||||
|
m_updates.push_back({ e, score, value });
|
||||||
|
else {
|
||||||
|
auto& u = m_updates[m_num_updates];
|
||||||
|
u.e = e;
|
||||||
|
u.score = score;
|
||||||
|
u.value = value;
|
||||||
|
}
|
||||||
|
m_num_updates++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bv_valuation& wval(expr* e) const;
|
bv_valuation& wval(expr* e) const;
|
||||||
|
|
||||||
void insert_update_stack(expr* e);
|
void insert_update_stack(expr* e);
|
||||||
bool insert_update(expr* e);
|
bool insert_update(expr* e);
|
||||||
|
|
||||||
void restore_lookahead();
|
void restore_lookahead();
|
||||||
|
|
||||||
double lookahead(expr* e, bvect const& new_value);
|
double lookahead(expr* e, bvect const& new_value);
|
||||||
|
|
||||||
|
void try_set(expr* e, bvect const& new_value);
|
||||||
|
void add_updates(expr* e);
|
||||||
|
void apply_update(expr* e, bvect const& new_value);
|
||||||
|
bool apply_update();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bv_lookahead(bv_eval& ev);
|
bv_lookahead(bv_eval& ev);
|
||||||
bool on_restore(expr* e) const;
|
bool on_restore(expr* e) const;
|
||||||
|
|
||||||
bool try_repair_down(expr* e);
|
bool try_repair_down(app* e);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -127,6 +127,7 @@ namespace sls {
|
||||||
ptr_vector<expr> todo;
|
ptr_vector<expr> todo;
|
||||||
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
||||||
expr_mark marked;
|
expr_mark marked;
|
||||||
|
expr* c, * th, * el;
|
||||||
for (unsigned i = 0; i < todo.size(); ++i) {
|
for (unsigned i = 0; i < todo.size(); ++i) {
|
||||||
e = todo[i];
|
e = todo[i];
|
||||||
if (marked.is_marked(e))
|
if (marked.is_marked(e))
|
||||||
|
@ -136,6 +137,10 @@ namespace sls {
|
||||||
for (expr* arg : *to_app(e))
|
for (expr* arg : *to_app(e))
|
||||||
todo.push_back(arg);
|
todo.push_back(arg);
|
||||||
}
|
}
|
||||||
|
else if (m.is_ite(e, c, th, el)) {
|
||||||
|
todo.push_back(th);
|
||||||
|
todo.push_back(el);
|
||||||
|
}
|
||||||
else if (bv.is_bv(e))
|
else if (bv.is_bv(e))
|
||||||
occs.push_back(e);
|
occs.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,21 @@
|
||||||
namespace bv {
|
namespace bv {
|
||||||
class sls_stats {
|
class sls_stats {
|
||||||
public:
|
public:
|
||||||
unsigned m_restarts;
|
unsigned m_restarts = 0;
|
||||||
|
unsigned m_full_evals = 0;
|
||||||
|
unsigned m_incr_evals = 0;
|
||||||
|
unsigned m_moves = 0;
|
||||||
|
unsigned m_flips = 0;
|
||||||
|
unsigned m_incs = 0;
|
||||||
|
unsigned m_decs = 0;
|
||||||
|
unsigned m_invs = 0;
|
||||||
stopwatch m_stopwatch;
|
stopwatch m_stopwatch;
|
||||||
unsigned m_full_evals;
|
|
||||||
unsigned m_incr_evals;
|
|
||||||
unsigned m_moves, m_flips, m_incs, m_decs, m_invs;
|
|
||||||
|
|
||||||
sls_stats() :
|
sls_stats() {
|
||||||
m_restarts(0),
|
|
||||||
m_full_evals(0),
|
|
||||||
m_incr_evals(0),
|
|
||||||
m_moves(0),
|
|
||||||
m_flips(0),
|
|
||||||
m_incs(0),
|
|
||||||
m_decs(0),
|
|
||||||
m_invs(0) {
|
|
||||||
m_stopwatch.reset();
|
m_stopwatch.reset();
|
||||||
m_stopwatch.start();
|
m_stopwatch.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
m_full_evals = m_flips = m_incr_evals = 0;
|
m_full_evals = m_flips = m_incr_evals = 0;
|
||||||
m_stopwatch.reset();
|
m_stopwatch.reset();
|
||||||
|
@ -44,7 +41,6 @@ namespace bv {
|
||||||
st.update("sls DEC moves", m_decs);
|
st.update("sls DEC moves", m_decs);
|
||||||
st.update("sls INV moves", m_invs);
|
st.update("sls INV moves", m_invs);
|
||||||
st.update("sls moves", m_moves);
|
st.update("sls moves", m_moves);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -213,9 +213,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() override {
|
void cleanup() override {
|
||||||
sls_engine * d = alloc(sls_engine, m, m_params);
|
|
||||||
std::swap(d, m_engine);
|
|
||||||
dealloc(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_statistics(statistics & st) const override {
|
void collect_statistics(statistics & st) const override {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue