3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 09:34:08 +00:00

implementing model updates

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-10-30 16:11:51 -05:00
parent 92b5301b7f
commit 3de8c193ea
63 changed files with 482 additions and 294 deletions

View file

@ -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) {

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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";
}
}

View file

@ -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_ */

View file

@ -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<symbol> buf;
mk_smt2_format(n, env(), params_ref(), 0, 0, r, buf);

View file

@ -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<format> 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<format**,f2f>(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<format**, f2f>(m(), buf.begin(), buf.end(), f2f());
args[2] = m_env.pp_sort(f->get_range());
r = mk_seq1<format**, f2f>(m(), args, args+3, f2f(), "declare-fun");
r = mk_seq1<format**, f2f>(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<format**, f2f>(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<symbol> 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<symbol> 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();

View file

@ -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<symbol> & 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)

View file

@ -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();

View file

@ -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<symbol> 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 {

View file

@ -23,20 +23,21 @@ Notes:
#include<sstream>
#include<vector>
#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<generic_model_converter> 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<symbol> 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;

View file

@ -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) {

View file

@ -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<n; i++) {
unsigned translated = translation[src[i]];
unsigned_vector & res) {
for (unsigned s : src) {
unsigned translated = translation[s];
if(translated!=UINT_MAX) {
res.push_back(translated);
}
@ -520,10 +521,8 @@ namespace datalog {
void transform_set(const unsigned_vector & map, const idx_set & src, idx_set & result) {
idx_set::iterator it = src.begin();
idx_set::iterator end = src.end();
for(; it!=end; ++it) {
result.insert(map[*it]);
for (unsigned s : src) {
result.insert(map[s]);
}
}

View file

@ -146,7 +146,7 @@ public:
virtual void collect_statistics(statistics &st) const ;
virtual void reset_statistics();
virtual void get_unsat_core(ptr_vector<expr> &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();}

View file

@ -80,7 +80,7 @@ public:
virtual void get_unsat_core(ptr_vector<expr> &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();}

View file

@ -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();

View file

@ -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);

View file

@ -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<bool> 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.

View file

@ -99,6 +99,9 @@ namespace datalog {
UNREACHABLE();
return 0;
}
virtual void display(std::ostream& out) { out << "(scale-model-converter)\n"; }
};

View file

@ -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):

View file

@ -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);
}

View file

@ -184,7 +184,7 @@ namespace opt {
virtual void set_hard_constraints(ptr_vector<expr> & 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;

View file

@ -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);
}

View file

@ -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<expr> & 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);

View file

@ -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"),

View file

@ -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<literal_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());
}
}
}
}
};

View file

@ -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<literal_vector>& update_stack);
};
};

View file

@ -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() {

View file

@ -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;

View file

@ -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<sat::literal_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";
}
};

View file

@ -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);
}

View file

@ -53,7 +53,7 @@ void simple_check_sat_result::get_unsat_core(ptr_vector<expr> & 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

View file

@ -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<expr> & 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<symbol> & r);

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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) {

View file

@ -36,6 +36,7 @@ class tactic2solver : public solver_na2as {
unsigned_vector m_scopes;
ref<simple_check_sat_result> m_result;
tactic_ref m_tactic;
ref<model_converter> 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<expr> & 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<expr> & 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() {

View file

@ -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

View file

@ -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<app, rational>::iterator it = m_var2degree.begin();
obj_map<app, rational>::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<app> to_delete;
obj_map<app, rational>::iterator it = m_var2degree.begin();
obj_map<app, rational>::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<app>::iterator it2 = to_delete.begin();
ptr_vector<app>::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<app, rational>::iterator it = m_var2degree.begin();
obj_map<app, rational>::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<app, rational>::iterator it = m_var2degree.begin();
obj_map<app, rational>::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);

View file

@ -113,6 +113,11 @@ public:
}
return mc;
}
virtual void display(std::ostream & out) {
out << "(elim01-model-converter)\n";
}
};

View file

@ -107,12 +107,18 @@ class eq2bv_tactic : public tactic {
virtual model_converter* translate(ast_translation & translator) {
bvmc* v = alloc(bvmc);
obj_map<func_decl, func_decl*>::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:

View file

@ -131,10 +131,8 @@ public:
for (unsigned i = 0; i < size; ++i) {
quick_for_each_expr(proc, visited, g->form(i));
}
obj_hashtable<sort>::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<extension_model_converter> ext = alloc(extension_model_converter, m);
ref<filter_model_converter> 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<func_decl, func_decl*>::iterator it = rw.enum2bv().begin(), end = rw.enum2bv().end();
for (; it != end; ++it) {
filter->insert(it->m_value);
}
}
{
obj_map<func_decl, expr*>::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());

View file

@ -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<typename T>
@ -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<T> 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);
}
};

View file

@ -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) {

View file

@ -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);

View file

@ -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:

View file

@ -47,6 +47,7 @@ public:
ast_manager& get_manager() { return m; }
virtual void display(std::ostream & out) {}
};
#endif

View file

@ -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;
}

View file

@ -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

View file

@ -55,11 +55,9 @@ void filter_model_converter::operator()(svector<symbol> & 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) {

View file

@ -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();

View file

@ -78,6 +78,7 @@ public:
ast_manager& get_manager() { return m; }
virtual void display(std::ostream & out) {}
};
#endif

View file

@ -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<model_converter> {
public:
concat_model_converter(model_converter * mc1, model_converter * mc2):concat_converter<model_converter>(mc1, mc2) {}
concat_model_converter(model_converter * mc1, model_converter * mc2): concat_converter<model_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) {

View file

@ -24,9 +24,19 @@ Notes:
#include "util/ref.h"
class labels_vec : public svector<symbol> {};
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> model_converter_ref;

View file

@ -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<expr> & 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);

View file

@ -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<expr> & 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);

View file

@ -87,7 +87,7 @@ public:
m_solver->collect_statistics(st);
}
virtual void get_unsat_core(ptr_vector<expr> & 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);

View file

@ -45,6 +45,8 @@ public:
// run the replacements the inverse direction.
void invert() { m_proofs.reverse(); }
virtual void display(std::ostream & out) {}
};
#endif

View file

@ -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;

View file

@ -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);