3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

add recfun to API

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-10-27 11:41:18 -05:00
parent c5cbf985ca
commit 51a0022450
11 changed files with 191 additions and 42 deletions

View file

@ -38,6 +38,8 @@ Revision History:
#include "util/cancel_eh.h"
#include "util/scoped_timer.h"
#include "ast/pp_params.hpp"
#include "ast/expr_abstract.h"
extern bool is_numeral_sort(Z3_context c, Z3_sort ty);
@ -110,6 +112,54 @@ extern "C" {
Z3_CATCH_RETURN(nullptr);
}
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s, unsigned domain_size, Z3_sort const* domain,
Z3_sort range) {
Z3_TRY;
LOG_Z3_mk_rec_func_decl(c, s, domain_size, domain, range);
RESET_ERROR_CODE();
//
recfun::promise_def def =
mk_c(c)->recfun().get_plugin().mk_def(to_symbol(s),
domain_size,
to_sorts(domain),
to_sort(range));
func_decl* d = def.get_def()->get_decl();
mk_c(c)->save_ast_trail(d);
RETURN_Z3(of_func_decl(d));
Z3_CATCH_RETURN(nullptr);
}
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body) {
Z3_TRY;
LOG_Z3_add_rec_def(c, f, n, args, body);
func_decl* d = to_func_decl(f);
ast_manager& m = mk_c(c)->m();
recfun::decl::plugin& p = mk_c(c)->recfun().get_plugin();
expr_ref abs_body(m);
expr_ref_vector _args(m);
var_ref_vector _vars(m);
for (unsigned i = 0; i < n; ++i) {
_args.push_back(to_expr(args[i]));
_vars.push_back(m.mk_var(n - i - 1, m.get_sort(_args.back())));
if (m.get_sort(_args.back()) != d->get_domain(i)) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
}
expr_abstract(m, 0, n, _args.c_ptr(), to_expr(body), abs_body);
recfun::promise_def pd = p.get_promise_def(d);
if (!pd.get_def()) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
if (m.get_sort(abs_body) != d->get_range()) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
p.set_definition(pd, n, _vars.c_ptr(), abs_body);
Z3_CATCH;
}
Z3_ast Z3_API Z3_mk_app(Z3_context c, Z3_func_decl d, unsigned num_args, Z3_ast const * args) {
Z3_TRY;
LOG_Z3_mk_app(c, d, num_args, args);

View file

@ -79,6 +79,7 @@ namespace api {
m_datalog_util(m()),
m_fpa_util(m()),
m_sutil(m()),
m_recfun(m()),
m_last_result(m()),
m_ast_trail(m()),
m_pmanager(m_limit) {

View file

@ -29,6 +29,7 @@ Revision History:
#include "ast/datatype_decl_plugin.h"
#include "ast/dl_decl_plugin.h"
#include "ast/fpa_decl_plugin.h"
#include "ast/recfun_decl_plugin.h"
#include "smt/smt_kernel.h"
#include "smt/params/smt_params.h"
#include "util/event_handler.h"
@ -62,6 +63,7 @@ namespace api {
datalog::dl_decl_util m_datalog_util;
fpa_util m_fpa_util;
seq_util m_sutil;
recfun_util m_recfun;
// Support for old solver API
smt_params m_fparams;
@ -128,6 +130,7 @@ namespace api {
fpa_util & fpautil() { return m_fpa_util; }
datatype_util& dtutil() { return m_dt_plugin->u(); }
seq_util& sutil() { return m_sutil; }
recfun_util& recfun() { return m_recfun; }
family_id get_basic_fid() const { return m_basic_fid; }
family_id get_array_fid() const { return m_array_fid; }
family_id get_arith_fid() const { return m_arith_fid; }

View file

@ -311,6 +311,13 @@ namespace z3 {
func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range);
func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range);
func_decl recfun(symbol const & name, unsigned arity, sort const * domain, sort const & range);
func_decl recfun(char const * name, unsigned arity, sort const * domain, sort const & range);
func_decl recfun(char const * name, sort const & domain, sort const & range);
func_decl recfun(char const * name, sort const & d1, sort const & d2, sort const & range);
void recdef(func_decl, expr_vector const& args, expr const& body);
expr constant(symbol const & name, sort const & s);
expr constant(char const * name, sort const & s);
expr bool_const(char const * name);
@ -2815,6 +2822,37 @@ namespace z3 {
return func_decl(*this, f);
}
inline func_decl context::recfun(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
array<Z3_sort> args(arity);
for (unsigned i = 0; i < arity; i++) {
check_context(domain[i], range);
args[i] = domain[i];
}
Z3_func_decl f = Z3_mk_rec_func_decl(m_ctx, name, arity, args.ptr(), range);
check_error();
return func_decl(*this, f);
}
inline func_decl context::recfun(char const * name, unsigned arity, sort const * domain, sort const & range) {
return recfun(str_symbol(name), arity, domain, range);
}
inline func_decl context::recfun(char const * name, sort const& d1, sort const & range) {
return recfun(str_symbol(name), 1, &d1, range);
}
inline func_decl context::recfun(char const * name, sort const& d1, sort const& d2, sort const & range) {
sort dom[2] = { d1, d2 };
return recfun(str_symbol(name), 2, dom, range);
}
void context::recdef(func_decl f, expr_vector const& args, expr const& body) {
check_context(f, args); check_context(f, body);
array<Z3_ast> vars(args);
Z3_add_rec_def(f.ctx(), f, vars.size(), vars.ptr(), body);
}
inline expr context::constant(symbol const & name, sort const & s) {
Z3_ast r = Z3_mk_const(m_ctx, name, s);
check_error();
@ -2976,6 +3014,19 @@ namespace z3 {
return range.ctx().function(name.c_str(), domain, range);
}
inline func_decl recfun(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
return range.ctx().recfun(name, arity, domain, range);
}
inline func_decl recfun(char const * name, unsigned arity, sort const * domain, sort const & range) {
return range.ctx().recfun(name, arity, domain, range);
}
inline func_decl recfun(char const * name, sort const& d1, sort const & range) {
return range.ctx().recfun(name, d1, range);
}
inline func_decl recfun(char const * name, sort const& d1, sort const& d2, sort const & range) {
return range.ctx().recfun(name, d1, d2, range);
}
inline expr select(expr const & a, expr const & i) {
check_context(a, i);
Z3_ast r = Z3_mk_select(a.ctx(), a, i);

View file

@ -2081,6 +2081,7 @@ extern "C" {
Z3_sort range);
/**
\brief Create a constant or function application.
@ -2140,6 +2141,48 @@ extern "C" {
def_API('Z3_mk_fresh_const', AST, (_in(CONTEXT), _in(STRING), _in(SORT)))
*/
Z3_ast Z3_API Z3_mk_fresh_const(Z3_context c, Z3_string prefix, Z3_sort ty);
/**
\brief Declare a recursive function
\param c logical context.
\param s name of the function.
\param domain_size number of arguments. It should be greater than 0.
\param domain array containing the sort of each argument. The array must contain domain_size elements.
\param range sort of the constant or the return sort of the function.
After declaring recursive function, it should be associated with a recursive definition #Z3_mk_rec_def.
The function #Z3_mk_app can be used to create a constant or function
application.
\sa Z3_mk_app
\sa Z3_mk_rec_def
def_API('Z3_mk_rec_func_decl', FUNC_DECL, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SORT), _in(SORT)))
*/
Z3_func_decl Z3_API Z3_mk_rec_func_decl(Z3_context c, Z3_symbol s,
unsigned domain_size, Z3_sort const domain[],
Z3_sort range);
/**
\brief Define the body of a recursive function.
\param c logical context.
\param f function declaration.
\param n number of arguments to the function
\param args constants that are used as arguments to the recursive function in the definition.
\param body body of the recursive function
After declaring a recursive function or a collection of mutually recursive functions, use
this function to provide the definition for the recursive function.
\sa Z3_mk_rec_func_decl
def_API('Z3_add_rec_def', VOID, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT), _in_array(2, AST), _in(AST)))
*/
void Z3_API Z3_add_rec_def(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast args[], Z3_ast body);
/*@}*/
/** @name Propositional Logic and Equality */