mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
recursive function definitions; combine model-building functionality
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
6fa2338edc
commit
7c6540e18f
19 changed files with 129 additions and 173 deletions
|
@ -29,7 +29,6 @@ Revision History:
|
|||
|
||||
proto_model::proto_model(ast_manager & m, simplifier & s, params_ref const & p):
|
||||
model_core(m),
|
||||
m_asts(m),
|
||||
m_simplifier(s),
|
||||
m_afid(m.mk_family_id(symbol("array"))) {
|
||||
register_factory(alloc(basic_factory, m));
|
||||
|
@ -39,45 +38,11 @@ proto_model::proto_model(ast_manager & m, simplifier & s, params_ref const & p):
|
|||
m_model_partial = model_params(p).partial();
|
||||
}
|
||||
|
||||
void proto_model::reset_finterp() {
|
||||
decl2finterp::iterator it = m_finterp.begin();
|
||||
decl2finterp::iterator end = m_finterp.end();
|
||||
for (; it != end; ++it) {
|
||||
dealloc(it->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
proto_model::~proto_model() {
|
||||
reset_finterp();
|
||||
}
|
||||
|
||||
void proto_model::register_decl(func_decl * d, expr * v) {
|
||||
SASSERT(d->get_arity() == 0);
|
||||
if (m_interp.contains(d)) {
|
||||
DEBUG_CODE({
|
||||
expr * old_v = 0;
|
||||
m_interp.find(d, old_v);
|
||||
SASSERT(old_v == v);
|
||||
});
|
||||
return;
|
||||
}
|
||||
SASSERT(!m_interp.contains(d));
|
||||
m_decls.push_back(d);
|
||||
m_asts.push_back(d);
|
||||
m_asts.push_back(v);
|
||||
m_interp.insert(d, v);
|
||||
m_const_decls.push_back(d);
|
||||
}
|
||||
|
||||
void proto_model::register_decl(func_decl * d, func_interp * fi, bool aux) {
|
||||
SASSERT(d->get_arity() > 0);
|
||||
SASSERT(!m_finterp.contains(d));
|
||||
m_decls.push_back(d);
|
||||
m_asts.push_back(d);
|
||||
m_finterp.insert(d, fi);
|
||||
m_func_decls.push_back(d);
|
||||
if (aux)
|
||||
m_aux_decls.insert(d);
|
||||
void proto_model::register_aux_decl(func_decl * d, func_interp * fi) {
|
||||
model_core::register_decl(d, fi);
|
||||
m_aux_decls.insert(d);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -486,6 +451,7 @@ void proto_model::cleanup() {
|
|||
m_finterp.find(faux, fi);
|
||||
SASSERT(fi != 0);
|
||||
m_finterp.erase(faux);
|
||||
m_manager.dec_ref(faux);
|
||||
dealloc(fi);
|
||||
}
|
||||
}
|
||||
|
@ -666,20 +632,16 @@ model * proto_model::mk_model() {
|
|||
decl2finterp::iterator end2 = m_finterp.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
m->register_decl(it2->m_key, it2->m_value);
|
||||
m_manager.dec_ref(it2->m_key);
|
||||
}
|
||||
|
||||
m_finterp.reset(); // m took the ownership of the func_interp's
|
||||
|
||||
unsigned sz = get_num_uninterpreted_sorts();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
sort * s = get_uninterpreted_sort(i);
|
||||
TRACE("proto_model", tout << "copying uninterpreted sorts...\n" << mk_pp(s, m_manager) << "\n";);
|
||||
ptr_buffer<expr> buf;
|
||||
obj_hashtable<expr> const & u = get_known_universe(s);
|
||||
obj_hashtable<expr>::iterator it = u.begin();
|
||||
obj_hashtable<expr>::iterator end = u.end();
|
||||
for (; it != end; ++it) {
|
||||
buf.push_back(*it);
|
||||
}
|
||||
ptr_vector<expr> const& buf = get_universe(s);
|
||||
m->register_usort(s, buf.size(), buf.c_ptr());
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ Revision History:
|
|||
#include"params.h"
|
||||
|
||||
class proto_model : public model_core {
|
||||
ast_ref_vector m_asts;
|
||||
plugin_manager<value_factory> m_factories;
|
||||
user_sort_factory * m_user_sort_factory;
|
||||
simplifier & m_simplifier;
|
||||
|
@ -48,8 +47,6 @@ class proto_model : public model_core {
|
|||
|
||||
bool m_model_partial;
|
||||
|
||||
void reset_finterp();
|
||||
|
||||
expr * mk_some_interp_for(func_decl * d);
|
||||
|
||||
// Invariant: m_decls subset m_func_decls union m_const_decls union union m_value_decls
|
||||
|
@ -63,7 +60,7 @@ class proto_model : public model_core {
|
|||
|
||||
public:
|
||||
proto_model(ast_manager & m, simplifier & s, params_ref const & p = params_ref());
|
||||
virtual ~proto_model();
|
||||
virtual ~proto_model() {}
|
||||
|
||||
void register_factory(value_factory * f) { m_factories.register_plugin(f); }
|
||||
|
||||
|
@ -73,7 +70,7 @@ public:
|
|||
|
||||
value_factory * get_factory(family_id fid);
|
||||
|
||||
expr * get_some_value(sort * s);
|
||||
virtual expr * get_some_value(sort * s);
|
||||
|
||||
bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2);
|
||||
|
||||
|
@ -84,8 +81,7 @@ public:
|
|||
//
|
||||
// Primitives for building models
|
||||
//
|
||||
void register_decl(func_decl * d, expr * v);
|
||||
void register_decl(func_decl * f, func_interp * fi, bool aux = false);
|
||||
void register_aux_decl(func_decl * f, func_interp * fi);
|
||||
void reregister_decl(func_decl * f, func_interp * new_fi, func_decl * f_aux);
|
||||
void compress();
|
||||
void cleanup();
|
||||
|
|
|
@ -322,20 +322,17 @@ namespace smt {
|
|||
for (; it != end; ++it) {
|
||||
if (m_context->is_relevant(*it)) {
|
||||
app* e = (*it)->get_owner();
|
||||
for (unsigned i = 0; i < e->get_num_args(); ++i) {
|
||||
args[num_decls - i - 1] = e->get_arg(i);
|
||||
SASSERT(e->get_num_args() == num_decls);
|
||||
for (unsigned i = 0; i < num_decls; ++i) {
|
||||
args[i] = e->get_arg(i);
|
||||
}
|
||||
sub(q->get_expr(), num_decls, args.c_ptr(), tmp);
|
||||
m_curr_model->eval(tmp, result, true);
|
||||
if (m.is_true(result)) {
|
||||
continue;
|
||||
}
|
||||
if (m.is_false(result)) {
|
||||
TRACE("model_checker", tout << tmp << "\nevaluates to:\n" << result << "\n";);
|
||||
add_instance(q, args, 0);
|
||||
return false;
|
||||
}
|
||||
TRACE("model_checker", tout << tmp << "evaluates to undetermined " << result << "\n";);
|
||||
is_undef = true;
|
||||
}
|
||||
}
|
||||
return !is_undef;
|
||||
|
@ -395,7 +392,7 @@ namespace smt {
|
|||
verbose_stream() << "(smt.mbqi :checking " << q->get_qid() << ")\n";
|
||||
}
|
||||
found_relevant = true;
|
||||
if (q->get_qid() == symbol(":rec-fun")) {
|
||||
if (m.is_rec_fun_def(q)) {
|
||||
if (!check_rec_fun(q)) {
|
||||
num_failures++;
|
||||
}
|
||||
|
|
|
@ -915,7 +915,7 @@ namespace smt {
|
|||
}
|
||||
func_interp * rpi = alloc(func_interp, m_manager, 1);
|
||||
rpi->set_else(pi);
|
||||
m_model->register_decl(p, rpi, true);
|
||||
m_model->register_aux_decl(p, rpi);
|
||||
n->set_proj(p);
|
||||
}
|
||||
|
||||
|
@ -928,7 +928,7 @@ namespace smt {
|
|||
func_decl * p = m_manager.mk_fresh_func_decl(1, &s, s);
|
||||
func_interp * pi = alloc(func_interp, m_manager, 1);
|
||||
pi->set_else(else_val);
|
||||
m_model->register_decl(p, pi, true);
|
||||
m_model->register_aux_decl(p, pi);
|
||||
ptr_buffer<expr>::const_iterator it = values.begin();
|
||||
ptr_buffer<expr>::const_iterator end = values.end();
|
||||
for (; it != end; ++it) {
|
||||
|
|
|
@ -516,43 +516,6 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Auxiliary functor for method register_indirect_elim_decls.
|
||||
*/
|
||||
class mk_interp_proc {
|
||||
context & m_context;
|
||||
proto_model & m_model;
|
||||
public:
|
||||
mk_interp_proc(context & ctx, proto_model & m):
|
||||
m_context(ctx),
|
||||
m_model(m) {
|
||||
}
|
||||
|
||||
void operator()(var * n) {
|
||||
}
|
||||
|
||||
void operator()(app * n) {
|
||||
if (!is_uninterp(n))
|
||||
return; // n is interpreted
|
||||
func_decl * d = n->get_decl();
|
||||
if (m_model.has_interpretation(d))
|
||||
return; // declaration already has an interpretation.
|
||||
if (n->get_num_args() == 0) {
|
||||
sort * r = d->get_range();
|
||||
expr * v = m_model.get_some_value(r);
|
||||
m_model.register_decl(d, v);
|
||||
}
|
||||
else {
|
||||
func_interp * fi = alloc(func_interp, m_context.get_manager(), d->get_arity());
|
||||
m_model.register_decl(d, fi);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(quantifier * n) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
proto_model * model_generator::mk_model() {
|
||||
SASSERT(!m_model);
|
||||
TRACE("func_interp_bug", m_context->display(tout););
|
||||
|
|
|
@ -40,7 +40,6 @@ namespace smt {
|
|||
ptr_vector<quantifier> m_quantifiers;
|
||||
scoped_ptr<quantifier_manager_plugin> m_plugin;
|
||||
unsigned m_num_instances;
|
||||
symbol m_rec_fun;
|
||||
|
||||
imp(quantifier_manager & wrapper, context & ctx, smt_params & p, quantifier_manager_plugin * plugin):
|
||||
m_wrapper(wrapper),
|
||||
|
@ -48,8 +47,7 @@ namespace smt {
|
|||
m_params(p),
|
||||
m_qi_queue(m_wrapper, ctx, p),
|
||||
m_qstat_gen(ctx.get_manager(), ctx.get_region()),
|
||||
m_plugin(plugin),
|
||||
m_rec_fun(":rec-fun") {
|
||||
m_plugin(plugin) {
|
||||
m_num_instances = 0;
|
||||
m_qi_queue.setup();
|
||||
}
|
||||
|
@ -187,7 +185,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
bool check_quantifier(quantifier* q) {
|
||||
return m_context.is_relevant(q) && m_context.get_assignment(q) == l_true; // TBD: && q->get_qid() != m_rec_fun;
|
||||
return m_context.is_relevant(q) && m_context.get_assignment(q) == l_true; // TBD: && !m_context->get_manager().is_rec_fun_def(q);
|
||||
}
|
||||
|
||||
bool quick_check_quantifiers() {
|
||||
|
|
|
@ -547,6 +547,10 @@ namespace smt {
|
|||
out << "\n";
|
||||
}
|
||||
|
||||
bool theory_datatype::include_func_interp(func_decl* f) {
|
||||
return false; // return m_util.is_accessor(f);
|
||||
}
|
||||
|
||||
void theory_datatype::init_model(model_generator & m) {
|
||||
m_factory = alloc(datatype_factory, get_manager(), m.get_model());
|
||||
m.register_factory(m_factory);
|
||||
|
|
|
@ -111,6 +111,8 @@ namespace smt {
|
|||
static void after_merge_eh(theory_var r1, theory_var r2, theory_var v1, theory_var v2) {}
|
||||
void unmerge_eh(theory_var v1, theory_var v2);
|
||||
virtual char const * get_name() const { return "datatype"; }
|
||||
virtual bool include_func_interp(func_decl* f);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue