3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 12:08:18 +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

@ -73,5 +73,22 @@ void expr2var::reset() {
dec_ref_map_keys(m(), m_mapping); dec_ref_map_keys(m(), m_mapping);
SASSERT(m_mapping.empty()); SASSERT(m_mapping.empty());
m_recent_exprs.reset(); m_recent_exprs.reset();
m_recent_lim.reset();
m_interpreted_vars = false; m_interpreted_vars = false;
} }
void expr2var::push() {
m_recent_lim.push_back(m_recent_exprs.size());
}
void expr2var::pop(unsigned num_scopes) {
if (num_scopes > 0) {
unsigned sz = m_recent_lim[m_recent_lim.size() - num_scopes];
for (unsigned i = sz; i < m_recent_exprs.size(); ++i) {
m_mapping.erase(m_recent_exprs[i]);
m().dec_ref(m_recent_exprs[i]);
}
m_recent_exprs.shrink(sz);
m_recent_lim.shrink(m_recent_lim.size() - num_scopes);
}
}

View file

@ -39,6 +39,7 @@ protected:
ast_manager & m_manager; ast_manager & m_manager;
expr2var_mapping m_mapping; expr2var_mapping m_mapping;
ptr_vector<expr> m_recent_exprs; ptr_vector<expr> m_recent_exprs;
unsigned_vector m_recent_lim;
bool m_interpreted_vars; bool m_interpreted_vars;
public: public:
expr2var(ast_manager & m); expr2var(ast_manager & m);
@ -62,7 +63,7 @@ public:
iterator begin() const { return m_mapping.begin(); } iterator begin() const { return m_mapping.begin(); }
iterator end() const { return m_mapping.end(); } iterator end() const { return m_mapping.end(); }
void reset_recent() { m_recent_exprs.reset(); } void reset_recent() { SASSERT(m_recent_lim.empty()); m_recent_exprs.reset(); }
// Iterators for traversing the recently registered expressions. // Iterators for traversing the recently registered expressions.
// The set of recent registered expressions is reset by using reset_recent(). // The set of recent registered expressions is reset by using reset_recent().
@ -70,6 +71,9 @@ public:
recent_iterator end_recent() const { return m_recent_exprs.end(); } recent_iterator end_recent() const { return m_recent_exprs.end(); }
void reset(); void reset();
void push();
void pop(unsigned num_scopes);
}; };
#endif #endif

View file

