mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
merged with unstable
This commit is contained in:
commit
3a0947b3ba
413 changed files with 31618 additions and 17204 deletions
|
@ -373,7 +373,7 @@ extern "C" {
|
|||
scoped_anum_vector roots(_am);
|
||||
{
|
||||
cancel_eh<algebraic_numbers::manager> eh(_am);
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
scoped_timer timer(mk_c(c)->params().m_timeout, &eh);
|
||||
vector_var2anum v2a(as);
|
||||
_am.isolate_roots(_p, v2a, roots);
|
||||
|
@ -408,7 +408,7 @@ extern "C" {
|
|||
}
|
||||
{
|
||||
cancel_eh<algebraic_numbers::manager> eh(_am);
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
scoped_timer timer(mk_c(c)->params().m_timeout, &eh);
|
||||
vector_var2anum v2a(as);
|
||||
int r = _am.eval_sign_at(_p, v2a);
|
||||
|
|
|
@ -46,7 +46,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_int_symbol(c, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i < 0 || (unsigned)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
|
||||
if (i < 0 || (size_t)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0;
|
||||
}
|
||||
|
@ -682,7 +682,7 @@ extern "C" {
|
|||
th_rewriter m_rw(m, p);
|
||||
expr_ref result(m);
|
||||
cancel_eh<th_rewriter> eh(m_rw);
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
|
@ -1072,6 +1072,16 @@ extern "C" {
|
|||
case OP_BV2INT: return Z3_OP_BV2INT;
|
||||
case OP_CARRY: return Z3_OP_CARRY;
|
||||
case OP_XOR3: return Z3_OP_XOR3;
|
||||
case OP_BSMUL_NO_OVFL:
|
||||
case OP_BUMUL_NO_OVFL:
|
||||
case OP_BSMUL_NO_UDFL:
|
||||
case OP_BSDIV_I:
|
||||
case OP_BUDIV_I:
|
||||
case OP_BSREM_I:
|
||||
case OP_BUREM_I:
|
||||
case OP_BSMOD_I:
|
||||
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
|
|
|
@ -121,10 +121,20 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
unsigned sz = Z3_get_bv_sort_size(c, s);
|
||||
rational max_bound = power(rational(2), sz);
|
||||
Z3_ast bound = Z3_mk_numeral(c, max_bound.to_string().c_str(), int_s);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, Z3_mk_int(c, 0, s));
|
||||
Z3_inc_ref(c, bound);
|
||||
Z3_ast zero = Z3_mk_int(c, 0, s);
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, zero);
|
||||
Z3_inc_ref(c, pred);
|
||||
// if n <_sigend 0 then r - s^sz else r
|
||||
Z3_ast args[2] = { r, bound };
|
||||
Z3_ast res = Z3_mk_ite(c, pred, Z3_mk_sub(c, 2, args), r);
|
||||
Z3_ast sub = Z3_mk_sub(c, 2, args);
|
||||
Z3_inc_ref(c, sub);
|
||||
Z3_ast res = Z3_mk_ite(c, pred, sub, r);
|
||||
Z3_dec_ref(c, bound);
|
||||
Z3_dec_ref(c, pred);
|
||||
Z3_dec_ref(c, sub);
|
||||
Z3_dec_ref(c, zero);
|
||||
RETURN_Z3(res);
|
||||
}
|
||||
else {
|
||||
|
@ -156,7 +166,14 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return Z3_mk_bvshl(c, Z3_mk_int64(c, 1, s), Z3_mk_int64(c, sz - 1, s));
|
||||
Z3_ast x = Z3_mk_int64(c, 1, s);
|
||||
Z3_inc_ref(c, x);
|
||||
Z3_ast y = Z3_mk_int64(c, sz - 1, s);
|
||||
Z3_inc_ref(c, y);
|
||||
Z3_ast result = Z3_mk_bvshl(c, x, y);
|
||||
Z3_dec_ref(c, x);
|
||||
Z3_dec_ref(c, y);
|
||||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -177,17 +194,40 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
RESET_ERROR_CODE();
|
||||
if (is_signed) {
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
Z3_ast args[2] = { Z3_mk_bvslt(c, zero, t1), Z3_mk_bvslt(c, zero, t2) };
|
||||
Z3_inc_ref(c, r);
|
||||
Z3_ast l1 = Z3_mk_bvslt(c, zero, t1);
|
||||
Z3_inc_ref(c, l1);
|
||||
Z3_ast l2 = Z3_mk_bvslt(c, zero, t2);
|
||||
Z3_inc_ref(c, l2);
|
||||
Z3_ast args[2] = { l1, l2 };
|
||||
Z3_ast args_pos = Z3_mk_and(c, 2, args);
|
||||
return Z3_mk_implies(c, args_pos, Z3_mk_bvslt(c, zero, r));
|
||||
Z3_inc_ref(c, args_pos);
|
||||
Z3_ast result = Z3_mk_implies(c, args_pos, Z3_mk_bvslt(c, zero, r));
|
||||
Z3_dec_ref(c, r);
|
||||
Z3_dec_ref(c, l1);
|
||||
Z3_dec_ref(c, l2);
|
||||
Z3_dec_ref(c, args_pos);
|
||||
Z3_dec_ref(c, zero);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
unsigned sz = Z3_get_bv_sort_size(c, Z3_get_sort(c, t1));
|
||||
t1 = Z3_mk_zero_ext(c, 1, t1);
|
||||
Z3_inc_ref(c, t1);
|
||||
t2 = Z3_mk_zero_ext(c, 1, t2);
|
||||
Z3_inc_ref(c, t2);
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
return Z3_mk_eq(c, Z3_mk_extract(c, sz, sz, r), Z3_mk_int(c, 0, Z3_mk_bv_sort(c, 1)));
|
||||
Z3_inc_ref(c, r);
|
||||
Z3_ast ex = Z3_mk_extract(c, sz, sz, r);
|
||||
Z3_inc_ref(c, ex);
|
||||
Z3_ast result = Z3_mk_eq(c, ex, Z3_mk_int(c, 0, Z3_mk_bv_sort(c, 1)));
|
||||
Z3_dec_ref(c, t1);
|
||||
Z3_dec_ref(c, t2);
|
||||
Z3_dec_ref(c, ex);
|
||||
Z3_dec_ref(c, r);
|
||||
return result;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -197,10 +237,26 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
Z3_ast args[2] = { Z3_mk_bvslt(c, t1, zero), Z3_mk_bvslt(c, t2, zero) };
|
||||
Z3_inc_ref(c, r);
|
||||
Z3_ast l1 = Z3_mk_bvslt(c, t1, zero);
|
||||
Z3_inc_ref(c, l1);
|
||||
Z3_ast l2 = Z3_mk_bvslt(c, t2, zero);
|
||||
Z3_inc_ref(c, l2);
|
||||
Z3_ast args[2] = { l1, l2 };
|
||||
Z3_ast args_neg = Z3_mk_and(c, 2, args);
|
||||
return Z3_mk_implies(c, args_neg, Z3_mk_bvslt(c, r, zero));
|
||||
Z3_inc_ref(c, args_neg);
|
||||
Z3_ast lt = Z3_mk_bvslt(c, r, zero);
|
||||
Z3_inc_ref(c, lt);
|
||||
Z3_ast result = Z3_mk_implies(c, args_neg, lt);
|
||||
Z3_dec_ref(c, lt);
|
||||
Z3_dec_ref(c, l1);
|
||||
Z3_dec_ref(c, l2);
|
||||
Z3_dec_ref(c, r);
|
||||
Z3_dec_ref(c, args_neg);
|
||||
Z3_dec_ref(c, zero);
|
||||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -208,12 +264,28 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort s = Z3_get_sort(c, t2);
|
||||
Z3_ast minus_t2 = Z3_mk_bvneg(c, t2);
|
||||
Z3_inc_ref(c, minus_t2);
|
||||
Z3_sort s = Z3_get_sort(c, t2);
|
||||
Z3_ast min = Z3_mk_bvsmin(c, s);
|
||||
return Z3_mk_ite(c, Z3_mk_eq(c, t2, min),
|
||||
Z3_mk_bvslt(c, t1, Z3_mk_int(c, 0, s)),
|
||||
Z3_mk_bvadd_no_overflow(c, t1, minus_t2, true));
|
||||
Z3_inc_ref(c, min);
|
||||
Z3_ast x = Z3_mk_eq(c, t2, min);
|
||||
Z3_inc_ref(c, x);
|
||||
Z3_ast zero = Z3_mk_int(c, 0, s);
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast y = Z3_mk_bvslt(c, t1, zero);
|
||||
Z3_inc_ref(c, y);
|
||||
Z3_ast z = Z3_mk_bvadd_no_overflow(c, t1, minus_t2, true);
|
||||
Z3_inc_ref(c, z);
|
||||
Z3_ast result = Z3_mk_ite(c, x, y, z);
|
||||
mk_c(c)->save_ast_trail(to_app(result));
|
||||
Z3_dec_ref(c, minus_t2);
|
||||
Z3_dec_ref(c, min);
|
||||
Z3_dec_ref(c, x);
|
||||
Z3_dec_ref(c, y);
|
||||
Z3_dec_ref(c, z);
|
||||
Z3_dec_ref(c, zero);
|
||||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -222,10 +294,19 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
RESET_ERROR_CODE();
|
||||
if (is_signed) {
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast minus_t2 = Z3_mk_bvneg(c, t2);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
return Z3_mk_implies(c, Z3_mk_bvslt(c, zero, t2), Z3_mk_bvadd_no_underflow(c, t1, minus_t2));
|
||||
Z3_inc_ref(c, minus_t2);
|
||||
Z3_ast x = Z3_mk_bvslt(c, zero, t2);
|
||||
Z3_inc_ref(c, x);
|
||||
Z3_ast y = Z3_mk_bvadd_no_underflow(c, t1, minus_t2);
|
||||
Z3_inc_ref(c, y);
|
||||
Z3_ast result = Z3_mk_implies(c, x, y);
|
||||
Z3_dec_ref(c, zero);
|
||||
Z3_dec_ref(c, minus_t2);
|
||||
Z3_dec_ref(c, x);
|
||||
Z3_dec_ref(c, y);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return Z3_mk_bvule(c, t2, t1);
|
||||
|
@ -267,12 +348,24 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort s = Z3_get_sort(c, t1);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast min = Z3_mk_bvmsb(c, s);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast args[2] = { Z3_mk_eq(c, t1, min),
|
||||
Z3_mk_eq(c, t2, Z3_mk_int(c, -1, s)) };
|
||||
return Z3_mk_not(c, Z3_mk_and(c, 2, args));
|
||||
Z3_inc_ref(c, min);
|
||||
Z3_ast x = Z3_mk_eq(c, t1, min);
|
||||
Z3_inc_ref(c, x);
|
||||
Z3_ast y = Z3_mk_int(c, -1, s);
|
||||
Z3_inc_ref(c, y);
|
||||
Z3_ast z = Z3_mk_eq(c, t2, y);
|
||||
Z3_inc_ref(c, z);
|
||||
Z3_ast args[2] = { x, z };
|
||||
Z3_ast u = Z3_mk_and(c, 2, args);
|
||||
Z3_inc_ref(c, u);
|
||||
Z3_ast result = Z3_mk_not(c, u);
|
||||
Z3_dec_ref(c, min);
|
||||
Z3_dec_ref(c, x);
|
||||
Z3_dec_ref(c, y);
|
||||
Z3_dec_ref(c, z);
|
||||
Z3_dec_ref(c, u);
|
||||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace api {
|
|||
if (m_interruptable)
|
||||
(*m_interruptable)();
|
||||
m().set_cancel(true);
|
||||
if (m_rcf_manager.get() == 0)
|
||||
if (m_rcf_manager.get() != 0)
|
||||
m_rcf_manager->set_cancel(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ Revision History:
|
|||
#include"api_datalog.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"dl_context.h"
|
||||
#include"ast_pp.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"api_log_macros.h"
|
||||
|
@ -29,104 +28,126 @@ Revision History:
|
|||
#include"dl_cmds.h"
|
||||
#include"cmd_context.h"
|
||||
#include"smt2parser.h"
|
||||
#include"dl_context.h"
|
||||
#include"dl_register_engine.h"
|
||||
#include"dl_external_relation.h"
|
||||
#include"dl_decl_plugin.h"
|
||||
#include"rel_context.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
fixedpoint_context::fixedpoint_context(ast_manager& m, smt_params& p) :
|
||||
m_state(0),
|
||||
m_reduce_app(0),
|
||||
m_reduce_assign(0),
|
||||
m_context(m, p),
|
||||
m_trail(m) {}
|
||||
|
||||
|
||||
void fixedpoint_context::set_state(void* state) {
|
||||
SASSERT(!m_state);
|
||||
m_state = state;
|
||||
symbol name("datalog_relation");
|
||||
ast_manager& m = m_context.get_manager();
|
||||
if (!m.has_plugin(name)) {
|
||||
m.register_plugin(name, alloc(datalog::dl_decl_plugin));
|
||||
}
|
||||
datalog::relation_manager& r = m_context.get_rel_context().get_rmanager();
|
||||
r.register_plugin(alloc(datalog::external_relation_plugin, *this, r));
|
||||
}
|
||||
|
||||
void fixedpoint_context::reduce(func_decl* f, unsigned num_args, expr * const* args, expr_ref& result) {
|
||||
expr* r = 0;
|
||||
if (m_reduce_app) {
|
||||
m_reduce_app(m_state, f, num_args, args, &r);
|
||||
result = r;
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
}
|
||||
m_trail.push_back(r);
|
||||
}
|
||||
// allow fallthrough.
|
||||
if (r == 0) {
|
||||
|
||||
class fixedpoint_context : public datalog::external_relation_context {
|
||||
void * m_state;
|
||||
reduce_app_callback_fptr m_reduce_app;
|
||||
reduce_assign_callback_fptr m_reduce_assign;
|
||||
datalog::register_engine m_register_engine;
|
||||
datalog::context m_context;
|
||||
ast_ref_vector m_trail;
|
||||
public:
|
||||
fixedpoint_context(ast_manager& m, smt_params& p):
|
||||
m_state(0),
|
||||
m_reduce_app(0),
|
||||
m_reduce_assign(0),
|
||||
m_context(m, m_register_engine, p),
|
||||
m_trail(m) {}
|
||||
|
||||
virtual ~fixedpoint_context() {}
|
||||
family_id get_family_id() const { return const_cast<datalog::context&>(m_context).get_decl_util().get_family_id(); }
|
||||
void set_state(void* state) {
|
||||
SASSERT(!m_state);
|
||||
m_state = state;
|
||||
symbol name("datalog_relation");
|
||||
ast_manager& m = m_context.get_manager();
|
||||
result = m.mk_app(f, num_args, args);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite terms passed in outs vector with values computed by function.
|
||||
void fixedpoint_context::reduce_assign(func_decl* f, unsigned num_args, expr * const* args, unsigned num_out, expr* const* outs) {
|
||||
if (m_reduce_assign) {
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
if (!m.has_plugin(name)) {
|
||||
m.register_plugin(name, alloc(datalog::dl_decl_plugin));
|
||||
}
|
||||
datalog::rel_context_base* rel = m_context.get_rel_context();
|
||||
if (rel) {
|
||||
datalog::relation_manager& r = rel->get_rmanager();
|
||||
r.register_plugin(alloc(datalog::external_relation_plugin, *this, r));
|
||||
}
|
||||
m_reduce_assign(m_state, f, num_args, args, num_out, outs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fixedpoint_context::add_rule(expr* rule, symbol const& name) {
|
||||
m_context.add_rule(rule, name);
|
||||
}
|
||||
|
||||
void fixedpoint_context::update_rule(expr* rule, symbol const& name) {
|
||||
m_context.update_rule(rule, name);
|
||||
}
|
||||
|
||||
void fixedpoint_context::add_table_fact(func_decl* r, unsigned num_args, unsigned args[]) {
|
||||
m_context.add_table_fact(r, num_args, args);
|
||||
}
|
||||
|
||||
unsigned fixedpoint_context::get_num_levels(func_decl* pred) {
|
||||
return m_context.get_num_levels(pred);
|
||||
}
|
||||
|
||||
expr_ref fixedpoint_context::get_cover_delta(int level, func_decl* pred) {
|
||||
return m_context.get_cover_delta(level, pred);
|
||||
}
|
||||
|
||||
void fixedpoint_context::add_cover(int level, func_decl* pred, expr* predicate) {
|
||||
m_context.add_cover(level, pred, predicate);
|
||||
}
|
||||
|
||||
std::string fixedpoint_context::get_last_status() {
|
||||
datalog::execution_result status = m_context.get_status();
|
||||
switch(status) {
|
||||
case datalog::INPUT_ERROR:
|
||||
return "input error";
|
||||
case datalog::OK:
|
||||
return "ok";
|
||||
case datalog::TIMEOUT:
|
||||
return "timeout";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return "unknown";
|
||||
void set_reduce_app(reduce_app_callback_fptr f) {
|
||||
m_reduce_app = f;
|
||||
}
|
||||
}
|
||||
|
||||
std::string fixedpoint_context::to_string(unsigned num_queries, expr*const* queries) {
|
||||
std::stringstream str;
|
||||
m_context.display_smt2(num_queries, queries, str);
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void set_reduce_assign(reduce_assign_callback_fptr f) {
|
||||
m_reduce_assign = f;
|
||||
}
|
||||
virtual void reduce(func_decl* f, unsigned num_args, expr * const* args, expr_ref& result) {
|
||||
expr* r = 0;
|
||||
if (m_reduce_app) {
|
||||
m_reduce_app(m_state, f, num_args, args, &r);
|
||||
result = r;
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
}
|
||||
m_trail.push_back(r);
|
||||
}
|
||||
// allow fallthrough.
|
||||
if (r == 0) {
|
||||
ast_manager& m = m_context.get_manager();
|
||||
result = m.mk_app(f, num_args, args);
|
||||
}
|
||||
}
|
||||
virtual void reduce_assign(func_decl* f, unsigned num_args, expr * const* args, unsigned num_out, expr* const* outs) {
|
||||
if (m_reduce_assign) {
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
}
|
||||
m_reduce_assign(m_state, f, num_args, args, num_out, outs);
|
||||
}
|
||||
}
|
||||
datalog::context& ctx() { return m_context; }
|
||||
void add_rule(expr* rule, symbol const& name) {
|
||||
m_context.add_rule(rule, name);
|
||||
}
|
||||
void update_rule(expr* rule, symbol const& name) {
|
||||
m_context.update_rule(rule, name);
|
||||
}
|
||||
void add_table_fact(func_decl* r, unsigned num_args, unsigned args[]) {
|
||||
m_context.add_table_fact(r, num_args, args);
|
||||
}
|
||||
std::string get_last_status() {
|
||||
datalog::execution_result status = m_context.get_status();
|
||||
switch(status) {
|
||||
case datalog::INPUT_ERROR:
|
||||
return "input error";
|
||||
case datalog::OK:
|
||||
return "ok";
|
||||
case datalog::TIMEOUT:
|
||||
return "timeout";
|
||||
case datalog::APPROX:
|
||||
return "approximated";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
std::string to_string(unsigned num_queries, expr*const* queries) {
|
||||
std::stringstream str;
|
||||
m_context.display_smt2(num_queries, queries, str);
|
||||
return str.str();
|
||||
}
|
||||
void cancel() {
|
||||
m_context.cancel();
|
||||
}
|
||||
void reset_cancel() {
|
||||
m_context.reset_cancel();
|
||||
}
|
||||
unsigned get_num_levels(func_decl* pred) {
|
||||
return m_context.get_num_levels(pred);
|
||||
}
|
||||
expr_ref get_cover_delta(int level, func_decl* pred) {
|
||||
return m_context.get_cover_delta(level, pred);
|
||||
}
|
||||
void add_cover(int level, func_decl* pred, expr* predicate) {
|
||||
m_context.add_cover(level, pred, predicate);
|
||||
}
|
||||
void collect_param_descrs(param_descrs & p) { m_context.collect_params(p); }
|
||||
void updt_params(params_ref const& p) { m_context.updt_params(p); }
|
||||
};
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
@ -266,7 +287,7 @@ extern "C" {
|
|||
lbool r = l_undef;
|
||||
cancel_eh<api::fixedpoint_context> eh(*to_fixedpoint_ref(d));
|
||||
unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
|
@ -291,7 +312,7 @@ extern "C" {
|
|||
lbool r = l_undef;
|
||||
unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
|
||||
cancel_eh<api::fixedpoint_context> eh(*to_fixedpoint_ref(d));
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
|
@ -358,7 +379,7 @@ extern "C" {
|
|||
v->m_ast_vector.push_back(coll.m_queries[i].get());
|
||||
}
|
||||
for (unsigned i = 0; i < coll.m_rels.size(); ++i) {
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(coll.m_rels[i].get());
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(coll.m_rels[i].get(), true);
|
||||
}
|
||||
for (unsigned i = 0; i < coll.m_rules.size(); ++i) {
|
||||
to_fixedpoint_ref(d)->add_rule(coll.m_rules[i].get(), coll.m_names[i]);
|
||||
|
@ -415,7 +436,7 @@ extern "C" {
|
|||
void Z3_API Z3_fixedpoint_register_relation(Z3_context c,Z3_fixedpoint d, Z3_func_decl f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_register_relation(c, d, f);
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(to_func_decl(f));
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(to_func_decl(f), true);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,48 +22,14 @@ Revision History:
|
|||
#include"z3.h"
|
||||
#include"ast.h"
|
||||
#include"smt_params.h"
|
||||
#include"dl_external_relation.h"
|
||||
#include"dl_decl_plugin.h"
|
||||
#include"smt_kernel.h"
|
||||
#include"api_util.h"
|
||||
#include"dl_context.h"
|
||||
|
||||
typedef void (*reduce_app_callback_fptr)(void*, func_decl*, unsigned, expr*const*, expr**);
|
||||
typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*const*, unsigned, expr*const*);
|
||||
|
||||
namespace api {
|
||||
|
||||
class fixedpoint_context : public datalog::external_relation_context {
|
||||
void * m_state;
|
||||
reduce_app_callback_fptr m_reduce_app;
|
||||
reduce_assign_callback_fptr m_reduce_assign;
|
||||
datalog::context m_context;
|
||||
ast_ref_vector m_trail;
|
||||
public:
|
||||
fixedpoint_context(ast_manager& m, smt_params& p);
|
||||
virtual ~fixedpoint_context() {}
|
||||
family_id get_family_id() const { return const_cast<datalog::context&>(m_context).get_decl_util().get_family_id(); }
|
||||
void set_state(void* state);
|
||||
void set_reduce_app(reduce_app_callback_fptr f) { m_reduce_app = f; }
|
||||
void set_reduce_assign(reduce_assign_callback_fptr f) { m_reduce_assign = f; }
|
||||
virtual void reduce(func_decl* f, unsigned num_args, expr * const* args, expr_ref& result);
|
||||
virtual void reduce_assign(func_decl* f, unsigned num_args, expr * const* args, unsigned num_out, expr* const* outs);
|
||||
datalog::context& ctx() { return m_context; }
|
||||
void add_rule(expr* rule, symbol const& name);
|
||||
void update_rule(expr* rule, symbol const& name);
|
||||
void add_table_fact(func_decl* r, unsigned num_args, unsigned args[]);
|
||||
std::string get_last_status();
|
||||
std::string to_string(unsigned num_queries, expr*const* queries);
|
||||
void cancel() { m_context.cancel(); }
|
||||
void reset_cancel() { m_context.reset_cancel(); }
|
||||
|
||||
unsigned get_num_levels(func_decl* pred);
|
||||
expr_ref get_cover_delta(int level, func_decl* pred);
|
||||
void add_cover(int level, func_decl* pred, expr* predicate);
|
||||
void collect_param_descrs(param_descrs & p) { m_context.collect_params(p); }
|
||||
void updt_params(params_ref const& p) { m_context.updt_params(p); }
|
||||
|
||||
};
|
||||
class fixedpoint_context;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ extern "C" {
|
|||
expr_ref _r(mk_c(c)->m());
|
||||
{
|
||||
cancel_eh<polynomial::manager> eh(pm);
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
scoped_timer timer(mk_c(c)->params().m_timeout, &eh);
|
||||
pm.psc_chain(_p, _q, v_x, rs);
|
||||
}
|
||||
|
|
|
@ -165,7 +165,10 @@ extern "C" {
|
|||
}
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
app* a = to_app(bound[i]);
|
||||
SASSERT(a->get_kind() == AST_APP);
|
||||
if (a->get_kind() != AST_APP) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
symbol s(to_app(a)->get_decl()->get_name());
|
||||
names.push_back(of_symbol(s));
|
||||
types.push_back(of_sort(mk_c(c)->m().get_sort(a)));
|
||||
|
|
|
@ -243,7 +243,7 @@ extern "C" {
|
|||
unsigned timeout = to_solver(s)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
|
||||
bool use_ctrl_c = to_solver(s)->m_params.get_bool("ctrl_c", false);
|
||||
cancel_eh<solver> eh(*to_solver_ref(s));
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
lbool result;
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
|
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
cancel_eh<smt::kernel> eh(mk_c(c)->get_smt_kernel());
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
flet<bool> _model(mk_c(c)->fparams().m_model, true);
|
||||
lbool result;
|
||||
try {
|
||||
|
@ -123,7 +123,7 @@ extern "C" {
|
|||
expr * const* _assumptions = to_exprs(assumptions);
|
||||
flet<bool> _model(mk_c(c)->fparams().m_model, true);
|
||||
cancel_eh<smt::kernel> eh(mk_c(c)->get_smt_kernel());
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
lbool result;
|
||||
result = mk_c(c)->get_smt_kernel().check(num_assumptions, _assumptions);
|
||||
if (result != l_false && m) {
|
||||
|
|
|
@ -410,7 +410,7 @@ extern "C" {
|
|||
|
||||
to_tactic_ref(t)->updt_params(p);
|
||||
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
|
|
|
@ -29,7 +29,6 @@ Revision History:
|
|||
#define Z3_CATCH_RETURN_NO_HANDLE(VAL) } catch (z3_exception &) { return VAL; }
|
||||
|
||||
#define CHECK_REF_COUNT(a) (reinterpret_cast<ast const*>(a)->get_ref_count() > 0)
|
||||
#define VALIDATE(a) SASSERT(!a || CHECK_REF_COUNT(a))
|
||||
|
||||
namespace api {
|
||||
// Generic wrapper for ref-count objects exposed by the API
|
||||
|
@ -44,30 +43,30 @@ namespace api {
|
|||
};
|
||||
};
|
||||
|
||||
inline ast * to_ast(Z3_ast a) { VALIDATE(a); return reinterpret_cast<ast *>(a); }
|
||||
inline ast * to_ast(Z3_ast a) { return reinterpret_cast<ast *>(a); }
|
||||
inline Z3_ast of_ast(ast* a) { return reinterpret_cast<Z3_ast>(a); }
|
||||
|
||||
inline expr * to_expr(Z3_ast a) { VALIDATE(a); return reinterpret_cast<expr*>(a); }
|
||||
inline expr * to_expr(Z3_ast a) { return reinterpret_cast<expr*>(a); }
|
||||
inline Z3_ast of_expr(expr* e) { return reinterpret_cast<Z3_ast>(e); }
|
||||
|
||||
inline expr * const * to_exprs(Z3_ast const* a) { return reinterpret_cast<expr* const*>(a); }
|
||||
inline Z3_ast * const * of_exprs(expr* const* e) { return reinterpret_cast<Z3_ast* const*>(e); }
|
||||
|
||||
inline app * to_app(Z3_app a) { VALIDATE(a); return reinterpret_cast<app*>(a); }
|
||||
inline app * to_app(Z3_ast a) { VALIDATE(a); return reinterpret_cast<app*>(a); }
|
||||
inline app * to_app(Z3_app a) { return reinterpret_cast<app*>(a); }
|
||||
inline app * to_app(Z3_ast a) { return reinterpret_cast<app*>(a); }
|
||||
inline Z3_app of_app(app* a) { return reinterpret_cast<Z3_app>(a); }
|
||||
|
||||
inline app * const* to_apps(Z3_ast const* a) { VALIDATE(a); return reinterpret_cast<app * const*>(a); }
|
||||
inline app * const* to_apps(Z3_ast const* a) { return reinterpret_cast<app * const*>(a); }
|
||||
|
||||
inline ast * const * to_asts(Z3_ast const* a) { return reinterpret_cast<ast* const*>(a); }
|
||||
|
||||
inline sort * to_sort(Z3_sort a) { VALIDATE(a); return reinterpret_cast<sort*>(a); }
|
||||
inline sort * to_sort(Z3_sort a) { return reinterpret_cast<sort*>(a); }
|
||||
inline Z3_sort of_sort(sort* s) { return reinterpret_cast<Z3_sort>(s); }
|
||||
|
||||
inline sort * const * to_sorts(Z3_sort const* a) { return reinterpret_cast<sort* const*>(a); }
|
||||
inline Z3_sort const * of_sorts(sort* const* s) { return reinterpret_cast<Z3_sort const*>(s); }
|
||||
|
||||
inline func_decl * to_func_decl(Z3_func_decl a) { VALIDATE(a); return reinterpret_cast<func_decl*>(a); }
|
||||
inline func_decl * to_func_decl(Z3_func_decl a) { return reinterpret_cast<func_decl*>(a); }
|
||||
inline Z3_func_decl of_func_decl(func_decl* f) { return reinterpret_cast<Z3_func_decl>(f); }
|
||||
|
||||
inline func_decl * const * to_func_decls(Z3_func_decl const* f) { return reinterpret_cast<func_decl*const*>(f); }
|
||||
|
@ -75,7 +74,7 @@ inline func_decl * const * to_func_decls(Z3_func_decl const* f) { return reinter
|
|||
inline symbol to_symbol(Z3_symbol s) { return symbol::mk_symbol_from_c_ptr(reinterpret_cast<void*>(s)); }
|
||||
inline Z3_symbol of_symbol(symbol s) { return reinterpret_cast<Z3_symbol>(const_cast<void*>(s.c_ptr())); }
|
||||
|
||||
inline Z3_pattern of_pattern(ast* a) { VALIDATE(a); return reinterpret_cast<Z3_pattern>(a); }
|
||||
inline Z3_pattern of_pattern(ast* a) { return reinterpret_cast<Z3_pattern>(a); }
|
||||
inline app* to_pattern(Z3_pattern p) { return reinterpret_cast<app*>(p); }
|
||||
|
||||
inline Z3_lbool of_lbool(lbool b) { return static_cast<Z3_lbool>(b); }
|
||||
|
|
|
@ -204,6 +204,8 @@ namespace z3 {
|
|||
|
||||
func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range);
|
||||
func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range);
|
||||
func_decl function(symbol const& name, sort_vector const& domain, sort const& range);
|
||||
func_decl function(char const * name, sort_vector const& domain, sort const& range);
|
||||
func_decl function(char const * name, sort const & domain, sort const & range);
|
||||
func_decl function(char const * name, sort const & d1, sort const & d2, sort const & range);
|
||||
func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range);
|
||||
|
@ -249,6 +251,8 @@ namespace z3 {
|
|||
array & operator=(array const & s);
|
||||
public:
|
||||
array(unsigned sz):m_size(sz) { m_array = new T[sz]; }
|
||||
template<typename T2>
|
||||
array(ast_vector_tpl<T2> const & v);
|
||||
~array() { delete[] m_array; }
|
||||
unsigned size() const { return m_size; }
|
||||
T & operator[](int i) { assert(0 <= i); assert(static_cast<unsigned>(i) < m_size); return m_array[i]; }
|
||||
|
@ -427,6 +431,7 @@ namespace z3 {
|
|||
|
||||
expr operator()() const;
|
||||
expr operator()(unsigned n, expr const * args) const;
|
||||
expr operator()(expr_vector const& v) const;
|
||||
expr operator()(expr const & a) const;
|
||||
expr operator()(int a) const;
|
||||
expr operator()(expr const & a1, expr const & a2) const;
|
||||
|
@ -872,7 +877,18 @@ namespace z3 {
|
|||
\brief Return a simplified version of this expression. The parameter \c p is a set of parameters for the Z3 simplifier.
|
||||
*/
|
||||
expr simplify(params const & p) const { Z3_ast r = Z3_simplify_ex(ctx(), m_ast, p); check_error(); return expr(ctx(), r); }
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Apply substitution. Replace src expressions by dst.
|
||||
*/
|
||||
expr substitute(expr_vector const& src, expr_vector const& dst);
|
||||
|
||||
/**
|
||||
\brief Apply substitution. Replace bound variables by expressions.
|
||||
*/
|
||||
expr substitute(expr_vector const& dst);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Wraps a Z3_ast as an expr object. It also checks for errors.
|
||||
|
@ -928,49 +944,6 @@ namespace z3 {
|
|||
inline expr udiv(expr const & a, int b) { return udiv(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
// Basic functions for creating quantified formulas.
|
||||
// The C API should be used for creating quantifiers with patterns, weights, many variables, etc.
|
||||
inline expr forall(expr const & x, expr const & b) {
|
||||
check_context(x, b);
|
||||
Z3_app vars[] = {(Z3_app) x};
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x, expr const & b) {
|
||||
check_context(x, b);
|
||||
Z3_app vars[] = {(Z3_app) x};
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
|
||||
template<typename T> class cast_ast;
|
||||
|
||||
template<> class cast_ast<ast> {
|
||||
|
@ -1032,6 +1005,67 @@ namespace z3 {
|
|||
friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
array<T>::array(ast_vector_tpl<T2> const & v) {
|
||||
m_array = new T[v.size()];
|
||||
m_size = v.size();
|
||||
for (unsigned i = 0; i < m_size; i++) {
|
||||
m_array[i] = v[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Basic functions for creating quantified formulas.
|
||||
// The C API should be used for creating quantifiers with patterns, weights, many variables, etc.
|
||||
inline expr forall(expr const & x, expr const & b) {
|
||||
check_context(x, b);
|
||||
Z3_app vars[] = {(Z3_app) x};
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr forall(expr_vector const & xs, expr const & b) {
|
||||
array<Z3_app> vars(xs);
|
||||
Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x, expr const & b) {
|
||||
check_context(x, b);
|
||||
Z3_app vars[] = {(Z3_app) x};
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
|
||||
check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
|
||||
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
inline expr exists(expr_vector const & xs, expr const & b) {
|
||||
array<Z3_app> vars(xs);
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
|
||||
class func_entry : public object {
|
||||
Z3_func_entry m_entry;
|
||||
void init(Z3_func_entry e) {
|
||||
|
@ -1274,7 +1308,7 @@ namespace z3 {
|
|||
expr as_expr() const {
|
||||
unsigned n = size();
|
||||
if (n == 0)
|
||||
return ctx().bool_val(false);
|
||||
return ctx().bool_val(true);
|
||||
else if (n == 1)
|
||||
return operator[](0);
|
||||
else {
|
||||
|
@ -1485,6 +1519,22 @@ namespace z3 {
|
|||
inline func_decl context::function(char const * name, unsigned arity, sort const * domain, sort const & range) {
|
||||
return function(range.ctx().str_symbol(name), arity, domain, range);
|
||||
}
|
||||
|
||||
inline func_decl context::function(symbol const& name, sort_vector const& domain, sort const& range) {
|
||||
array<Z3_sort> args(domain.size());
|
||||
for (unsigned i = 0; i < domain.size(); i++) {
|
||||
check_context(domain[i], range);
|
||||
args[i] = domain[i];
|
||||
}
|
||||
Z3_func_decl f = Z3_mk_func_decl(m_ctx, name, domain.size(), args.ptr(), range);
|
||||
check_error();
|
||||
return func_decl(*this, f);
|
||||
}
|
||||
|
||||
inline func_decl context::function(char const * name, sort_vector const& domain, sort const& range) {
|
||||
return function(range.ctx().str_symbol(name), domain, range);
|
||||
}
|
||||
|
||||
|
||||
inline func_decl context::function(char const * name, sort const & domain, sort const & range) {
|
||||
check_context(domain, range);
|
||||
|
@ -1571,6 +1621,16 @@ namespace z3 {
|
|||
return expr(ctx(), r);
|
||||
|
||||
}
|
||||
inline expr func_decl::operator()(expr_vector const& args) const {
|
||||
array<Z3_ast> _args(args.size());
|
||||
for (unsigned i = 0; i < args.size(); i++) {
|
||||
check_context(*this, args[i]);
|
||||
_args[i] = args[i];
|
||||
}
|
||||
Z3_ast r = Z3_mk_app(ctx(), *this, args.size(), _args.ptr());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
inline expr func_decl::operator()() const {
|
||||
Z3_ast r = Z3_mk_app(ctx(), *this, 0, 0);
|
||||
ctx().check_error();
|
||||
|
@ -1680,6 +1740,30 @@ namespace z3 {
|
|||
d.check_error();
|
||||
return expr(d.ctx(), r);
|
||||
}
|
||||
|
||||
inline expr expr::substitute(expr_vector const& src, expr_vector const& dst) {
|
||||
assert(src.size() == dst.size());
|
||||
array<Z3_ast> _src(src.size());
|
||||
array<Z3_ast> _dst(dst.size());
|
||||
for (unsigned i = 0; i < src.size(); ++i) {
|
||||
_src[i] = src[i];
|
||||
_dst[i] = dst[i];
|
||||
}
|
||||
Z3_ast r = Z3_substitute(ctx(), m_ast, src.size(), _src.ptr(), _dst.ptr());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
inline expr expr::substitute(expr_vector const& dst) {
|
||||
array<Z3_ast> _dst(dst.size());
|
||||
for (unsigned i = 0; i < dst.size(); ++i) {
|
||||
_dst[i] = dst[i];
|
||||
}
|
||||
Z3_ast r = Z3_substitute_vars(ctx(), m_ast, dst.size(), _dst.ptr());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -44,6 +44,21 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The following parameters can be set:
|
||||
/// - proof (Boolean) Enable proof generation
|
||||
/// - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
|
||||
/// - trace (Boolean) Tracing support for VCC
|
||||
/// - trace_file_name (String) Trace out file for VCC traces
|
||||
/// - timeout (unsigned) default timeout (in milliseconds) used for solvers
|
||||
/// - well_sorted_check type checker
|
||||
/// - auto_config use heuristics to automatically select solver and configure it
|
||||
/// - model model generation for solvers, this parameter can be overwritten when creating a solver
|
||||
/// - model_validate validate models produced by solvers
|
||||
/// - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver
|
||||
/// Note that in previous versions of Z3, this constructor was also used to set global and module parameters.
|
||||
/// For this purpose we should now use <see cref="Global.SetParameter"/>
|
||||
/// </remarks>
|
||||
public Context(Dictionary<string, string> settings)
|
||||
: base()
|
||||
{
|
||||
|
@ -288,6 +303,9 @@ namespace Microsoft.Z3
|
|||
|
||||
/// <summary>
|
||||
/// Create a new finite domain sort.
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param size="size">The size of the sort</param>
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// </summary>
|
||||
public FiniteDomainSort MkFiniteDomainSort(Symbol name, ulong size)
|
||||
{
|
||||
|
@ -300,6 +318,11 @@ namespace Microsoft.Z3
|
|||
|
||||
/// <summary>
|
||||
/// Create a new finite domain sort.
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param size="size">The size of the sort</param>
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// Elements of the sort are created using <seealso cref="MkNumeral"/>,
|
||||
/// and the elements range from 0 to <tt>size-1</tt>.
|
||||
/// </summary>
|
||||
public FiniteDomainSort MkFiniteDomainSort(string name, ulong size)
|
||||
{
|
||||
|
|
|
@ -399,4 +399,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -210,7 +210,7 @@ namespace Microsoft.Z3
|
|||
public Status Check(params Expr[] assumptions)
|
||||
{
|
||||
Z3_lbool r;
|
||||
if (assumptions == null)
|
||||
if (assumptions == null || assumptions.Length == 0)
|
||||
r = (Z3_lbool)Native.Z3_solver_check(Context.nCtx, NativeObject);
|
||||
else
|
||||
r = (Z3_lbool)Native.Z3_solver_check_assumptions(Context.nCtx, NativeObject, (uint)assumptions.Length, AST.ArrayToNative(assumptions));
|
||||
|
|
|
@ -27,6 +27,21 @@ public class Context extends IDisposable
|
|||
|
||||
/**
|
||||
* Constructor.
|
||||
* <remarks>
|
||||
* The following parameters can be set:
|
||||
* - proof (Boolean) Enable proof generation
|
||||
* - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
|
||||
* - trace (Boolean) Tracing support for VCC
|
||||
* - trace_file_name (String) Trace out file for VCC traces
|
||||
* - timeout (unsigned) default timeout (in milliseconds) used for solvers
|
||||
* - well_sorted_check type checker
|
||||
* - auto_config use heuristics to automatically select solver and configure it
|
||||
* - model model generation for solvers, this parameter can be overwritten when creating a solver
|
||||
* - model_validate validate models produced by solvers
|
||||
* - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver
|
||||
* Note that in previous versions of Z3, this constructor was also used to set global and
|
||||
* module parameters. For this purpose we should now use <see cref="Global.setParameter"/>
|
||||
* </remarks>
|
||||
**/
|
||||
public Context(Map<String, String> settings) throws Z3Exception
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.microsoft.z3;
|
|||
public enum Status
|
||||
{
|
||||
// / Used to signify an unsatisfiable status.
|
||||
UNSATISFIABLE(1),
|
||||
UNSATISFIABLE(-1),
|
||||
|
||||
// / Used to signify an unknown status.
|
||||
UNKNOWN(0),
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
This directory contains scripts to build the test application using
|
||||
OCaml. You also need CamlIDL to be able to generate the OCaml API.
|
||||
|
||||
- To download OCaml:
|
||||
http://caml.inria.fr/ocaml/
|
||||
|
||||
- To download CamlIDL:
|
||||
http://forge.ocamlcore.org/projects/camlidl/
|
||||
|
||||
- One must build the OCaml library before compiling the example.
|
||||
Go to directory ../ocaml
|
||||
|
||||
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
|
||||
|
||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
|
||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
|
||||
|
||||
- The script 'exec.cmd' adds the bin directory to the path. So,
|
||||
test_mlapi.exe can find z3.dll.
|
||||
|
||||
|
||||
|
||||
|
||||
This directory contains scripts to build the test application using
|
||||
OCaml. You also need CamlIDL to be able to generate the OCaml API.
|
||||
|
||||
- To download OCaml:
|
||||
http://caml.inria.fr/ocaml/
|
||||
|
||||
- To download CamlIDL:
|
||||
http://forge.ocamlcore.org/projects/camlidl/
|
||||
|
||||
- One must build the OCaml library before compiling the example.
|
||||
Go to directory ../ocaml
|
||||
|
||||
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
|
||||
|
||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
|
||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
|
||||
|
||||
- The script 'exec.cmd' adds the bin directory to the path. So,
|
||||
test_mlapi.exe can find z3.dll.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
The OCaml API for Z3 was tested using OCaml 3.12.1.
|
||||
You also need CamlIDL to be able to generate the OCaml API.
|
||||
|
||||
- To download OCaml:
|
||||
http://caml.inria.fr/ocaml/
|
||||
|
||||
- To download CamlIDL:
|
||||
http://forge.ocamlcore.org/projects/camlidl/
|
||||
|
||||
- To build the OCaml API for Z3:
|
||||
.\build-lib.cmd
|
||||
|
||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
|
||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
|
||||
|
||||
Remark: Building the OCaml API copies some pathnames into files,
|
||||
so the OCaml API must be recompiled if the Z3 library files are moved.
|
||||
|
||||
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
|
||||
|
||||
Acknowledgements:
|
||||
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg.
|
||||
Many thanks to them!
|
||||
The OCaml API for Z3 was tested using OCaml 3.12.1.
|
||||
You also need CamlIDL to be able to generate the OCaml API.
|
||||
|
||||
- To download OCaml:
|
||||
http://caml.inria.fr/ocaml/
|
||||
|
||||
- To download CamlIDL:
|
||||
http://forge.ocamlcore.org/projects/camlidl/
|
||||
|
||||
- To build the OCaml API for Z3:
|
||||
.\build-lib.cmd
|
||||
|
||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
|
||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
|
||||
|
||||
Remark: Building the OCaml API copies some pathnames into files,
|
||||
so the OCaml API must be recompiled if the Z3 library files are moved.
|
||||
|
||||
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
|
||||
|
||||
Acknowledgements:
|
||||
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg.
|
||||
Many thanks to them!
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@echo off
|
||||
|
||||
call .\compile_mlapi.cmd ..\include ..\bin ..\bin
|
||||
@echo off
|
||||
|
||||
call .\compile_mlapi.cmd ..\include ..\bin ..\bin
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
@echo off
|
||||
|
||||
if not exist ..\..\ocaml\z3.cmxa (
|
||||
echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
REM ocaml (>= 3.11) calls the linker through flexlink
|
||||
ocamlc -version >> ocaml_version
|
||||
set /p OCAML_VERSION= <ocaml_version
|
||||
if %OCAML_VERSION% GEQ 3.11 (
|
||||
set XCFLAGS=
|
||||
) else (
|
||||
set XCFLAGS=/nologo /MT /DWIN32
|
||||
)
|
||||
|
||||
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
|
||||
|
||||
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml
|
||||
@echo off
|
||||
|
||||
if not exist ..\..\ocaml\z3.cmxa (
|
||||
echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
REM ocaml (>= 3.11) calls the linker through flexlink
|
||||
ocamlc -version >> ocaml_version
|
||||
set /p OCAML_VERSION= <ocaml_version
|
||||
if %OCAML_VERSION% GEQ 3.11 (
|
||||
set XCFLAGS=
|
||||
) else (
|
||||
set XCFLAGS=/nologo /MT /DWIN32
|
||||
)
|
||||
|
||||
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
|
||||
|
||||
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@echo off
|
||||
SETLOCAL
|
||||
set PATH=..\..\bin;%PATH%
|
||||
test_mlapi.exe
|
||||
ENDLOCAL
|
||||
@echo off
|
||||
SETLOCAL
|
||||
set PATH=..\..\bin;%PATH%
|
||||
test_mlapi.exe
|
||||
ENDLOCAL
|
||||
|
|
|
@ -585,6 +585,9 @@ class FuncDeclRef(AstRef):
|
|||
def as_ast(self):
|
||||
return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
|
||||
|
||||
def as_func_decl(self):
|
||||
return self.ast
|
||||
|
||||
def name(self):
|
||||
"""Return the name of the function declaration `self`.
|
||||
|
||||
|
@ -3853,32 +3856,6 @@ def is_array(a):
|
|||
"""
|
||||
return isinstance(a, ArrayRef)
|
||||
|
||||
def is_select(a):
|
||||
"""Return `True` if `a` is a Z3 array select.
|
||||
|
||||
>>> a = Array('a', IntSort(), IntSort())
|
||||
>>> is_select(a)
|
||||
False
|
||||
>>> i = Int('i')
|
||||
>>> is_select(a[i])
|
||||
True
|
||||
"""
|
||||
return is_app_of(a, Z3_OP_SELECT)
|
||||
|
||||
def is_store(a):
|
||||
"""Return `True` if `a` is a Z3 array store.
|
||||
|
||||
>>> a = Array('a', IntSort(), IntSort())
|
||||
>>> is_store(a)
|
||||
False
|
||||
>>> i = Int('i')
|
||||
>>> is_store(a[i])
|
||||
False
|
||||
>>> is_store(Store(a, i, i + 1))
|
||||
True
|
||||
"""
|
||||
return is_app_of(a, Z3_OP_STORE)
|
||||
|
||||
def is_const_array(a):
|
||||
"""Return `True` if `a` is a Z3 constant array.
|
||||
|
||||
|
@ -4069,7 +4046,8 @@ def is_select(a):
|
|||
>>> a = Array('a', IntSort(), IntSort())
|
||||
>>> is_select(a)
|
||||
False
|
||||
>>> is_select(a[0])
|
||||
>>> i = Int('i')
|
||||
>>> is_select(a[i])
|
||||
True
|
||||
"""
|
||||
return is_app_of(a, Z3_OP_SELECT)
|
||||
|
|
|
@ -703,7 +703,7 @@ typedef enum
|
|||
over Boolean connectives 'and' and 'or'.
|
||||
|
||||
|
||||
- Z3_OP_PR_NFF_NEG: Proof for a (negative) NNF step. Examples:
|
||||
- Z3_OP_PR_NNF_NEG: Proof for a (negative) NNF step. Examples:
|
||||
\nicebox{
|
||||
T1: (not s_1) ~ r_1
|
||||
...
|
||||
|
@ -780,11 +780,11 @@ typedef enum
|
|||
}
|
||||
or
|
||||
\nicebox{
|
||||
(=> (and ln+1 ln+2 .. ln+m) l0)
|
||||
(=> (and l1 l2 .. ln) l0)
|
||||
}
|
||||
or in the most general (ground) form:
|
||||
\nicebox{
|
||||
(=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1))
|
||||
(=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln))
|
||||
}
|
||||
In other words we use the following (Prolog style) convention for Horn
|
||||
implications:
|
||||
|
@ -800,7 +800,7 @@ typedef enum
|
|||
general non-ground form is:
|
||||
|
||||
\nicebox{
|
||||
(forall (vars) (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1)))
|
||||
(forall (vars) (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln)))
|
||||
}
|
||||
|
||||
The hyper-resolution rule takes a sequence of parameters.
|
||||
|
@ -1724,6 +1724,8 @@ extern "C" {
|
|||
To create constants that belong to the finite domain,
|
||||
use the APIs for creating numerals and pass a numeric
|
||||
constant together with the sort returned by this call.
|
||||
The numeric constant should be between 0 and the less
|
||||
than the size of the domain.
|
||||
|
||||
\sa Z3_get_finite_domain_sort_size
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ Notes:
|
|||
void register_z3_replayer_cmds(z3_replayer & in);
|
||||
|
||||
void throw_invalid_reference() {
|
||||
TRACE("z3_replayer", tout << "invalid argument reference\n";);
|
||||
throw z3_replayer_exception("invalid argument reference");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue