From 3de8c193eaac44c8b5c6ce4e04af6efe19bb00de Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 30 Oct 2017 16:11:51 -0500 Subject: [PATCH] implementing model updates Signed-off-by: Nikolaj Bjorner --- src/ackermannization/ackr_model_converter.cpp | 5 ++ .../lackr_model_converter_lazy.cpp | 5 ++ src/api/python/z3/z3.py | 15 ---- src/ast/ast.cpp | 4 + src/ast/ast.h | 2 + src/ast/ast_pp_util.cpp | 6 +- src/ast/ast_pp_util.h | 6 +- src/ast/ast_printer.cpp | 2 +- src/ast/ast_smt2_pp.cpp | 73 +++++++++++++--- src/ast/ast_smt2_pp.h | 5 +- src/ast/ast_translation.h | 1 + src/cmd_context/cmd_context.cpp | 15 +++- src/cmd_context/cmd_context.h | 20 +++-- src/cmd_context/tactic_cmds.cpp | 3 +- src/muz/base/dl_util.cpp | 15 ++-- src/muz/spacer/spacer_itp_solver.h | 2 +- src/muz/spacer/spacer_virtual_solver.h | 2 +- src/muz/transforms/dl_mk_bit_blast.cpp | 2 + src/muz/transforms/dl_mk_karr_invariants.cpp | 2 + .../dl_mk_quantifier_abstraction.cpp | 8 +- src/muz/transforms/dl_mk_scale.cpp | 3 + src/muz/transforms/dl_mk_slice.cpp | 4 + src/opt/opt_context.cpp | 2 +- src/opt/opt_context.h | 2 +- src/opt/opt_solver.cpp | 2 +- src/opt/opt_solver.h | 2 +- src/parsers/smt2/smt2parser.cpp | 37 +++++++- src/sat/sat_model_converter.cpp | 86 +++++++++---------- src/sat/sat_model_converter.h | 11 ++- src/sat/sat_simplifier.cpp | 16 ++-- src/sat/sat_solver/inc_sat_solver.cpp | 15 +++- src/sat/tactic/goal2sat.cpp | 36 +++++--- src/smt/smt_solver.cpp | 4 +- src/solver/check_sat_result.cpp | 2 +- src/solver/check_sat_result.h | 12 ++- src/solver/combined_solver.cpp | 2 +- src/solver/solver.cpp | 6 ++ src/solver/solver.h | 21 ++--- src/solver/solver2tactic.cpp | 11 +-- src/solver/tactic2solver.cpp | 13 +-- src/tactic/CMakeLists.txt | 1 + src/tactic/arith/degree_shift_tactic.cpp | 66 ++++++-------- src/tactic/arith/elim01_tactic.cpp | 5 ++ src/tactic/arith/eq2bv_tactic.cpp | 12 ++- src/tactic/bv/dt2bv_tactic.cpp | 27 ++---- src/tactic/converter.h | 36 +++----- src/tactic/core/elim_uncnstr_tactic.cpp | 6 +- src/tactic/core/pb_preprocess_tactic.cpp | 14 ++- src/tactic/core/split_clause_tactic.cpp | 2 + src/tactic/equiv_proof_converter.h | 1 + src/tactic/extension_model_converter.cpp | 25 +++--- src/tactic/extension_model_converter.h | 5 +- src/tactic/filter_model_converter.cpp | 6 +- src/tactic/filter_model_converter.h | 2 +- src/tactic/horn_subsume_model_converter.h | 1 + src/tactic/model_converter.cpp | 54 ++++++++++-- src/tactic/model_converter.h | 14 ++- .../portfolio/bounded_int2bv_solver.cpp | 2 +- src/tactic/portfolio/enum2bv_solver.cpp | 2 +- src/tactic/portfolio/pb2bv_solver.cpp | 2 +- src/tactic/replace_proof_converter.h | 2 + src/tactic/tactic.cpp | 9 +- src/tactic/tactic.h | 2 +- 63 files changed, 482 insertions(+), 294 deletions(-) diff --git a/src/ackermannization/ackr_model_converter.cpp b/src/ackermannization/ackr_model_converter.cpp index a7c021913..3cd86d2f1 100644 --- a/src/ackermannization/ackr_model_converter.cpp +++ b/src/ackermannization/ackr_model_converter.cpp @@ -62,6 +62,10 @@ public: } } + virtual void display(std::ostream & out) { + out << "(ackr-model-converter)\n"; + } + protected: ast_manager & m; const ackr_info_ref info; @@ -144,6 +148,7 @@ void ackr_model_converter::add_entry(model_evaluator & evaluator, else { TRACE("ackr_model", tout << "entry already present\n";); } + } model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info) { diff --git a/src/ackermannization/lackr_model_converter_lazy.cpp b/src/ackermannization/lackr_model_converter_lazy.cpp index 2a7adb839..ffb4cae9d 100644 --- a/src/ackermannization/lackr_model_converter_lazy.cpp +++ b/src/ackermannization/lackr_model_converter_lazy.cpp @@ -48,6 +48,11 @@ public: virtual model_converter * translate(ast_translation & translator) { NOT_IMPLEMENTED_YET(); } + + virtual void display(std::ostream & out) { + out << "(lackr-model-converter)\n"; + } + protected: ast_manager& m; const lackr_model_constructor_ref model_constructor; diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index ab6249ff6..b47873398 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -6279,21 +6279,6 @@ class Solver(Z3PPObject): consequences = [ consequences[i] for i in range(sz) ] return CheckSatResult(r), consequences - def lemmas(self): - """Extract auxiliary lemmas produced by solver""" - return AstVector(Z3_solver_get_lemmas(self.ctx.ref(), self.solver), self.ctx) - - def lookahead(self, candidates = None): - """Get lookahead literal""" - if candidates is None: - candidates = AstVector(None, self.ctx) - elif not isinstance(candidates, AstVector): - _cs = AstVector(None, self.ctx) - for c in candidates: - _asms.push(c) - candidates = _cs - return _to_expr_ref(Z3_solver_lookahead(self.ctx.ref(), self.solver, candidates), self.ctx) - def cube(self): """Get set of cubes""" rounds = 0 diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 232e7b6d0..c8de22899 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1356,6 +1356,10 @@ ast_manager::ast_manager(ast_manager const & src, bool disable_proofs): copy_families_plugins(src); } +void ast_manager::update_fresh_id(ast_manager const& m) { + m_fresh_id = std::max(m_fresh_id, m.m_fresh_id); +} + void ast_manager::init() { m_int_real_coercions = true; m_debug_ref_count = false; diff --git a/src/ast/ast.h b/src/ast/ast.h index 4eb43d30b..d1466e569 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1435,6 +1435,8 @@ public: void show_id_gen(); + void update_fresh_id(ast_manager const& other); + protected: reslimit m_limit; small_object_allocator m_alloc; diff --git a/src/ast/ast_pp_util.cpp b/src/ast/ast_pp_util.cpp index 455addf73..bbd1d0f41 100644 --- a/src/ast/ast_pp_util.cpp +++ b/src/ast/ast_pp_util.cpp @@ -36,7 +36,6 @@ void ast_pp_util::collect(expr_ref_vector const& es) { } void ast_pp_util::display_decls(std::ostream& out) { - smt2_pp_environment_dbg env(m); ast_smt_pp pp(m); unsigned n = coll.get_num_sorts(); for (unsigned i = 0; i < n; ++i) { @@ -46,7 +45,7 @@ void ast_pp_util::display_decls(std::ostream& out) { for (unsigned i = 0; i < n; ++i) { func_decl* f = coll.get_func_decls()[i]; if (f->get_family_id() == null_family_id) { - ast_smt2_pp(out, f, env); + ast_smt2_pp(out, f, m_env); out << "\n"; } } @@ -54,10 +53,9 @@ void ast_pp_util::display_decls(std::ostream& out) { void ast_pp_util::display_asserts(std::ostream& out, expr_ref_vector const& fmls, bool neat) { if (neat) { - smt2_pp_environment_dbg env(m); for (expr* f : fmls) { out << "(assert "; - ast_smt2_pp(out, f, env); + ast_smt2_pp(out, f, m_env); out << ")\n"; } } diff --git a/src/ast/ast_pp_util.h b/src/ast/ast_pp_util.h index 964a862a2..ead31a475 100644 --- a/src/ast/ast_pp_util.h +++ b/src/ast/ast_pp_util.h @@ -20,14 +20,16 @@ Revision History: #define AST_PP_UTIL_H_ #include "ast/decl_collector.h" +#include "ast/ast_smt2_pp.h" class ast_pp_util { ast_manager& m; + smt2_pp_environment_dbg m_env; public: decl_collector coll; - ast_pp_util(ast_manager& m): m(m), coll(m, false) {} + ast_pp_util(ast_manager& m): m(m), m_env(m), coll(m, false) {} void collect(expr* e); @@ -38,6 +40,8 @@ class ast_pp_util { void display_decls(std::ostream& out); void display_asserts(std::ostream& out, expr_ref_vector const& fmls, bool neat = true); + + smt2_pp_environment& env() { return m_env; } }; #endif /* AST_PP_UTIL_H_ */ diff --git a/src/ast/ast_printer.cpp b/src/ast/ast_printer.cpp index b5cf60ee9..9e19e4bfe 100644 --- a/src/ast/ast_printer.cpp +++ b/src/ast/ast_printer.cpp @@ -34,7 +34,7 @@ public: out << f->get_name(); } virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), params_ref(), r); } - virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r); } + virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r, "declare-fun"); } virtual void pp(expr * n, format_ns::format_ref & r) const { sbuffer buf; mk_smt2_format(n, env(), params_ref(), 0, 0, r, buf); diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index e093dc2ff..db66d9097 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -876,8 +876,21 @@ class smt2_printer { } } + void register_var_names(unsigned n) { + unsigned idx = 1; + for (unsigned i = 0; i < n; i++) { + symbol name = next_name("x", idx); + SASSERT(!m_var_names_set.contains(name)); + m_var_names.push_back(name); + m_var_names_set.insert(name); + } + } + void unregister_var_names(quantifier * q) { - unsigned num_decls = q->get_num_decls(); + unregister_var_names(q->get_num_decls()); + } + + void unregister_var_names(unsigned num_decls) { for (unsigned i = 0; i < num_decls; i++) { symbol s = m_var_names.back(); m_var_names.pop_back(); @@ -885,25 +898,28 @@ class smt2_printer { } } - format * pp_var_decls(quantifier * q) { + format * pp_var_args(unsigned num_decls, sort* const* srts) { ptr_buffer buf; - unsigned num_decls = q->get_num_decls(); SASSERT(num_decls <= m_var_names.size()); symbol * it = m_var_names.end() - num_decls; for (unsigned i = 0; i < num_decls; i++, it++) { - format * fs[1] = { m_env.pp_sort(q->get_decl_sort(i)) }; + format * fs[1] = { m_env.pp_sort(srts[i]) }; std::string var_name; if (is_smt2_quoted_symbol (*it)) { var_name = mk_smt2_quoted_symbol (*it); } else { - var_name = it->str ();\ + var_name = it->str (); } buf.push_back(mk_seq1(m(), fs, fs+1, f2f(), var_name.c_str ())); } return mk_seq5(m(), buf.begin(), buf.end(), f2f()); } + format * pp_var_decls(quantifier * q) { + return pp_var_args(q->get_num_decls(), q->get_decl_sorts()); + } + void process_quantifier(quantifier * q, frame & fr) { if (fr.m_idx == 0) { begin_scope(); @@ -1098,7 +1114,7 @@ public: r = m_env.pp_sort(s); } - void operator()(func_decl * f, format_ref & r) { + void operator()(func_decl * f, format_ref & r, char const* cmd) { unsigned arity = f->get_arity(); unsigned len; format * fname = m_env.pp_fdecl_name(f, len); @@ -1110,9 +1126,27 @@ public: } args[1] = mk_seq5(m(), buf.begin(), buf.end(), f2f()); args[2] = m_env.pp_sort(f->get_range()); - r = mk_seq1(m(), args, args+3, f2f(), "declare-fun"); + r = mk_seq1(m(), args, args+3, f2f(), cmd); } + + void operator()(func_decl * f, expr * e, format_ref & r, char const* cmd) { + unsigned arity = f->get_arity(); + unsigned len; + format * fname = m_env.pp_fdecl_name(f, len); + register_var_names(f->get_arity()); + format * args[4]; + args[0] = fname; + args[1] = pp_var_args(f->get_arity(), f->get_domain()); + args[2] = m_env.pp_sort(f->get_range()); + process(e, r); + args[3] = r; + r = mk_seq1(m(), args, args+4, f2f(), cmd); + unregister_var_names(f->get_arity()); + } + + + }; void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p, @@ -1127,9 +1161,14 @@ void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, f pr(s, r); } -void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r) { +void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd) { smt2_printer pr(env, p); - pr(f, r); + pr(f, r, cmd); +} + +void mk_smt2_format(func_decl * f, expr * e, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd) { + smt2_printer pr(env, p); + pr(f, e, r, cmd); } void mk_smt2_format(unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p, @@ -1170,17 +1209,29 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e return out; } -std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent) { +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) { ast_manager & m = env.get_manager(); format_ref r(fm(m)); sbuffer var_names; - mk_smt2_format(f, env, p, r); + mk_smt2_format(f, env, p, r, cmd); if (indent > 0) r = mk_indent(m, indent, r.get()); pp(out, r.get(), m, p); return out; } +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) { + ast_manager & m = env.get_manager(); + format_ref r(fm(m)); + sbuffer var_names; + mk_smt2_format(f, e, env, p, r, cmd); + if (indent > 0) + r = mk_indent(m, indent, r.get()); + pp(out, r.get(), m, p); + return out; +} + + std::ostream & ast_smt2_pp(std::ostream & out, unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p, unsigned indent, unsigned num_vars, char const * var_prefix) { ast_manager & m = env.get_manager(); diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index 7a0267960..8a4b3d80a 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -97,12 +97,13 @@ void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names); void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r); -void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r); +void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r, char const* cmd); std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0); -std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0); +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "declare-fun"); +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "define-fun"); /** \brief Internal wrapper (for debugging purposes only) diff --git a/src/ast/ast_translation.h b/src/ast/ast_translation.h index b278791d7..886aaf417 100644 --- a/src/ast/ast_translation.h +++ b/src/ast/ast_translation.h @@ -52,6 +52,7 @@ public: ast_translation(ast_manager & from, ast_manager & to, bool copy_plugins = true) : m_from_manager(from), m_to_manager(to) { if (copy_plugins) m_to_manager.copy_families_plugins(m_from_manager); + m_to_manager.update_fresh_id(m_from_manager); } ~ast_translation(); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index ce6c4a65a..97c53d423 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -43,6 +43,7 @@ Notes: #include "model/model_v2_pp.h" #include "model/model_params.hpp" #include "tactic/tactic_exception.h" +#include "tactic/generic_model_converter.h" #include "solver/smt_logics.h" #include "cmd_context/basic_cmds.h" #include "cmd_context/interpolant_cmds.h" @@ -864,6 +865,17 @@ void cmd_context::insert(symbol const & s, object_ref * r) { m_object_refs.insert(s, r); } +void cmd_context::model_add(symbol const & s, unsigned arity, sort *const* domain, expr * t) { + if (!m_mc0) m_mc0 = alloc(generic_model_converter, m()); + func_decl_ref fn(m().mk_func_decl(s, arity, domain, m().get_sort(t)), m()); + m_mc0->add(fn, t); +} + +void cmd_context::model_del(func_decl* f) { + if (!m_mc0) m_mc0 = alloc(generic_model_converter, m()); + m_mc0->hide(f); +} + void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector const& ids, expr* e) { expr_ref eq(m()); app_ref lhs(m()); @@ -1573,6 +1585,7 @@ void cmd_context::display_dimacs() { void cmd_context::display_model(model_ref& mdl) { if (mdl) { + if (m_mc0) (*m_mc0)(mdl); model_params p; if (p.v1() || p.v2()) { std::ostringstream buffer; @@ -1895,7 +1908,7 @@ void cmd_context::pp(expr * n, format_ns::format_ref & r) const { } void cmd_context::pp(func_decl * f, format_ns::format_ref & r) const { - mk_smt2_format(f, get_pp_env(), params_ref(), r); + mk_smt2_format(f, get_pp_env(), params_ref(), r, "declare-fun"); } void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const { diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index b60f590a9..48dd17cb0 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -23,20 +23,21 @@ Notes: #include #include -#include "ast/ast.h" -#include "ast/ast_printer.h" -#include "cmd_context/pdecl.h" -#include "util/dictionary.h" -#include "solver/solver.h" -#include "ast/datatype_decl_plugin.h" #include "util/stopwatch.h" #include "util/cmd_context_types.h" #include "util/event_handler.h" #include "util/sexpr.h" +#include "util/dictionary.h" +#include "util/scoped_ptr_vector.h" +#include "ast/ast.h" +#include "ast/ast_printer.h" +#include "ast/datatype_decl_plugin.h" +#include "tactic/generic_model_converter.h" +#include "solver/solver.h" +#include "solver/progress_callback.h" +#include "cmd_context/pdecl.h" #include "cmd_context/tactic_manager.h" #include "cmd_context/check_logic.h" -#include "solver/progress_callback.h" -#include "util/scoped_ptr_vector.h" #include "cmd_context/context_params.h" @@ -303,6 +304,7 @@ protected: void erase_macro(symbol const& s); bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const; + ref m_mc0; public: cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null); @@ -381,6 +383,8 @@ public: void insert_user_tactic(symbol const & s, sexpr * d); void insert_aux_pdecl(pdecl * p); void insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector const& ids, expr* e); + void model_add(symbol const & s, unsigned arity, sort *const* domain, expr * t); + void model_del(func_decl* f); func_decl * find_func_decl(symbol const & s) const; func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices, unsigned arity, sort * const * domain, sort * range) const; diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index cbc90c62c..20a2b1c11 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -211,6 +211,7 @@ public: assert_exprs_from(ctx, *g); TRACE("check_sat_using", g->display(tout);); model_ref md; + model_converter_ref mc; proof_ref pr(m); expr_dependency_ref core(m); std::string reason_unknown; @@ -226,7 +227,7 @@ public: cmd_context::scoped_watch sw(ctx); lbool r = l_undef; try { - r = check_sat(t, g, md, result->labels, pr, core, reason_unknown); + r = check_sat(t, g, md, mc, result->labels, pr, core, reason_unknown); ctx.display_sat_result(r); result->set_status(r); if (r == l_undef) { diff --git a/src/muz/base/dl_util.cpp b/src/muz/base/dl_util.cpp index f0439a55c..463b78c4a 100644 --- a/src/muz/base/dl_util.cpp +++ b/src/muz/base/dl_util.cpp @@ -384,6 +384,7 @@ namespace datalog { return alloc(skip_model_converter); } + virtual void display(std::ostream & out) { } }; model_converter* mk_skip_model_converter() { return alloc(skip_model_converter); } @@ -398,6 +399,7 @@ namespace datalog { return alloc(skip_proof_converter); } + virtual void display(std::ostream & out) { out << "(skip-proof-converter)\n"; } }; proof_converter* mk_skip_proof_converter() { return alloc(skip_proof_converter); } @@ -508,10 +510,9 @@ namespace datalog { } void collect_and_transform(const unsigned_vector & src, const unsigned_vector & translation, - unsigned_vector & res) { - unsigned n = src.size(); - for(unsigned i=0; i &r); - virtual void get_model(model_ref &m) {m_solver.get_model(m);} + virtual void get_model_core(model_ref &m) {m_solver.get_model(m);} virtual proof *get_proof() {return m_solver.get_proof();} virtual std::string reason_unknown() const {return m_solver.reason_unknown();} diff --git a/src/muz/spacer/spacer_virtual_solver.h b/src/muz/spacer/spacer_virtual_solver.h index fafaf2020..613f85169 100644 --- a/src/muz/spacer/spacer_virtual_solver.h +++ b/src/muz/spacer/spacer_virtual_solver.h @@ -80,7 +80,7 @@ public: virtual void get_unsat_core(ptr_vector &r); virtual void assert_expr(expr *e); virtual void collect_statistics(statistics &st) const {} - virtual void get_model(model_ref &m) {m_context.get_model(m);} + virtual void get_model_core(model_ref &m) {m_context.get_model(m);} virtual proof* get_proof(); virtual std::string reason_unknown() const {return m_context.last_failure_as_string();} diff --git a/src/muz/transforms/dl_mk_bit_blast.cpp b/src/muz/transforms/dl_mk_bit_blast.cpp index 3c8045e34..924b12eda 100644 --- a/src/muz/transforms/dl_mk_bit_blast.cpp +++ b/src/muz/transforms/dl_mk_bit_blast.cpp @@ -63,6 +63,8 @@ namespace datalog { return alloc(bit_blast_model_converter, m); } + virtual void display(std::ostream& out) { out << "(bit-blast-model-converter)\n"; } + virtual void operator()(model_ref & model) { for (unsigned i = 0; i < m_new_funcs.size(); ++i) { func_decl* p = m_new_funcs[i].get(); diff --git a/src/muz/transforms/dl_mk_karr_invariants.cpp b/src/muz/transforms/dl_mk_karr_invariants.cpp index 48219eeb9..678c673a8 100644 --- a/src/muz/transforms/dl_mk_karr_invariants.cpp +++ b/src/muz/transforms/dl_mk_karr_invariants.cpp @@ -150,6 +150,8 @@ namespace datalog { return mc; } + virtual void display(std::ostream& out) { out << "(add-invariant-model-converter)\n"; } + private: void mk_body(matrix const& M, expr_ref& body) { expr_ref_vector conj(m); diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp index b171aaa7c..888e1ebb5 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp @@ -53,6 +53,8 @@ namespace datalog { return alloc(qa_model_converter, m); } + virtual void display(std::ostream& out) { display_add(out, m); } + void insert(func_decl* old_p, func_decl* new_p, expr_ref_vector& sub, sort_ref_vector& sorts, svector const& bound) { m_old_funcs.push_back(old_p); m_new_funcs.push_back(new_p); @@ -81,7 +83,11 @@ namespace datalog { SASSERT(body); } else { - body = m.mk_false(); + expr_ref_vector args(m); + for (unsigned i = 0; i < p->get_arity(); ++i) { + args.push_back(m.mk_var(i, p->get_domain(i))); + } + body = m.mk_app(p, args.size(), args.c_ptr()); } // Create quantifier wrapper around body. diff --git a/src/muz/transforms/dl_mk_scale.cpp b/src/muz/transforms/dl_mk_scale.cpp index 5bc10b957..5eeaaaeca 100644 --- a/src/muz/transforms/dl_mk_scale.cpp +++ b/src/muz/transforms/dl_mk_scale.cpp @@ -99,6 +99,9 @@ namespace datalog { UNREACHABLE(); return 0; } + + virtual void display(std::ostream& out) { out << "(scale-model-converter)\n"; } + }; diff --git a/src/muz/transforms/dl_mk_slice.cpp b/src/muz/transforms/dl_mk_slice.cpp index c094e5520..8b38335e0 100644 --- a/src/muz/transforms/dl_mk_slice.cpp +++ b/src/muz/transforms/dl_mk_slice.cpp @@ -283,6 +283,8 @@ namespace datalog { // this would require implementing translation for the dl_context. return 0; } + + virtual void display(std::ostream& out) { out << "(slice-proof-converter)\n"; } }; class mk_slice::slice_model_converter : public model_converter { @@ -396,6 +398,8 @@ namespace datalog { return 0; } + virtual void display(std::ostream& out) { out << "(slice-model-converter)\n"; } + }; mk_slice::mk_slice(context & ctx): diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp index 29470ba18..9c861eb49 100644 --- a/src/opt/opt_context.cpp +++ b/src/opt/opt_context.cpp @@ -331,7 +331,7 @@ namespace opt { } } - void context::get_model(model_ref& mdl) { + void context::get_model_core(model_ref& mdl) { mdl = m_model; fix_model(mdl); } diff --git a/src/opt/opt_context.h b/src/opt/opt_context.h index ad40db074..4fec5d452 100644 --- a/src/opt/opt_context.h +++ b/src/opt/opt_context.h @@ -184,7 +184,7 @@ namespace opt { virtual void set_hard_constraints(ptr_vector & hard); virtual lbool optimize(); virtual void set_model(model_ref& _m) { m_model = _m; } - virtual void get_model(model_ref& _m); + virtual void get_model_core(model_ref& _m); virtual void get_box_model(model_ref& _m, unsigned index); virtual void fix_model(model_ref& _m); virtual void collect_statistics(statistics& stats) const; diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index 69b62083f..78ae2bbbb 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -296,7 +296,7 @@ namespace opt { } } - void opt_solver::get_model(model_ref & m) { + void opt_solver::get_model_core(model_ref & m) { m_context.get_model(m); } diff --git a/src/opt/opt_solver.h b/src/opt/opt_solver.h index 46b52e387..1f0a518b2 100644 --- a/src/opt/opt_solver.h +++ b/src/opt/opt_solver.h @@ -97,7 +97,7 @@ namespace opt { virtual void pop_core(unsigned n); virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions); virtual void get_unsat_core(ptr_vector & r); - virtual void get_model(model_ref & _m); + virtual void get_model_core(model_ref & _m); virtual proof * get_proof(); virtual std::string reason_unknown() const; virtual void set_reason_unknown(char const* msg); diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index b8ad7e610..446059227 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -96,6 +96,8 @@ namespace smt2 { symbol m_check_sat; symbol m_define_fun; symbol m_define_const; + symbol m_model_add; + symbol m_model_del; symbol m_declare_fun; symbol m_declare_const; symbol m_define_sort; @@ -2179,9 +2181,9 @@ namespace smt2 { next(); } - void parse_define_fun() { + void parse_define(bool is_fun) { SASSERT(curr_is_identifier()); - SASSERT(curr_id() == m_define_fun); + SASSERT(curr_id() == (is_fun ? m_define_fun : m_model_add)); SASSERT(m_num_bindings == 0); next(); check_identifier("invalid function/constant definition, symbol expected"); @@ -2195,7 +2197,10 @@ namespace smt2 { parse_expr(); if (m().get_sort(expr_stack().back()) != sort_stack().back()) throw parser_exception("invalid function/constant definition, sort mismatch"); - m_ctx.insert(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back()); + if (is_fun) + m_ctx.insert(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back()); + else + m_ctx.model_add(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back()); check_rparen("invalid function/constant definition, ')' expected"); // restore stacks & env symbol_stack().shrink(sym_spos); @@ -2208,6 +2213,22 @@ namespace smt2 { next(); } + void parse_define_fun() { + parse_define(true); + } + + void parse_model_add() { + parse_define(false); + } + + void parse_model_del() { + func_decl* f = parse_func_decl_ref(); + check_rparen("invalid model-del, ')' expected"); + m_ctx.model_del(f); + m_ctx.print_success(); + next(); + } + void parse_define_fun_rec() { // ( define-fun-rec hfun_defi ) SASSERT(curr_is_identifier()); @@ -2910,6 +2931,14 @@ namespace smt2 { parse_define_funs_rec(); return; } + if (s == m_model_add) { + parse_model_add(); + return; + } + if (s == m_model_del) { + parse_model_del(); + return; + } parse_ext_cmd(line, pos); } @@ -2941,6 +2970,8 @@ namespace smt2 { m_check_sat("check-sat"), m_define_fun("define-fun"), m_define_const("define-const"), + m_model_add("model-add"), + m_model_del("model-del"), m_declare_fun("declare-fun"), m_declare_const("declare-const"), m_define_sort("define-sort"), diff --git a/src/sat/sat_model_converter.cpp b/src/sat/sat_model_converter.cpp index 2cc9ceffc..7339f966d 100644 --- a/src/sat/sat_model_converter.cpp +++ b/src/sat/sat_model_converter.cpp @@ -295,51 +295,6 @@ namespace sat { return out; } - void model_converter::validate_is_blocked(entry const& e, clause const& c) { - if (c.is_blocked() || c.is_learned()) return; - unsigned index = 0; - literal lit = null_literal; - bool_var v = e.var(); - for (literal l : c) { - if (l.var() == v) { - lit = l; - break; - } - } - if (lit == null_literal) return; - - bool sat = false; - for (literal l : e.m_clauses) { - if (l == null_literal) { - if (!sat) { - display(std::cout << "clause is not blocked\n", e) << "\n"; - std::cout << c << "\n"; - } - sat = false; - elim_stack* st = e.m_elim_stack[index]; - if (st) { - elim_stackv const& stack = st->stack(); - unsigned sz = stack.size(); - for (unsigned i = sz; i-- > 0; ) { - // verify ... - } - - } - ++index; - continue; - } - if (sat) { - continue; - } - if (l.var() == v) { - sat = l == lit; - } - else { - sat = c.contains(~l); - } - } - } - void model_converter::copy(model_converter const & src) { reset(); m_entries.append(src.m_entries); @@ -362,4 +317,45 @@ namespace sat { return result; } + void model_converter::expand(vector& update_stack) { + literal_vector clause; + for (entry const& e : m_entries) { + clause.reset(); + unsigned index = 0; + bool var_sign = false; + for (literal l : e.m_clauses) { + if (l == null_literal) { + elim_stack* st = e.m_elim_stack[index]; + if (st) { + // clause sizes increase + elim_stackv const& stack = st->stack(); + unsigned sz = stack.size(); + for (unsigned i = 0; i < sz; ++i) { + unsigned csz = stack[i].first; + literal lit = stack[i].second; + BOOL found = false; + unsigned j = 0; + for (j = 0; j < csz; ++j) { + if (clause[j] == lit) { + std::swap(clause[j], clause[0]); + found = true; + break; + } + } + SASSERT(found); + update_stack.push_back(literal_vector(csz, clause.c_ptr())); + } + } + update_stack.push_back(clause); + clause.reset(); + continue; + } + clause.push_back(l); + if (l.var() == e.var()) { + std::swap(clause[0], clause.back()); + } + } + } + } + }; diff --git a/src/sat/sat_model_converter.h b/src/sat/sat_model_converter.h index cdd8c60ed..a6f1f0bbe 100644 --- a/src/sat/sat_model_converter.h +++ b/src/sat/sat_model_converter.h @@ -84,8 +84,6 @@ namespace sat { std::ostream& display(std::ostream & out, entry const& entry) const; - void validate_is_blocked(entry const& e, clause const& c); - public: model_converter(); ~model_converter(); @@ -109,6 +107,15 @@ namespace sat { void copy(model_converter const & src); void collect_vars(bool_var_set & s) const; unsigned max_var(unsigned min) const; + /* + * \brief expand entries to a list of clauses, such that + * the first literal in each clause is the literal whose + * truth value is updated as follows: + * + * lit0 := lit0 or (~lit1 & ~lit2 & ... & ~lit_k) + * + */ + void expand(vector& update_stack); }; }; diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index 820000b4c..e2e035dfb 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -1318,7 +1318,7 @@ namespace sat { void prepare_block_clause(clause& c, literal l, model_converter::entry*& new_entry, model_converter::kind k) { TRACE("blocked_clause", tout << "new blocked clause: " << c << "\n";); - if (new_entry == 0) + if (new_entry == 0 && !s.m_retain_blocked_clauses) new_entry = &(mc.mk(k, l.var())); m_to_remove.push_back(&c); for (literal lit : c) { @@ -1330,17 +1330,19 @@ namespace sat { void block_clause(clause& c, literal l, model_converter::entry *& new_entry) { prepare_block_clause(c, l, new_entry, model_converter::BLOCK_LIT); - mc.insert(*new_entry, c); + if (!s.m_retain_blocked_clauses) + mc.insert(*new_entry, c); } void block_covered_clause(clause& c, literal l, model_converter::kind k) { model_converter::entry * new_entry = 0; prepare_block_clause(c, l, new_entry, k); - mc.insert(*new_entry, m_covered_clause, m_elim_stack); + if (!s.m_retain_blocked_clauses) + mc.insert(*new_entry, m_covered_clause, m_elim_stack); } void prepare_block_binary(watch_list::iterator it, literal l1, literal blocked, model_converter::entry*& new_entry, model_converter::kind k) { - if (new_entry == 0) + if (new_entry == 0 && !s.m_retain_blocked_clauses) new_entry = &(mc.mk(k, blocked.var())); literal l2 = it->get_literal(); TRACE("blocked_clause", tout << "new blocked clause: " << l2 << " " << l1 << "\n";); @@ -1356,13 +1358,15 @@ namespace sat { void block_binary(watch_list::iterator it, literal l, model_converter::entry *& new_entry) { prepare_block_binary(it, l, l, new_entry, model_converter::BLOCK_LIT); - mc.insert(*new_entry, l, it->get_literal()); + if (!s.m_retain_blocked_clauses) + mc.insert(*new_entry, l, it->get_literal()); } void block_covered_binary(watch_list::iterator it, literal l, literal blocked, model_converter::kind k) { model_converter::entry * new_entry = 0; prepare_block_binary(it, l, blocked, new_entry, k); - mc.insert(*new_entry, m_covered_clause, m_elim_stack); + if (!s.m_retain_blocked_clauses) + mc.insert(*new_entry, m_covered_clause, m_elim_stack); } void bca() { diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index 44dc414af..218646de3 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -114,6 +114,7 @@ public: if (m_mc0.get()) result->m_mc0 = m_mc0->translate(tr); result->m_internalized = m_internalized; result->m_internalized_converted = m_internalized_converted; + if (mc0()) result->set_model_converter(mc0()->translate(tr)); return result; } @@ -299,7 +300,7 @@ public: r.reset(); r.append(m_core.size(), m_core.c_ptr()); } - virtual void get_model(model_ref & mdl) { + virtual void get_model_core(model_ref & mdl) { if (!m_model.get()) { extract_model(); } @@ -442,6 +443,18 @@ public: return m_asmsf[idx]; } + virtual model_converter_ref get_model_converter() const { + if (m_internalized && m_internalized_converted) { + NOT_IMPLEMENTED_YET(); + model_converter_ref mc = concat(m_mc0.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter->const2bits())); + mc = concat(solver::get_model_converter().get(), mc.get()); + return mc; + } + else { + return solver::get_model_converter(); + } + } + void convert_internalized() { if (!m_internalized) return; sat2goal s2g; diff --git a/src/sat/tactic/goal2sat.cpp b/src/sat/tactic/goal2sat.cpp index 1270b67c2..8daeb7ec0 100644 --- a/src/sat/tactic/goal2sat.cpp +++ b/src/sat/tactic/goal2sat.cpp @@ -968,21 +968,31 @@ struct sat2goal::imp { return res; } - void display(std::ostream & out) { - out << "(sat-model-converter\n"; - m_mc.display(out); - sat::bool_var_set vars; - m_mc.collect_vars(vars); - out << "(atoms"; - unsigned sz = m_var2expr.size(); - for (unsigned i = 0; i < sz; i++) { - if (vars.contains(i)) { - out << "\n (" << i << "\n " << mk_ismt2_pp(m_var2expr.get(i), m(), 2) << ")"; - } + expr_ref lit2expr(sat::literal l) { + expr_ref result(m_var2expr.get(l.var()), m()); + if (l.sign()) { + result = m().mk_not(result); + } + return result; + } + + void display(std::ostream & out) { + vector updates; + m_mc.expand(updates); + for (sat::literal_vector const& clause : updates) { + expr_ref_vector tail(m()); + sat::literal lit0 = clause[0]; + for (unsigned i = 1; i < clause.size(); ++i) { + tail.push_back(lit2expr(~clause[i])); + } + expr_ref def(m().mk_or(lit2expr(lit0), mk_and(tail)), m()); + if (lit0.sign()) { + lit0.neg(); + def = m().mk_not(def); + } + display_add(out, m(), to_app(lit2expr(lit0))->get_decl(), def); } - out << ")\n"; m_fmc->display(out); - out << ")\n"; } }; diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 9f411b0e6..b7a686a71 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -70,6 +70,8 @@ namespace smt { result->m_name2assertion.insert(translator(kv.m_key), translator(kv.m_value)); + if (mc0()) + result->set_model_converter(mc0()->translate(translator)); return result; } @@ -186,7 +188,7 @@ namespace smt { add_nonlocal_pattern_literals_to_core(r); } - virtual void get_model(model_ref & m) { + virtual void get_model_core(model_ref & m) { m_context.get_model(m); } diff --git a/src/solver/check_sat_result.cpp b/src/solver/check_sat_result.cpp index f1bedfc08..1308c52de 100644 --- a/src/solver/check_sat_result.cpp +++ b/src/solver/check_sat_result.cpp @@ -53,7 +53,7 @@ void simple_check_sat_result::get_unsat_core(ptr_vector & r) { r.append(m_core.size(), m_core.c_ptr()); } -void simple_check_sat_result::get_model(model_ref & m) { +void simple_check_sat_result::get_model_core(model_ref & m) { if (m_status != l_false) m = m_model; else diff --git a/src/solver/check_sat_result.h b/src/solver/check_sat_result.h index 38720a5e9..572c4d88d 100644 --- a/src/solver/check_sat_result.h +++ b/src/solver/check_sat_result.h @@ -23,6 +23,7 @@ Notes: #include "util/lbool.h" #include "util/statistics.h" #include "util/event_handler.h" +#include "tactic/model_converter.h" /** \brief Abstract interface for the result of a (check-sat) like command. @@ -40,6 +41,7 @@ class check_sat_result { protected: unsigned m_ref_count; lbool m_status; + model_converter_ref m_mc0; public: check_sat_result():m_ref_count(0), m_status(l_undef) {} virtual ~check_sat_result() {} @@ -54,7 +56,13 @@ public: get_unsat_core(core); r.append(core.size(), core.c_ptr()); } - virtual void get_model(model_ref & m) = 0; + void set_model_converter(model_converter* mc) { m_mc0 = mc; } + model_converter* mc0() { return m_mc0.get(); } + virtual void get_model_core(model_ref & m) = 0; + void get_model(model_ref & m) { + get_model_core(m); + if (m && mc0()) (*mc0())(m); + } virtual proof * get_proof() = 0; virtual std::string reason_unknown() const = 0; virtual void set_reason_unknown(char const* msg) = 0; @@ -80,7 +88,7 @@ struct simple_check_sat_result : public check_sat_result { virtual ast_manager& get_manager() const { return m_proof.get_manager(); } virtual void collect_statistics(statistics & st) const; virtual void get_unsat_core(ptr_vector & r); - virtual void get_model(model_ref & m); + virtual void get_model_core(model_ref & m); virtual proof * get_proof(); virtual std::string reason_unknown() const; virtual void get_labels(svector & r); diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index 9a685d5b3..6888dd406 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -307,7 +307,7 @@ public: m_solver2->get_unsat_core(r); } - virtual void get_model(model_ref & m) { + virtual void get_model_core(model_ref & m) { if (m_use_solver1_results) m_solver1->get_model(m); else diff --git a/src/solver/solver.cpp b/src/solver/solver.cpp index 0f5a72831..122bb2933 100644 --- a/src/solver/solver.cpp +++ b/src/solver/solver.cpp @@ -22,6 +22,7 @@ Notes: #include "ast/ast_pp.h" #include "ast/ast_pp_util.h" #include "util/common_msgs.h" +#include "tactic/model_converter.h" unsigned solver::get_num_assertions() const { @@ -41,6 +42,11 @@ std::ostream& solver::display(std::ostream & out) const { visitor.collect(fmls); visitor.display_decls(out); visitor.display_asserts(out, fmls, true); + model_converter_ref mc = get_model_converter(); + if (mc.get()) { + mc->set_pp_env(&visitor.env()); + mc->display(out); + } return out; } diff --git a/src/solver/solver.h b/src/solver/solver.h index 6171f111f..0f64c943d 100644 --- a/src/solver/solver.h +++ b/src/solver/solver.h @@ -24,6 +24,7 @@ Notes: #include "util/params.h" class solver; +class model_converter; class solver_factory { public: @@ -184,25 +185,17 @@ public: virtual expr_ref cube() = 0; -#if 0 - /** - \brief extract a lookahead candidates for branching. - */ - - virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) = 0; - - - /** - \brief extract learned lemmas. - */ - virtual void get_lemmas(expr_ref_vector& lemmas) {} -#endif - /** \brief Display the content of this solver. */ virtual std::ostream& display(std::ostream & out) const; + /** + \brief expose model converter when solver produces partially reduced set of assertions. + */ + + virtual model_converter_ref get_model_converter() const { return m_mc0; } + class scoped_push { solver& s; bool m_nopop; diff --git a/src/solver/solver2tactic.cpp b/src/solver/solver2tactic.cpp index 4f7b750f8..eea3aa9c5 100644 --- a/src/solver/solver2tactic.cpp +++ b/src/solver/solver2tactic.cpp @@ -122,6 +122,7 @@ public: local_solver->get_model(mdl); mc = model2model_converter(mdl.get()); mc = concat(fmc.get(), mc.get()); + mc = concat(local_solver->mc0(), mc.get()); } in->reset(); result.push_back(in.get()); @@ -150,14 +151,8 @@ public: if (m.canceled()) { throw tactic_exception(Z3_CANCELED_MSG); } - if (in->models_enabled()) { - model_ref mdl; - local_solver->get_model(mdl); - if (mdl) { - mc = model2model_converter(mdl.get()); - mc = concat(fmc.get(), mc.get()); - } - } + mc = local_solver->get_model_converter(); + mc = concat(fmc.get(), mc.get()); in->reset(); unsigned sz = local_solver->get_num_assertions(); for (unsigned i = 0; i < sz; ++i) { diff --git a/src/solver/tactic2solver.cpp b/src/solver/tactic2solver.cpp index 0286197fa..1dd48fb9c 100644 --- a/src/solver/tactic2solver.cpp +++ b/src/solver/tactic2solver.cpp @@ -36,6 +36,7 @@ class tactic2solver : public solver_na2as { unsigned_vector m_scopes; ref m_result; tactic_ref m_tactic; + ref m_mc; symbol m_logic; params_ref m_params; bool m_produce_models; @@ -64,7 +65,7 @@ public: virtual void collect_statistics(statistics & st) const; virtual void get_unsat_core(ptr_vector & r); - virtual void get_model(model_ref & m); + virtual void get_model_core(model_ref & m); virtual proof * get_proof(); virtual std::string reason_unknown() const; virtual void set_reason_unknown(char const* msg); @@ -82,6 +83,8 @@ public: return expr_ref(m.mk_true(), m); } + virtual model_converter* get_model_converter() { return m_mc.get(); } + }; ast_manager& tactic2solver::get_manager() const { return m_assertions.get_manager(); } @@ -153,12 +156,12 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass } model_ref md; - proof_ref pr(m); + proof_ref pr(m); expr_dependency_ref core(m); std::string reason_unknown = "unknown"; labels_vec labels; try { - switch (::check_sat(*m_tactic, g, md, labels, pr, core, reason_unknown)) { + switch (::check_sat(*m_tactic, g, md, m_mc, labels, pr, core, reason_unknown)) { case l_true: m_result->set_status(l_true); break; @@ -226,9 +229,9 @@ void tactic2solver::get_unsat_core(ptr_vector & r) { } } -void tactic2solver::get_model(model_ref & m) { +void tactic2solver::get_model_core(model_ref & m) { if (m_result.get()) - m_result->get_model(m); + m_result->get_model_core(m); } proof * tactic2solver::get_proof() { diff --git a/src/tactic/CMakeLists.txt b/src/tactic/CMakeLists.txt index e7cfdb644..74379b30f 100644 --- a/src/tactic/CMakeLists.txt +++ b/src/tactic/CMakeLists.txt @@ -3,6 +3,7 @@ z3_add_component(tactic equiv_proof_converter.cpp extension_model_converter.cpp filter_model_converter.cpp + generic_model_converter.cpp goal.cpp goal_num_occurs.cpp goal_shared_occs.cpp diff --git a/src/tactic/arith/degree_shift_tactic.cpp b/src/tactic/arith/degree_shift_tactic.cpp index 6344c4c51..80b7a416c 100644 --- a/src/tactic/arith/degree_shift_tactic.cpp +++ b/src/tactic/arith/degree_shift_tactic.cpp @@ -21,7 +21,7 @@ Revision History: --*/ #include "tactic/tactical.h" #include "tactic/filter_model_converter.h" -#include "tactic/extension_model_converter.h" +#include "tactic/generic_model_converter.h" #include "util/cooperate.h" #include "ast/arith_decl_plugin.h" #include "tactic/core/simplify_tactic.h" @@ -127,9 +127,7 @@ class degree_shift_tactic : public tactic { void visit_args(expr * t, expr_fast_mark1 & visited) { if (is_app(t)) { - unsigned num_args = to_app(t)->get_num_args(); - for (unsigned i = 0; i < num_args; i++) { - expr * arg = to_app(t)->get_arg(i); + for (expr * arg : *to_app(t)) { save_degree(arg, m_one); visit(arg, visited); } @@ -166,11 +164,9 @@ class degree_shift_tactic : public tactic { void display_candidates(std::ostream & out) { out << "candidates:\n"; - obj_map::iterator it = m_var2degree.begin(); - obj_map::iterator end = m_var2degree.end(); - for (; it != end; ++it) { - if (!it->m_value.is_one()) { - out << "POWER: " << it->m_value << "\n" << mk_ismt2_pp(it->m_key, m) << "\n"; + for (auto const& kv : m_var2degree) { + if (!kv.m_value.is_one()) { + out << "POWER: " << kv.m_value << "\n" << mk_ismt2_pp(kv.m_key, m) << "\n"; } } } @@ -189,48 +185,42 @@ class degree_shift_tactic : public tactic { void discard_non_candidates() { m_pinned.reset(); ptr_vector to_delete; - obj_map::iterator it = m_var2degree.begin(); - obj_map::iterator end = m_var2degree.end(); - for (; it != end; ++it) { - if (it->m_value.is_one()) - to_delete.push_back(it->m_key); + for (auto const& kv : m_var2degree) { + if (kv.m_value.is_one()) + to_delete.push_back(kv.m_key); else - m_pinned.push_back(it->m_key); // make sure it is not deleted during simplifications + m_pinned.push_back(kv.m_key); // make sure it is not deleted during simplifications } - ptr_vector::iterator it2 = to_delete.begin(); - ptr_vector::iterator end2 = to_delete.end(); - for (; it2 != end2; ++it2) - m_var2degree.erase(*it2); + for (app* a : to_delete) + m_var2degree.erase(a); } void prepare_substitution(model_converter_ref & mc) { SASSERT(!m_var2degree.empty()); filter_model_converter * fmc = 0; - extension_model_converter * xmc = 0; + generic_model_converter * xmc = 0; if (m_produce_models) { fmc = alloc(filter_model_converter, m); - xmc = alloc(extension_model_converter, m); + xmc = alloc(generic_model_converter, m); mc = concat(fmc, xmc); } - obj_map::iterator it = m_var2degree.begin(); - obj_map::iterator end = m_var2degree.end(); - for (; it != end; ++it) { - SASSERT(it->m_value.is_int()); - SASSERT(it->m_value >= rational(2)); - app * fresh = m.mk_fresh_const(0, it->m_key->get_decl()->get_range()); + for (auto const& kv : m_var2degree) { + SASSERT(kv.m_value.is_int()); + SASSERT(kv.m_value >= rational(2)); + app * fresh = m.mk_fresh_const(0, kv.m_key->get_decl()->get_range()); m_pinned.push_back(fresh); - m_var2var.insert(it->m_key, fresh); + m_var2var.insert(kv.m_key, fresh); if (m_produce_models) { fmc->insert(fresh->get_decl()); - xmc->insert(it->m_key->get_decl(), mk_power(fresh, rational(1)/it->m_value)); + xmc->add(kv.m_key->get_decl(), mk_power(fresh, rational(1)/kv.m_value)); } if (m_produce_proofs) { - expr * s = mk_power(it->m_key, it->m_value); + expr * s = mk_power(kv.m_key, kv.m_value); expr * eq = m.mk_eq(fresh, s); proof * pr1 = m.mk_def_intro(eq); proof * result_pr = m.mk_apply_def(fresh, s, pr1); m_pinned.push_back(result_pr); - m_var2pr.insert(it->m_key, result_pr); + m_var2pr.insert(kv.m_key, result_pr); } } } @@ -267,17 +257,15 @@ class degree_shift_tactic : public tactic { } // add >= 0 constraints for variables with even degree - obj_map::iterator it = m_var2degree.begin(); - obj_map::iterator end = m_var2degree.end(); - for (; it != end; ++it) { - SASSERT(it->m_value.is_int()); - SASSERT(it->m_value >= rational(2)); - if (it->m_value.is_even()) { - app * new_var = m_var2var.find(it->m_key); + for (auto const& kv : m_var2degree) { + SASSERT(kv.m_value.is_int()); + SASSERT(kv.m_value >= rational(2)); + if (kv.m_value.is_even()) { + app * new_var = m_var2var.find(kv.m_key); app * new_c = m_autil.mk_ge(new_var, m_autil.mk_numeral(rational(0), false)); proof * new_pr = 0; if (m_produce_proofs) { - proof * pr = m_var2pr.find(it->m_key); + proof * pr = m_var2pr.find(kv.m_key); new_pr = m.mk_th_lemma(m_autil.get_family_id(), new_c, 1, &pr); } g->assert_expr(new_c, new_pr, 0); diff --git a/src/tactic/arith/elim01_tactic.cpp b/src/tactic/arith/elim01_tactic.cpp index b6fd5eee7..68534c60b 100644 --- a/src/tactic/arith/elim01_tactic.cpp +++ b/src/tactic/arith/elim01_tactic.cpp @@ -113,6 +113,11 @@ public: } return mc; } + + virtual void display(std::ostream & out) { + out << "(elim01-model-converter)\n"; + } + }; diff --git a/src/tactic/arith/eq2bv_tactic.cpp b/src/tactic/arith/eq2bv_tactic.cpp index 255665b56..492b12fcf 100644 --- a/src/tactic/arith/eq2bv_tactic.cpp +++ b/src/tactic/arith/eq2bv_tactic.cpp @@ -107,12 +107,18 @@ class eq2bv_tactic : public tactic { virtual model_converter* translate(ast_translation & translator) { bvmc* v = alloc(bvmc); - obj_map::iterator it = m_map.begin(), end = m_map.end(); - for (; it != end; ++it) { - v->m_map.insert(translator(it->m_key), translator(it->m_value)); + for (auto const& kv : m_map) { + v->m_map.insert(translator(kv.m_key), translator(kv.m_value)); } return v; } + + virtual void display(std::ostream & out) { + for (auto const& kv : m_map) { + out << "(model-set " << kv.m_key->get_name() << " " << kv.m_value->get_name() << ")\n"; + } + } + }; public: diff --git a/src/tactic/bv/dt2bv_tactic.cpp b/src/tactic/bv/dt2bv_tactic.cpp index fe59480e7..2b1aa0fdd 100644 --- a/src/tactic/bv/dt2bv_tactic.cpp +++ b/src/tactic/bv/dt2bv_tactic.cpp @@ -131,10 +131,8 @@ public: for (unsigned i = 0; i < size; ++i) { quick_for_each_expr(proc, visited, g->form(i)); } - obj_hashtable::iterator it = m_non_fd_sorts.begin(), end = m_non_fd_sorts.end(); - for (; it != end; ++it) { - m_fd_sorts.remove(*it); - } + for (sort* s : m_non_fd_sorts) + m_fd_sorts.remove(s); if (!m_fd_sorts.empty()) { ref ext = alloc(extension_model_converter, m); ref filter = alloc(filter_model_converter, m); @@ -152,21 +150,12 @@ public: } expr_ref_vector bounds(m); rw.flush_side_constraints(bounds); - for (unsigned i = 0; i < bounds.size(); ++i) { - g->assert_expr(bounds[i].get()); - } - { - obj_map::iterator it = rw.enum2bv().begin(), end = rw.enum2bv().end(); - for (; it != end; ++it) { - filter->insert(it->m_value); - } - } - { - obj_map::iterator it = rw.enum2def().begin(), end = rw.enum2def().end(); - for (; it != end; ++it) { - ext->insert(it->m_key, it->m_value); - } - } + for (expr* b : bounds) + g->assert_expr(b); + for (auto const& kv : rw.enum2bv()) + filter->insert(kv.m_value); + for (auto const& kv : rw.enum2def()) + ext->insert(kv.m_key, kv.m_value); mc = concat(filter.get(), ext.get()); report_tactic_progress(":fd-num-translated", rw.num_translated()); diff --git a/src/tactic/converter.h b/src/tactic/converter.h index 9de8218c3..84df02c94 100644 --- a/src/tactic/converter.h +++ b/src/tactic/converter.h @@ -38,8 +38,7 @@ public: virtual void cancel() {} - // for debugging purposes - virtual void display(std::ostream & out) {} + virtual void display(std::ostream & out) = 0; }; template @@ -68,10 +67,8 @@ public: virtual char const * get_name() const = 0; virtual void display(std::ostream & out) { - out << "(" << get_name() << "\n"; m_c1->display(out); m_c2->display(out); - out << ")\n"; } }; @@ -86,10 +83,9 @@ protected: T * translate_core(ast_translation & translator) { T * t1 = m_c1 ? m_c1->translate(translator) : 0; ptr_buffer t2s; - unsigned num = m_c2s.size(); - for (unsigned i = 0; i < num; i++) - t2s.push_back(m_c2s[i] ? m_c2s[i]->translate(translator) : 0); - return alloc(T2, t1, num, t2s.c_ptr(), m_szs.c_ptr()); + for (T* c : m_c2s) + t2s.push_back(c ? c->translate(translator) : 0); + return alloc(T2, t1, m_c2s.size(), t2s.c_ptr(), m_szs.c_ptr()); } public: @@ -105,36 +101,24 @@ public: } virtual ~concat_star_converter() { - unsigned sz = m_c2s.size(); - for (unsigned i = 0; i < sz; i++) { - T * c2 = m_c2s[i]; - if (c2) - c2->dec_ref(); - } + for (T* c : m_c2s) + if (c) c->dec_ref(); } virtual void cancel() { if (m_c1) m_c1->cancel(); - unsigned num = m_c2s.size(); - for (unsigned i = 0; i < num; i++) { - if (m_c2s[i]) - m_c2s[i]->cancel(); - } + for (T* c : m_c2s) + if (c) c->cancel(); } virtual char const * get_name() const = 0; virtual void display(std::ostream & out) { - out << "(" << get_name() << "\n"; if (m_c1) m_c1->display(out); - out << "(\n"; - unsigned num = m_c2s.size(); - for (unsigned i = 0; i < num; i++) - if (m_c2s[i]) - m_c2s[i]->display(out); - out << "))\n"; + for (T* c : m_c2s) + if (c) c->display(out); } }; diff --git a/src/tactic/core/elim_uncnstr_tactic.cpp b/src/tactic/core/elim_uncnstr_tactic.cpp index 6a38f787e..614b20a10 100644 --- a/src/tactic/core/elim_uncnstr_tactic.cpp +++ b/src/tactic/core/elim_uncnstr_tactic.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "tactic/tactical.h" -#include "tactic/extension_model_converter.h" +#include "tactic/generic_model_converter.h" #include "tactic/filter_model_converter.h" #include "ast/rewriter/rewriter_def.h" #include "ast/arith_decl_plugin.h" @@ -34,7 +34,7 @@ class elim_uncnstr_tactic : public tactic { struct imp { // unconstrained vars collector - typedef extension_model_converter mc; + typedef generic_model_converter mc; struct rw_cfg : public default_rewriter_cfg { bool m_produce_proofs; @@ -120,7 +120,7 @@ class elim_uncnstr_tactic : public tactic { SASSERT(uncnstr(v)); SASSERT(to_app(v)->get_num_args() == 0); if (m_mc) - m_mc->insert(to_app(v)->get_decl(), def); + m_mc->add(to_app(v)->get_decl(), def); } void add_defs(unsigned num, expr * const * args, expr * u, expr * identity) { diff --git a/src/tactic/core/pb_preprocess_tactic.cpp b/src/tactic/core/pb_preprocess_tactic.cpp index 6a0d7205b..c52f0526b 100644 --- a/src/tactic/core/pb_preprocess_tactic.cpp +++ b/src/tactic/core/pb_preprocess_tactic.cpp @@ -50,8 +50,8 @@ public: virtual void operator()(model_ref & mdl, unsigned goal_idx) { SASSERT(goal_idx == 0); - for (unsigned i = 0; i < m_const.size(); ++i) { - mdl->register_decl(m_const[i].first->get_decl(), m_const[i].second); + for (auto const& kv : m_const) { + mdl->register_decl(kv.first->get_decl(), kv.second); } } @@ -65,12 +65,18 @@ public: virtual model_converter * translate(ast_translation & translator) { pb_preproc_model_converter* mc = alloc(pb_preproc_model_converter, translator.to()); - for (unsigned i = 0; i < m_const.size(); ++i) { - mc->set_value_p(translator(m_const[i].first), translator(m_const[i].second)); + for (auto const& kv : m_const) { + mc->set_value_p(translator(kv.first), translator(kv.second)); } return mc; } + virtual void display(std::ostream & out) { + for (auto const& kv : m_const) { + out << "(model-set " << mk_pp(kv.first, m) << " " << mk_pp(kv.second, m) << ")\n"; + } + } + private: void set_value_p(app* e, expr* v) { SASSERT(e->get_num_args() == 0); diff --git a/src/tactic/core/split_clause_tactic.cpp b/src/tactic/core/split_clause_tactic.cpp index 7a2df81b5..a120f2910 100644 --- a/src/tactic/core/split_clause_tactic.cpp +++ b/src/tactic/core/split_clause_tactic.cpp @@ -79,6 +79,8 @@ class split_clause_tactic : public tactic { virtual proof_converter * translate(ast_translation & translator) { return alloc(split_pc, translator.to(), translator(m_clause), translator(m_clause_pr)); } + + virtual void display(std::ostream & out) { out << "(split-clause-pc)\n"; } }; public: diff --git a/src/tactic/equiv_proof_converter.h b/src/tactic/equiv_proof_converter.h index 79f5142b2..0ee44aec2 100644 --- a/src/tactic/equiv_proof_converter.h +++ b/src/tactic/equiv_proof_converter.h @@ -47,6 +47,7 @@ public: ast_manager& get_manager() { return m; } + virtual void display(std::ostream & out) {} }; #endif diff --git a/src/tactic/extension_model_converter.cpp b/src/tactic/extension_model_converter.cpp index 38f0100ee..0ae4e1323 100644 --- a/src/tactic/extension_model_converter.cpp +++ b/src/tactic/extension_model_converter.cpp @@ -7,7 +7,7 @@ Module Name: Abstract: - Model converter that introduces eliminated variables in a model. +Model converter that introduces eliminated variables in a model. Author: @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include "tactic/extension_model_converter.h" -#include "model/model_evaluator.h" -#include "ast/ast_smt2_pp.h" -#include "model/model_v2_pp.h" #include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" +#include "model/model_evaluator.h" +#include "model/model_v2_pp.h" +#include "tactic/extension_model_converter.h" extension_model_converter::~extension_model_converter() { } @@ -78,20 +78,17 @@ void extension_model_converter::insert(func_decl * v, expr * def) { void extension_model_converter::display(std::ostream & out) { - out << "(extension-model-converter"; for (unsigned i = 0; i < m_vars.size(); i++) { - out << "\n (" << m_vars.get(i)->get_name() << " "; - unsigned indent = m_vars.get(i)->get_name().size() + 4; - out << mk_ismt2_pp(m_defs.get(i), m(), indent) << ")"; + display_add(out, m(), m_vars.get(i), m_defs.get(i)); } - out << ")" << std::endl; } model_converter * extension_model_converter::translate(ast_translation & translator) { extension_model_converter * res = alloc(extension_model_converter, translator.to()); - for (unsigned i = 0; i < m_vars.size(); i++) - res->m_vars.push_back(translator(m_vars[i].get())); - for (unsigned i = 0; i < m_defs.size(); i++) - res->m_defs.push_back(translator(m_defs[i].get())); + for (func_decl* v : m_vars) + res->m_vars.push_back(translator(v)); + for (expr* d : m_defs) + res->m_defs.push_back(translator(d)); return res; } + diff --git a/src/tactic/extension_model_converter.h b/src/tactic/extension_model_converter.h index dbd7a7e3b..7ee6c68f5 100644 --- a/src/tactic/extension_model_converter.h +++ b/src/tactic/extension_model_converter.h @@ -23,12 +23,11 @@ Notes: #include "ast/ast.h" #include "tactic/model_converter.h" - class extension_model_converter : public model_converter { func_decl_ref_vector m_vars; expr_ref_vector m_defs; public: - extension_model_converter(ast_manager & m):m_vars(m), m_defs(m) { + extension_model_converter(ast_manager & m): m_vars(m), m_defs(m) { } virtual ~extension_model_converter(); @@ -44,6 +43,4 @@ public: virtual model_converter * translate(ast_translation & translator); }; - - #endif diff --git a/src/tactic/filter_model_converter.cpp b/src/tactic/filter_model_converter.cpp index 46328186d..40de848be 100644 --- a/src/tactic/filter_model_converter.cpp +++ b/src/tactic/filter_model_converter.cpp @@ -55,11 +55,9 @@ void filter_model_converter::operator()(svector & labels, unsigned goal_ } void filter_model_converter::display(std::ostream & out) { - out << "(filter-model-converter"; - for (unsigned i = 0; i < m_decls.size(); i++) { - out << " " << m_decls.get(i)->get_name(); + for (func_decl* f : m_decls) { + display_del(out, f); } - out << ")" << std::endl; } model_converter * filter_model_converter::translate(ast_translation & translator) { diff --git a/src/tactic/filter_model_converter.h b/src/tactic/filter_model_converter.h index b5d6b86f4..1cb6ec056 100644 --- a/src/tactic/filter_model_converter.h +++ b/src/tactic/filter_model_converter.h @@ -24,7 +24,7 @@ Notes: class filter_model_converter : public model_converter { func_decl_ref_vector m_decls; public: - filter_model_converter(ast_manager & m):m_decls(m) {} + filter_model_converter(ast_manager & m): m_decls(m) {} virtual ~filter_model_converter(); diff --git a/src/tactic/horn_subsume_model_converter.h b/src/tactic/horn_subsume_model_converter.h index 1c1ae9feb..74d5882a5 100644 --- a/src/tactic/horn_subsume_model_converter.h +++ b/src/tactic/horn_subsume_model_converter.h @@ -78,6 +78,7 @@ public: ast_manager& get_manager() { return m; } + virtual void display(std::ostream & out) {} }; #endif diff --git a/src/tactic/model_converter.cpp b/src/tactic/model_converter.cpp index 4269946a1..6984c0536 100644 --- a/src/tactic/model_converter.cpp +++ b/src/tactic/model_converter.cpp @@ -18,10 +18,53 @@ Notes: --*/ #include "tactic/model_converter.h" #include "model/model_v2_pp.h" +#include "ast/ast_smt2_pp.h" + +/* + * Add or overwrite value in model. + */ +void model_converter::display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const { + // TBD: for arity > 0, requires signature of arguments. + if (m_env) { + ast_smt2_pp(out, f, e, *m_env, params_ref(), 0, "model-add"); + } + else { + unsigned indent = f->get_name().size() + 4; + out << "(model-add " << f->get_name() << " " << mk_ismt2_pp(e, m, indent) << ")\n"; + } +} + +/* + * A value is removed from the model. + */ +void model_converter::display_del(std::ostream& out, func_decl* f) const { + if (m_env) { + ast_smt2_pp(out, f, *m_env, params_ref(), 0, "model-del"); + } + else { + out << "(model-del " << f->get_name() << ")\n"; + } +} + +void model_converter::display_add(std::ostream& out, ast_manager& m) { + // default printer for converter that adds entries + model_ref mdl = alloc(model, m); + (*this)(mdl); + for (unsigned i = 0, sz = mdl->get_num_constants(); i < sz; ++i) { + func_decl* f = mdl->get_constant(i); + display_add(out, m, f, mdl->get_const_interp(f)); + } + for (unsigned i = 0, sz = mdl->get_num_functions(); i < sz; ++i) { + func_decl* f = mdl->get_function(i); + func_interp* fi = mdl->get_func_interp(f); + display_add(out, m, f, fi->get_interp()); + } +} + class concat_model_converter : public concat_converter { public: - concat_model_converter(model_converter * mc1, model_converter * mc2):concat_converter(mc1, mc2) {} + concat_model_converter(model_converter * mc1, model_converter * mc2): concat_converter(mc1, mc2) {} virtual void operator()(model_ref & m) { this->m_c2->operator()(m); @@ -37,7 +80,6 @@ public: this->m_c2->operator()(r, goal_idx); this->m_c1->operator()(r, 0); } - virtual char const * get_name() const { return "concat-model-converter"; } @@ -90,9 +132,9 @@ public: // found the model converter that should be used model_converter * c2 = this->m_c2s[i]; if (c2) - c2->operator()(r, goal_idx); + c2->operator()(r, goal_idx); if (m_c1) - this->m_c1->operator()(r, i); + this->m_c1->operator()(r, i); return; } // invalid goal @@ -143,10 +185,10 @@ public: } virtual void operator()(labels_vec & r, unsigned goal_idx) { - r.append(m_labels.size(), m_labels.c_ptr()); + r.append(m_labels.size(), m_labels.c_ptr()); } - virtual void cancel() { + virtual void cancel() { } virtual void display(std::ostream & out) { diff --git a/src/tactic/model_converter.h b/src/tactic/model_converter.h index 5e549344e..02e59f6d5 100644 --- a/src/tactic/model_converter.h +++ b/src/tactic/model_converter.h @@ -24,9 +24,19 @@ Notes: #include "util/ref.h" class labels_vec : public svector {}; +class smt2_pp_environment; class model_converter : public converter { +protected: + smt2_pp_environment* m_env; + void display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const; + void display_del(std::ostream& out, func_decl* f) const; + void display_add(std::ostream& out, ast_manager& m); + public: + + model_converter(): m_env(0) {} + virtual void operator()(model_ref & m) {} // TODO: delete virtual void operator()(model_ref & m, unsigned goal_idx) { @@ -34,10 +44,12 @@ public: SASSERT(goal_idx == 0); operator()(m); } - virtual void operator()(labels_vec & r, unsigned goal_idx) {} + virtual model_converter * translate(ast_translation & translator) = 0; + + void set_pp_env(smt2_pp_environment* env) { m_env = env; } }; typedef ref model_converter_ref; diff --git a/src/tactic/portfolio/bounded_int2bv_solver.cpp b/src/tactic/portfolio/bounded_int2bv_solver.cpp index db8a1fe53..9e4a0c547 100644 --- a/src/tactic/portfolio/bounded_int2bv_solver.cpp +++ b/src/tactic/portfolio/bounded_int2bv_solver.cpp @@ -150,7 +150,7 @@ public: virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); } virtual void collect_statistics(statistics & st) const { m_solver->collect_statistics(st); } virtual void get_unsat_core(ptr_vector & r) { m_solver->get_unsat_core(r); } - virtual void get_model(model_ref & mdl) { + virtual void get_model_core(model_ref & mdl) { m_solver->get_model(mdl); if (mdl) { extend_model(mdl); diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index c5c7e3028..1df7a000c 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -95,7 +95,7 @@ public: virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); } virtual void collect_statistics(statistics & st) const { m_solver->collect_statistics(st); } virtual void get_unsat_core(ptr_vector & r) { m_solver->get_unsat_core(r); } - virtual void get_model(model_ref & mdl) { + virtual void get_model_core(model_ref & mdl) { m_solver->get_model(mdl); if (mdl) { extend_model(mdl); diff --git a/src/tactic/portfolio/pb2bv_solver.cpp b/src/tactic/portfolio/pb2bv_solver.cpp index 4ff7251be..44898a578 100644 --- a/src/tactic/portfolio/pb2bv_solver.cpp +++ b/src/tactic/portfolio/pb2bv_solver.cpp @@ -87,7 +87,7 @@ public: m_solver->collect_statistics(st); } virtual void get_unsat_core(ptr_vector & r) { m_solver->get_unsat_core(r); } - virtual void get_model(model_ref & mdl) { + virtual void get_model_core(model_ref & mdl) { m_solver->get_model(mdl); if (mdl) { filter_model(mdl); diff --git a/src/tactic/replace_proof_converter.h b/src/tactic/replace_proof_converter.h index b768a18a0..d5cf7dc31 100644 --- a/src/tactic/replace_proof_converter.h +++ b/src/tactic/replace_proof_converter.h @@ -45,6 +45,8 @@ public: // run the replacements the inverse direction. void invert() { m_proofs.reverse(); } + virtual void display(std::ostream & out) {} + }; #endif diff --git a/src/tactic/tactic.cpp b/src/tactic/tactic.cpp index 6c4ca7476..7610c420a 100644 --- a/src/tactic/tactic.cpp +++ b/src/tactic/tactic.cpp @@ -175,7 +175,7 @@ void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_conve } -lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) { +lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) { bool models_enabled = g->models_enabled(); bool proofs_enabled = g->proofs_enabled(); bool cores_enabled = g->unsat_core_enabled(); @@ -184,7 +184,6 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, p core = 0; ast_manager & m = g->m(); goal_ref_buffer r; - model_converter_ref mc; proof_converter_ref pc; try { exec(t, g, r, mc, pc, core); @@ -219,9 +218,9 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, p } else { if (models_enabled) { - model_converter2model(m, mc.get(), md); - if (mc) - (*mc)(labels, 0); + model_converter2model(m, mc.get(), md); + if (mc) + (*mc)(labels, 0); } reason_unknown = "incomplete"; return l_undef; diff --git a/src/tactic/tactic.h b/src/tactic/tactic.h index 0e4c61611..93da52366 100644 --- a/src/tactic/tactic.h +++ b/src/tactic/tactic.h @@ -153,7 +153,7 @@ public: #define MK_SIMPLE_TACTIC_FACTORY(NAME, ST) MK_TACTIC_FACTORY(NAME, return ST;) void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core); -lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown); +lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown); // Throws an exception if goal \c in requires proof generation. void fail_if_proof_generation(char const * tactic_name, goal_ref const & in);