3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-08 00:05:46 +00:00

wip: add recursive functions

This commit is contained in:
Simon Cruanes 2017-11-07 15:57:27 +01:00
parent fba22d2fac
commit d5e134dd94
19 changed files with 1362 additions and 4 deletions

View file

@ -678,6 +678,8 @@ bool cmd_context::logic_has_datatype() const {
return !has_logic() || smt_logics::logic_has_datatype(m_logic);
}
bool cmd_context::logic_has_recfun() const { return true; }
void cmd_context::init_manager_core(bool new_manager) {
SASSERT(m_manager != 0);
SASSERT(m_pmanager != 0);
@ -690,6 +692,7 @@ void cmd_context::init_manager_core(bool new_manager) {
register_plugin(symbol("bv"), alloc(bv_decl_plugin), logic_has_bv());
register_plugin(symbol("array"), alloc(array_decl_plugin), logic_has_array());
register_plugin(symbol("datatype"), alloc(datatype_decl_plugin), logic_has_datatype());
register_plugin(symbol("recfun"), alloc(recfun_decl_plugin), logic_has_recfun());
register_plugin(symbol("seq"), alloc(seq_decl_plugin), logic_has_seq());
register_plugin(symbol("pb"), alloc(pb_decl_plugin), logic_has_pb());
register_plugin(symbol("fpa"), alloc(fpa_decl_plugin), logic_has_fpa());
@ -705,6 +708,7 @@ void cmd_context::init_manager_core(bool new_manager) {
load_plugin(symbol("bv"), logic_has_bv(), fids);
load_plugin(symbol("array"), logic_has_array(), fids);
load_plugin(symbol("datatype"), logic_has_datatype(), fids);
load_plugin(symbol("recfun"), logic_has_recfun(), fids);
load_plugin(symbol("seq"), logic_has_seq(), fids);
load_plugin(symbol("fpa"), logic_has_fpa(), fids);
load_plugin(symbol("pb"), logic_has_pb(), fids);
@ -868,7 +872,24 @@ void cmd_context::insert(symbol const & s, object_ref * r) {
m_object_refs.insert(s, r);
}
void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e) {
recfun_decl_plugin * cmd_context::get_recfun_plugin() {
ast_manager & m = get_ast_manager();
family_id id = m.get_family_id("recfun");
recfun_decl_plugin* p = reinterpret_cast<recfun_decl_plugin*>(m.get_plugin(id));
SASSERT(p);
return p;
}
recfun::promise_def cmd_context::decl_rec_fun(const symbol &name, unsigned int arity, sort *const *domain, sort *range) {
SASSERT(logic_has_recfun());
recfun_decl_plugin* p = get_recfun_plugin();
recfun::promise_def def = p->mk_def(name, arity, domain, range);
return def;
}
// insert a recursive function as a regular quantified axiom
void cmd_context::insert_rec_fun_as_axiom(func_decl *f, expr_ref_vector const& binding, svector<symbol> const &ids, expr* e) {
expr_ref eq(m());
app_ref lhs(m());
lhs = m().mk_app(f, binding.size(), binding.c_ptr());
@ -899,6 +920,31 @@ void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, s
assert_expr(eq);
}
// TODO: make this a parameter
#define USE_NATIVE_RECFUN 1
void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* rhs) {
TRACE("recfun", tout<<"define recfun " << f->get_name()
<<" = " << mk_pp(rhs, m()) << "\n";);
if (! USE_NATIVE_RECFUN) {
// just use an axiom
insert_rec_fun_as_axiom(f, binding, ids, rhs);
return;
}
recfun_decl_plugin* p = get_recfun_plugin();
var_ref_vector vars(m());
for (expr* b : binding) {
SASSERT(is_var(b));
vars.push_back(to_var(b));
}
recfun::promise_def d = p->get_promise_def(f->get_name());
p->set_definition(d, vars.size(), vars.c_ptr(), rhs);
}
func_decl * cmd_context::find_func_decl(symbol const & s) const {
builtin_decl d;
if (m_builtin_decls.find(s, d)) {

View file

@ -29,6 +29,7 @@ Notes:
#include "util/dictionary.h"
#include "solver/solver.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/recfun_decl_plugin.h"
#include "util/stopwatch.h"
#include "util/cmd_context_types.h"
#include "util/event_handler.h"
@ -289,6 +290,7 @@ protected:
bool logic_has_array() const;
bool logic_has_datatype() const;
bool logic_has_fpa() const;
bool logic_has_recfun() const;
void print_unsupported_msg() { regular_stream() << "unsupported" << std::endl; }
void print_unsupported_info(symbol const& s, int line, int pos) { if (s != symbol::null) diagnostic_stream() << "; " << s << " line: " << line << " position: " << pos << std::endl;}
@ -304,6 +306,7 @@ protected:
void erase_macro(symbol const& s);
bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const;
recfun_decl_plugin * get_recfun_plugin();
public:
cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);
@ -382,9 +385,11 @@ 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 insert_rec_fun_as_axiom(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e);
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;
recfun::promise_def decl_rec_fun(const symbol &name, unsigned int arity, sort *const *domain, sort *range);
psort_decl * find_psort_decl(symbol const & s) const;
cmd * find_cmd(symbol const & s) const;
sexpr * find_user_tactic(symbol const & s) const;