@ -92,6 +92,9 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
expr_ref_vector m_out; expr_ref_vector m_out;
obj_map<func_decl, expr*> m_const2bits; obj_map<func_decl, expr*> m_const2bits;
expr_ref_vector m_bindings; expr_ref_vector m_bindings;
func_decl_ref_vector m_keys;
expr_ref_vector m_values;
unsigned_vector m_keyval_lim;
bool m_blast_mul; bool m_blast_mul;
bool m_blast_add; bool m_blast_add;
@ -116,12 +119,13 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
m_in1(m), m_in1(m),
m_in2(m), m_in2(m),
m_out(m), m_out(m),
m_bindings(m) { m_bindings(m),
m_keys(m),
m_values(m) {
updt_params(p); updt_params(p);
} }
~blaster_rewriter_cfg() { ~blaster_rewriter_cfg() {
dec_ref_map_key_values(m_manager, m_const2bits);
} }
void updt_params(params_ref const & p) { void updt_params(params_ref const & p) {
@ -157,6 +161,24 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
} }
} }
void push() {
m_keyval_lim.push_back(m_keys.size());
}
void pop(unsigned num_scopes) {
if (num_scopes > 0) {
unsigned new_sz = m_keyval_lim.size() - num_scopes;
unsigned lim = m_keyval_lim[new_sz];
for (unsigned i = m_keys.size(); i > lim; ) {
--i;
m_const2bits.remove(m_keys[i].get());
}
m_keys.resize(lim);
m_values.resize(lim);
m_keyval_lim.resize(new_sz);
}
}
template<typename V> template<typename V>
app * mk_mkbv(V const & bits) { app * mk_mkbv(V const & bits) {
return m().mk_app(butil().get_family_id(), OP_MKBV, bits.size(), bits.c_ptr()); return m().mk_app(butil().get_family_id(), OP_MKBV, bits.size(), bits.c_ptr());
@ -180,8 +202,8 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
} }
r = mk_mkbv(m_out); r = mk_mkbv(m_out);
m_const2bits.insert(f, r); m_const2bits.insert(f, r);
m_manager.inc_ref(f); m_keys.push_back(f);
m_manager.inc_ref(r); m_values.push_back(r);
result = r; result = r;
} }
@ -611,6 +633,8 @@ struct bit_blaster_rewriter::imp : public rewriter_tpl<blaster_rewriter_cfg> {
m_cfg(m, m_blaster, p) { m_cfg(m, m_blaster, p) {
SASSERT(m_blaster.butil().get_family_id() == m.get_family_id("bv")); SASSERT(m_blaster.butil().get_family_id() == m.get_family_id("bv"));
} }
void push() { m_cfg.push(); }
void pop(unsigned s) { m_cfg.pop(s); }
}; };
bit_blaster_rewriter::bit_blaster_rewriter(ast_manager & m, params_ref const & p): bit_blaster_rewriter::bit_blaster_rewriter(ast_manager & m, params_ref const & p):
@ -630,6 +654,14 @@ void bit_blaster_rewriter::set_cancel(bool f) {
m_imp->m_blaster.set_cancel(f); m_imp->m_blaster.set_cancel(f);
} }
void bit_blaster_rewriter::push() {
m_imp->push();
}
void bit_blaster_rewriter::pop(unsigned num_scopes) {
m_imp->pop(num_scopes);
}
ast_manager & bit_blaster_rewriter::m() const { ast_manager & bit_blaster_rewriter::m() const {
return m_imp->m(); return m_imp->m();
} }

View file

@ -36,6 +36,8 @@ public:
void cleanup(); void cleanup();
obj_map<func_decl, expr*> const& const2bits() const; obj_map<func_decl, expr*> const& const2bits() const;
void operator()(expr * e, expr_ref & result, proof_ref & result_proof); void operator()(expr * e, expr_ref & result, proof_ref & result_proof);
void push();
void pop(unsigned num_scopes);
}; };
#endif #endif

View file

@ -19,7 +19,7 @@ def_module_params('opt',
('maxres.maximize_assignment', BOOL, False, 'find an MSS/MCS to improve current assignment'), ('maxres.maximize_assignment', BOOL, False, 'find an MSS/MCS to improve current assignment'),
('maxres.max_correction_set_size', UINT, 3, 'allow generating correction set constraints up to maximal size'), ('maxres.max_correction_set_size', UINT, 3, 'allow generating correction set constraints up to maximal size'),
('maxres.wmax', BOOL, False, 'use weighted theory solver to constrain upper bounds'), ('maxres.wmax', BOOL, False, 'use weighted theory solver to constrain upper bounds'),
('maxres.pivot_on_correction_set', BOOL, True, 'prefer reducing soft constraints if the current correction set is smaller than current core') ('maxres.pivot_on_correction_set', BOOL, True, 'reduce soft constraints if the current correction set is smaller than current core')
)) ))

View file

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

View file

