3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

enable incremental bit-vector solving

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-09-01 09:48:35 -07:00
parent 0ed38ed59b
commit cc5d719d9e
15 changed files with 208 additions and 55 deletions

View file

@ -173,6 +173,7 @@ namespace sat {
~simplifier();
void insert_todo(bool_var v) { m_elim_todo.insert(v); }
void reset_todo() { m_elim_todo.reset(); }
void operator()(bool learned);

View file

@ -97,7 +97,7 @@ namespace sat {
if (!it2->is_binary_non_learned_clause())
continue;
literal l2 = it2->get_literal();
mk_clause(l, l2);
mk_clause_core(l, l2);
}
}
}
@ -111,7 +111,7 @@ namespace sat {
buffer.reset();
for (unsigned i = 0; i < c.size(); i++)
buffer.push_back(c[i]);
mk_clause(buffer);
mk_clause_core(buffer);
}
}
}
@ -553,7 +553,7 @@ namespace sat {
m_cleaner.dec();
SASSERT(!m_inconsistent);
l = m_trail[m_qhead];
TRACE("sat_propagate", tout << "propagating: " << l << "\n";);
TRACE("sat_propagate", tout << "propagating: " << l << " " << m_justification[l.var()] << "\n";);
m_qhead++;
not_l = ~l;
SASSERT(value(l) == l_true);
@ -881,7 +881,7 @@ namespace sat {
bool solver::check_inconsistent() {
if (inconsistent()) {
if (tracking_assumptions())
if (tracking_assumptions() || !m_user_scope_literals.empty())
resolve_conflict();
return true;
}
@ -919,7 +919,7 @@ namespace sat {
assign(nlit, justification());
}
if (weights) {
if (weights && !inconsistent()) {
if (m_config.m_optimize_model) {
m_wsls.set_soft(num_lits, lits, weights);
}
@ -1033,7 +1033,7 @@ namespace sat {
TRACE("opt", tout << "blocking soft correction set: " << m_blocker << "\n";);
IF_VERBOSE(11, verbose_stream() << "blocking " << m_blocker << "\n";);
pop_to_base_level();
mk_clause(m_blocker);
mk_clause_core(m_blocker);
return false;
}
return true;
@ -1094,7 +1094,7 @@ namespace sat {
}
bool solver::tracking_assumptions() const {
return !m_assumptions.empty();
return !m_assumptions.empty() || !m_user_scope_literals.empty();
}
bool solver::is_assumption(literal l) const {
@ -1648,6 +1648,7 @@ namespace sat {
resolve_conflict_for_unsat_core();
return false;
}
if (m_conflict_lvl == 0) {
return false;
}
@ -2568,16 +2569,10 @@ namespace sat {
void solver::user_push() {
literal lit;
if (m_user_scope_literal_pool.empty()) {
bool_var new_v = mk_var(true, false);
lit = literal(new_v, false);
}
else {
lit = m_user_scope_literal_pool.back();
m_user_scope_literal_pool.pop_back();
}
TRACE("sat", tout << "user_push: " << lit << "\n";);
bool_var new_v = mk_var(true, false);
lit = literal(new_v, false);
m_user_scope_literals.push_back(lit);
TRACE("sat", tout << "user_push: " << lit << "\n";);
}
void solver::gc_lit(clause_vector &clauses, literal lit) {
@ -2608,11 +2603,69 @@ namespace sat {
}
}
bool_var solver::max_var(bool learned, bool_var v) {
m_user_bin_clauses.reset();
collect_bin_clauses(m_user_bin_clauses, learned);
for (unsigned i = 0; i < m_user_bin_clauses.size(); ++i) {
literal l1 = m_user_bin_clauses[i].first;
literal l2 = m_user_bin_clauses[i].second;
if (l1.var() > v) v = l1.var();
if (l2.var() > v) v = l2.var();
}
return v;
}
bool_var solver::max_var(clause_vector& clauses, bool_var v) {
for (unsigned i = 0; i < clauses.size(); ++i) {
clause & c = *(clauses[i]);
literal* it = c.begin();
literal * end = c.end();
for (; it != end; ++it) {
if (it->var() > v) {
v = it->var();
}
}
}
return v;
}
void solver::gc_var(bool_var v) {
if (v > 0) {
bool_var w = max_var(m_learned, v-1);
w = max_var(m_clauses, w);
w = max_var(true, w);
w = max_var(false, w);
for (unsigned i = 0; i < m_trail.size(); ++i) {
if (m_trail[i].var() > w) w = m_trail[i].var();
}
v = std::max(v, w + 1);
}
// v is an index of a variable that does not occur in solver state.
if (v < m_level.size()) {
for (bool_var i = v; i < m_level.size(); ++i) {
m_case_split_queue.del_var_eh(i);
}
m_watches.shrink(2*v);
m_assignment.shrink(2*v);
m_justification.shrink(v);
m_decision.shrink(v);
m_eliminated.shrink(v);
m_external.shrink(v);
m_activity.shrink(v);
m_level.shrink(v);
m_mark.shrink(v);
m_lit_mark.shrink(2*v);
m_phase.shrink(v);
m_prev_phase.shrink(v);
m_assigned_since_gc.shrink(v);
m_simplifier.reset_todo();
}
}
void solver::user_pop(unsigned num_scopes) {
pop_to_base_level();
while (num_scopes > 0) {
literal lit = m_user_scope_literals.back();
m_user_scope_literal_pool.push_back(lit);
m_user_scope_literals.pop_back();
gc_lit(m_learned, lit);
gc_lit(m_clauses, lit);
@ -2620,6 +2673,14 @@ namespace sat {
gc_bin(false, lit);
TRACE("sat", tout << "gc: " << lit << "\n"; display(tout););
--num_scopes;
for (unsigned i = 0; i < m_trail.size(); ++i) {
if (m_trail[i] == lit) {
TRACE("sat", tout << m_trail << "\n";);
unassign_vars(i);
break;
}
}
gc_var(lit.var());
}
}

View file

@ -183,6 +183,9 @@ namespace sat {
protected:
void del_clause(clause & c);
clause * mk_clause_core(unsigned num_lits, literal * lits, bool learned);
void mk_clause_core(literal_vector const& lits) { mk_clause_core(lits.size(), lits.c_ptr()); }
void mk_clause_core(unsigned num_lits, literal * lits) { mk_clause_core(num_lits, lits, false); }
void mk_clause_core(literal l1, literal l2) { literal lits[2] = { l1, l2 }; mk_clause_core(2, lits); }
void mk_bin_clause(literal l1, literal l2, bool learned);
bool propagate_bin_clause(literal l1, literal l2);
clause * mk_ter_clause(literal * lits, bool learned);
@ -400,11 +403,14 @@ namespace sat {
void reinit_clauses(unsigned old_sz);
literal_vector m_user_scope_literals;
literal_vector m_user_scope_literal_pool;
literal_vector m_aux_literals;
svector<bin_clause> m_user_bin_clauses;
void gc_lit(clause_vector& clauses, literal lit);
void gc_bin(bool learned, literal nlit);
void gc_var(bool_var v);
bool_var max_var(clause_vector& clauses, bool_var v);
bool_var max_var(bool learned, bool_var v);
public:
void user_push();
void user_pop(unsigned num_scopes);

View file

@ -31,6 +31,7 @@ Notes:
#include "ast_pp.h"
#include "model_smt2_pp.h"
#include "filter_model_converter.h"
#include "bit_blaster_model_converter.h"
// incremental SAT solver.
class inc_sat_solver : public solver {
@ -48,7 +49,8 @@ class inc_sat_solver : public solver {
expr_ref_vector m_core;
atom2bool_var m_map;
model_ref m_model;
model_converter_ref m_mc;
model_converter_ref m_mc;
bit_blaster_rewriter m_bb_rewriter;
tactic_ref m_preprocess;
unsigned m_num_scopes;
sat::literal_vector m_asms;
@ -67,6 +69,7 @@ public:
m_asmsf(m),
m_fmls_head(0),
m_core(m),
m_bb_rewriter(m, p),
m_map(m),
m_num_scopes(0),
m_dep_core(m) {
@ -84,7 +87,7 @@ public:
and_then(mk_card2bv_tactic(m, m_params),
using_params(mk_simplify_tactic(m), simp2_p),
mk_max_bv_sharing_tactic(m),
mk_bit_blaster_tactic(m),
mk_bit_blaster_tactic(m, &m_bb_rewriter),
mk_aig_tactic(),
using_params(mk_simplify_tactic(m), simp2_p));
}
@ -157,11 +160,15 @@ public:
m_fmls_lim.push_back(m_fmls.size());
m_asms_lim.push_back(m_asmsf.size());
m_fmls_head_lim.push_back(m_fmls_head);
m_bb_rewriter.push();
m_map.push();
}
virtual void pop(unsigned n) {
if (n < m_num_scopes) { // allow inc_sat_solver to
n = m_num_scopes; // take over for another solver.
}
m_bb_rewriter.pop(n);
m_map.pop(n);
SASSERT(n >= m_num_scopes);
m_solver.user_pop(n);
m_num_scopes -= n;
@ -258,11 +265,11 @@ private:
IF_VERBOSE(0, verbose_stream() << "exception in tactic " << ex.msg() << "\n";);
return l_undef;
}
m_mc = concat(m_mc.get(), m_mc2.get());
if (m_subgoals.size() != 1) {
IF_VERBOSE(0, verbose_stream() << "size of subgoals is not 1, it is: " << m_subgoals.size() << "\n";);
return l_undef;
}
CTRACE("sat", m_mc.get(), m_mc->display(tout); );
g = m_subgoals[0];
TRACE("sat", g->display_with_dependencies(tout););
m_goal2sat(*g, m_params, m_solver, m_map, dep2asm, true);
@ -384,8 +391,12 @@ private:
}
}
m_model = md;
if (m_mc) {
(*m_mc)(m_model);
if (m_mc || !m_bb_rewriter.const2bits().empty()) {
model_converter_ref mc = m_mc;
if (!m_bb_rewriter.const2bits().empty()) {
mc = concat(mc.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter.const2bits()));
}
(*mc)(m_model);
}
SASSERT(m_model);

View file

@ -105,14 +105,14 @@ struct goal2sat::imp {
}
sat::bool_var mk_true() {
// create fake variable to represent true;
if (m_true == sat::null_bool_var) {
// create fake variable to represent true;
m_true = m_solver.mk_var();
mk_clause(sat::literal(m_true, false)); // v is true
}
return m_true;
}
void convert_atom(expr * t, bool root, bool sign) {
SASSERT(m.is_bool(t));
sat::literal l;
@ -515,6 +515,7 @@ void goal2sat::set_cancel(bool f) {
}
}
struct sat2goal::imp {
// Wrapper for sat::model_converter: converts it into an "AST level" model_converter.

View file

@ -60,6 +60,7 @@ public:
void operator()(goal const & g, params_ref const & p, sat::solver & t, atom2bool_var & m, dep2asm_map& dep2asm, bool default_external = false);
void set_cancel(bool f);
};