@ -97,7 +97,7 @@ namespace sat {
if (!it2->is_binary_non_learned_clause()) if (!it2->is_binary_non_learned_clause())
continue; continue;
literal l2 = it2->get_literal(); literal l2 = it2->get_literal();
mk_clause(l, l2); mk_clause_core(l, l2);
} }
} }
} }
@ -111,7 +111,7 @@ namespace sat {
buffer.reset(); buffer.reset();
for (unsigned i = 0; i < c.size(); i++) for (unsigned i = 0; i < c.size(); i++)
buffer.push_back(c[i]); buffer.push_back(c[i]);
mk_clause(buffer); mk_clause_core(buffer);
} }
} }
} }
@ -553,7 +553,7 @@ namespace sat {
m_cleaner.dec(); m_cleaner.dec();
SASSERT(!m_inconsistent); SASSERT(!m_inconsistent);
l = m_trail[m_qhead]; 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++; m_qhead++;
not_l = ~l; not_l = ~l;
SASSERT(value(l) == l_true); SASSERT(value(l) == l_true);
@ -881,7 +881,7 @@ namespace sat {
bool solver::check_inconsistent() { bool solver::check_inconsistent() {
if (inconsistent()) { if (inconsistent()) {
if (tracking_assumptions()) if (tracking_assumptions() || !m_user_scope_literals.empty())
resolve_conflict(); resolve_conflict();
return true; return true;
} }
@ -919,7 +919,7 @@ namespace sat {
assign(nlit, justification()); assign(nlit, justification());
} }
if (weights) { if (weights && !inconsistent()) {
if (m_config.m_optimize_model) { if (m_config.m_optimize_model) {
m_wsls.set_soft(num_lits, lits, weights); m_wsls.set_soft(num_lits, lits, weights);
} }
@ -1033,7 +1033,7 @@ namespace sat {
TRACE("opt", tout << "blocking soft correction set: " << m_blocker << "\n";); TRACE("opt", tout << "blocking soft correction set: " << m_blocker << "\n";);
IF_VERBOSE(11, verbose_stream() << "blocking " << m_blocker << "\n";); IF_VERBOSE(11, verbose_stream() << "blocking " << m_blocker << "\n";);
pop_to_base_level(); pop_to_base_level();
mk_clause(m_blocker); mk_clause_core(m_blocker);
return false; return false;
} }
return true; return true;
@ -1094,7 +1094,7 @@ namespace sat {
} }
bool solver::tracking_assumptions() const { 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 { bool solver::is_assumption(literal l) const {
@ -1648,6 +1648,7 @@ namespace sat {
resolve_conflict_for_unsat_core(); resolve_conflict_for_unsat_core();
return false; return false;
} }
if (m_conflict_lvl == 0) { if (m_conflict_lvl == 0) {
return false; return false;
} }
@ -2568,16 +2569,10 @@ namespace sat {
void solver::user_push() { void solver::user_push() {
literal lit; literal lit;
if (m_user_scope_literal_pool.empty()) { bool_var new_v = mk_var(true, false);
bool_var new_v = mk_var(true, false); lit = literal(new_v, 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";);
m_user_scope_literals.push_back(lit); m_user_scope_literals.push_back(lit);
TRACE("sat", tout << "user_push: " << lit << "\n";);
} }
void solver::gc_lit(clause_vector &clauses, literal lit) { 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) { void solver::user_pop(unsigned num_scopes) {
pop_to_base_level(); pop_to_base_level();
while (num_scopes > 0) { while (num_scopes > 0) {
literal lit = m_user_scope_literals.back(); literal lit = m_user_scope_literals.back();
m_user_scope_literal_pool.push_back(lit);
m_user_scope_literals.pop_back(); m_user_scope_literals.pop_back();
gc_lit(m_learned, lit); gc_lit(m_learned, lit);
gc_lit(m_clauses, lit); gc_lit(m_clauses, lit);
@ -2620,6 +2673,14 @@ namespace sat {
gc_bin(false, lit); gc_bin(false, lit);
TRACE("sat", tout << "gc: " << lit << "\n"; display(tout);); TRACE("sat", tout << "gc: " << lit << "\n"; display(tout););
--num_scopes; --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: protected:
void del_clause(clause & c); void del_clause(clause & c);
clause * mk_clause_core(unsigned num_lits, literal * lits, bool learned); 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); void mk_bin_clause(literal l1, literal l2, bool learned);
bool propagate_bin_clause(literal l1, literal l2); bool propagate_bin_clause(literal l1, literal l2);
clause * mk_ter_clause(literal * lits, bool learned); clause * mk_ter_clause(literal * lits, bool learned);
@ -400,11 +403,14 @@ namespace sat {
void reinit_clauses(unsigned old_sz); void reinit_clauses(unsigned old_sz);
literal_vector m_user_scope_literals; literal_vector m_user_scope_literals;
literal_vector m_user_scope_literal_pool;
literal_vector m_aux_literals; literal_vector m_aux_literals;
svector<bin_clause> m_user_bin_clauses; svector<bin_clause> m_user_bin_clauses;
void gc_lit(clause_vector& clauses, literal lit); void gc_lit(clause_vector& clauses, literal lit);
void gc_bin(bool learned, literal nlit); 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: public:
void user_push(); void user_push();
void user_pop(unsigned num_scopes); void user_pop(unsigned num_scopes);

View file

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

View file

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

View file

@ -98,6 +98,11 @@ struct bit_blaster_model_converter : public model_converter {
SASSERT(m_vars.size() == m_bits.size()); SASSERT(m_vars.size() == m_bits.size());
unsigned sz = m_vars.size(); unsigned sz = m_vars.size();
for (unsigned i = 0; i < sz; i++) { for (unsigned i = 0; i < sz; i++) {
expr* new_val = old_model->get_const_interp(m_vars.get(i));
if (new_val) {
new_model->register_decl(m_vars.get(i), new_val);
continue;
}
expr * bs = m_bits.get(i); expr * bs = m_bits.get(i);
val.reset(); val.reset();
unsigned bv_sz = to_app(bs)->get_num_args(); unsigned bv_sz = to_app(bs)->get_num_args();
@ -132,7 +137,7 @@ struct bit_blaster_model_converter : public model_converter {
val++; val++;
} }
} }
expr * new_val = util.mk_numeral(val, bv_sz); new_val = util.mk_numeral(val, bv_sz);
new_model->register_decl(m_vars.get(i), new_val); new_model->register_decl(m_vars.get(i), new_val);
} }
} }

View file

@ -25,13 +25,16 @@ Notes:
class bit_blaster_tactic : public tactic { class bit_blaster_tactic : public tactic {
struct imp {
bit_blaster_rewriter m_rewriter;
unsigned m_num_steps;
bool m_blast_quant;
imp(ast_manager & m, params_ref const & p): struct imp {
m_rewriter(m, p) { bit_blaster_rewriter m_base_rewriter;
bit_blaster_rewriter* m_rewriter;
unsigned m_num_steps;
bool m_blast_quant;
imp(ast_manager & m, bit_blaster_rewriter* rw, params_ref const & p):
m_base_rewriter(m, p),
m_rewriter(rw?rw:&m_base_rewriter) {
updt_params(p); updt_params(p);
} }
@ -40,14 +43,14 @@ class bit_blaster_tactic : public tactic {
} }
void updt_params(params_ref const & p) { void updt_params(params_ref const & p) {
m_rewriter.updt_params(p); m_rewriter->updt_params(p);
updt_params_core(p); updt_params_core(p);
} }
ast_manager & m() const { return m_rewriter.m(); } ast_manager & m() const { return m_rewriter->m(); }
void set_cancel(bool f) { void set_cancel(bool f) {
m_rewriter.set_cancel(f); m_rewriter->set_cancel(f);
} }
void operator()(goal_ref const & g, void operator()(goal_ref const & g,
@ -74,8 +77,8 @@ class bit_blaster_tactic : public tactic {
if (g->inconsistent()) if (g->inconsistent())
break; break;
expr * curr = g->form(idx); expr * curr = g->form(idx);
m_rewriter(curr, new_curr, new_pr); (*m_rewriter)(curr, new_curr, new_pr);
m_num_steps += m_rewriter.get_num_steps(); m_num_steps += m_rewriter->get_num_steps();
if (proofs_enabled) { if (proofs_enabled) {
proof * pr = g->pr(idx); proof * pr = g->pr(idx);
new_pr = m().mk_modus_ponens(pr, new_pr); new_pr = m().mk_modus_ponens(pr, new_pr);
@ -88,29 +91,32 @@ class bit_blaster_tactic : public tactic {
} }
if (change && g->models_enabled()) if (change && g->models_enabled())
mc = mk_bit_blaster_model_converter(m(), m_rewriter.const2bits()); mc = mk_bit_blaster_model_converter(m(), m_rewriter->const2bits());
else else
mc = 0; mc = 0;
g->inc_depth(); g->inc_depth();
result.push_back(g.get()); result.push_back(g.get());
TRACE("after_bit_blaster", g->display(tout); if (mc) mc->display(tout); tout << "\n";); TRACE("after_bit_blaster", g->display(tout); if (mc) mc->display(tout); tout << "\n";);
m_rewriter.cleanup(); m_rewriter->cleanup();
} }
unsigned get_num_steps() const { return m_num_steps; } unsigned get_num_steps() const { return m_num_steps; }
}; };
imp * m_imp; imp * m_imp;
bit_blaster_rewriter* m_rewriter;
params_ref m_params; params_ref m_params;
public: public:
bit_blaster_tactic(ast_manager & m, params_ref const & p): bit_blaster_tactic(ast_manager & m, bit_blaster_rewriter* rw, params_ref const & p):
m_params(p){ m_rewriter(rw),
m_imp = alloc(imp, m, p); m_params(p) {
m_imp = alloc(imp, m, m_rewriter, p);
} }
virtual tactic * translate(ast_manager & m) { virtual tactic * translate(ast_manager & m) {
return alloc(bit_blaster_tactic, m, m_params); SASSERT(!m_rewriter); // assume translation isn't used where rewriter is external.
return alloc(bit_blaster_tactic, m, 0, m_params);
} }
virtual ~bit_blaster_tactic() { virtual ~bit_blaster_tactic() {
@ -145,7 +151,7 @@ public:
} }
virtual void cleanup() { virtual void cleanup() {
imp * d = alloc(imp, m_imp->m(), m_params); imp * d = alloc(imp, m_imp->m(), m_rewriter, m_params);
#pragma omp critical (tactic_cancel) #pragma omp critical (tactic_cancel)
{ {
std::swap(d, m_imp); std::swap(d, m_imp);
@ -166,5 +172,9 @@ protected:
tactic * mk_bit_blaster_tactic(ast_manager & m, params_ref const & p) { tactic * mk_bit_blaster_tactic(ast_manager & m, params_ref const & p) {
return clean(alloc(bit_blaster_tactic, m, p)); return clean(alloc(bit_blaster_tactic, m, 0, p));
}
tactic * mk_bit_blaster_tactic(ast_manager & m, bit_blaster_rewriter* rw, params_ref const & p) {
return clean(alloc(bit_blaster_tactic, m, rw, p));
} }

View file

@ -20,10 +20,12 @@ Notes:
#define BIT_BLASTER_TACTIC_H_ #define BIT_BLASTER_TACTIC_H_
#include"params.h" #include"params.h"
#include"bit_blaster_rewriter.h"
class ast_manager; class ast_manager;
class tactic; class tactic;
tactic * mk_bit_blaster_tactic(ast_manager & m, params_ref const & p = params_ref()); tactic * mk_bit_blaster_tactic(ast_manager & m, params_ref const & p = params_ref());
tactic * mk_bit_blaster_tactic(ast_manager & m, bit_blaster_rewriter* rw, params_ref const & p = params_ref());
/* /*
ADD_TACTIC("bit-blast", "reduce bit-vector expressions into SAT.", "mk_bit_blaster_tactic(m, p)") ADD_TACTIC("bit-blast", "reduce bit-vector expressions into SAT.", "mk_bit_blaster_tactic(m, p)")
*/ */

View file

@ -92,7 +92,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const
return mk_default_tactic(m, p); return mk_default_tactic(m, p);
} }
solver* mk_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) { static solver* mk_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) {
if (logic == "QF_BV") if (logic == "QF_BV")
return mk_inc_sat_solver(m, p); return mk_inc_sat_solver(m, p);
return mk_smt_solver(m, p, logic); return mk_smt_solver(m, p, logic);
@ -112,8 +112,8 @@ public:
l = logic; l = logic;
tactic * t = mk_tactic_for_logic(m, p, l); tactic * t = mk_tactic_for_logic(m, p, l);
return mk_combined_solver(mk_tactic2solver(m, t, p, proofs_enabled, models_enabled, unsat_core_enabled, l), return mk_combined_solver(mk_tactic2solver(m, t, p, proofs_enabled, models_enabled, unsat_core_enabled, l),
//mk_solver_for_logic(m, p, l), mk_solver_for_logic(m, p, l),
mk_smt_solver(m, p, l), //mk_smt_solver(m, p, l),
p); p);
} }
}; };