mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
Merge branch 'opt' of https://github.com/Z3Prover/z3 into unstable
This commit is contained in:
commit
ab5022888c
396 changed files with 86387 additions and 3294 deletions
|
@ -24,6 +24,7 @@ Revision History:
|
|||
#include"bv_decl_plugin.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"pb_decl_plugin.h"
|
||||
#include"ast_translation.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
|
@ -1081,7 +1082,6 @@ extern "C" {
|
|||
case OP_BSREM_I:
|
||||
case OP_BUREM_I:
|
||||
case OP_BSMOD_I:
|
||||
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -1090,9 +1090,10 @@ extern "C" {
|
|||
}
|
||||
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
|
||||
switch(_d->get_decl_kind()) {
|
||||
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
|
||||
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
|
||||
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
|
||||
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
|
||||
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
|
||||
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
|
||||
case OP_DT_UPDATE_FIELD: return Z3_OP_DT_UPDATE_FIELD;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
|
@ -1186,6 +1187,15 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
|
||||
if (mk_c(c)->get_pb_fid() == _d->get_family_id()) {
|
||||
switch(_d->get_decl_kind()) {
|
||||
case OP_PB_LE: return Z3_OP_PB_LE;
|
||||
case OP_PB_GE: return Z3_OP_PB_GE;
|
||||
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
|
||||
}
|
||||
|
|
|
@ -37,9 +37,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
std::ostringstream buffer;
|
||||
buffer << "Error setting " << param_id << ", " << ex.msg();
|
||||
warning_msg(buffer.str().c_str());
|
||||
warning_msg(ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +62,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
std::ostringstream buffer;
|
||||
buffer << "Error setting " << param_id << ": " << ex.msg();
|
||||
warning_msg(buffer.str().c_str());
|
||||
warning_msg(ex.msg());
|
||||
return Z3_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -92,9 +88,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
std::ostringstream buffer;
|
||||
buffer << "Error setting " << param_id << ": " << ex.msg();
|
||||
warning_msg(buffer.str().c_str());
|
||||
warning_msg(ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ namespace api {
|
|||
m_basic_fid = m().get_basic_family_id();
|
||||
m_arith_fid = m().mk_family_id("arith");
|
||||
m_bv_fid = m().mk_family_id("bv");
|
||||
m_pb_fid = m().mk_family_id("pb");
|
||||
m_array_fid = m().mk_family_id("array");
|
||||
m_dt_fid = m().mk_family_id("datatype");
|
||||
m_datalog_fid = m().mk_family_id("datalog_relation");
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace api {
|
|||
family_id m_bv_fid;
|
||||
family_id m_dt_fid;
|
||||
family_id m_datalog_fid;
|
||||
family_id m_pb_fid;
|
||||
family_id m_fpa_fid;
|
||||
datatype_decl_plugin * m_dt_plugin;
|
||||
|
||||
|
@ -127,6 +128,7 @@ namespace api {
|
|||
family_id get_bv_fid() const { return m_bv_fid; }
|
||||
family_id get_dt_fid() const { return m_dt_fid; }
|
||||
family_id get_datalog_fid() const { return m_datalog_fid; }
|
||||
family_id get_pb_fid() const { return m_pb_fid; }
|
||||
family_id get_fpa_fid() const { return m_fpa_fid; }
|
||||
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace api {
|
|||
return "unknown";
|
||||
}
|
||||
}
|
||||
std::string to_string(unsigned num_queries, expr*const* queries) {
|
||||
std::string to_string(unsigned num_queries, expr* const* queries) {
|
||||
std::stringstream str;
|
||||
m_context.display_smt2(num_queries, queries, str);
|
||||
return str.str();
|
||||
|
@ -466,13 +466,16 @@ extern "C" {
|
|||
ast_manager& m = mk_c(c)->m();
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
mk_c(c)->save_object(v);
|
||||
expr_ref_vector rules(m);
|
||||
expr_ref_vector rules(m), queries(m);
|
||||
svector<symbol> names;
|
||||
|
||||
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, names);
|
||||
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, queries, names);
|
||||
for (unsigned i = 0; i < rules.size(); ++i) {
|
||||
v->m_ast_vector.push_back(rules[i].get());
|
||||
}
|
||||
for (unsigned i = 0; i < queries.size(); ++i) {
|
||||
v->m_ast_vector.push_back(m.mk_not(queries[i].get()));
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -476,7 +476,7 @@ extern "C" {
|
|||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (idx >= decls->size()) {
|
||||
if (!decls || idx >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
|
@ -506,9 +506,9 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (idx >= decls->size()) {
|
||||
if (!decls || idx >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
func_decl* decl = (*decls)[idx];
|
||||
decl = dt_util.get_constructor_recognizer(decl);
|
||||
|
@ -529,7 +529,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (idx_c >= decls->size()) {
|
||||
if (!decls || idx_c >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
|
@ -618,4 +618,25 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_datatype_update_field(
|
||||
__in Z3_context c, __in Z3_func_decl f, __in Z3_ast t, __in Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_datatype_update_field(c, f, t, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* _t = to_expr(t);
|
||||
expr* _v = to_expr(v);
|
||||
expr* args[2] = { _t, _v };
|
||||
sort* domain[2] = { m.get_sort(_t), m.get_sort(_v) };
|
||||
parameter param(_f);
|
||||
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_DT_UPDATE_FIELD, 1, ¶m, 2, domain);
|
||||
app* r = m.mk_app(d, 2, args);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -290,10 +290,10 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
else {
|
||||
model_ref _m;
|
||||
m_solver.get()->get_model(_m);
|
||||
model_ref mr;
|
||||
m_solver.get()->get_model(mr);
|
||||
Z3_model_ref *tmp_val = alloc(Z3_model_ref);
|
||||
tmp_val->m_model = _m.get();
|
||||
tmp_val->m_model = mr.get();
|
||||
mk_c(c)->save_object(tmp_val);
|
||||
*model = of_model(tmp_val);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,18 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_model_has_interp(Z3_context c, Z3_model m, Z3_func_decl a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_has_interp(c, m, a);
|
||||
CHECK_NON_NULL(m, 0);
|
||||
if (to_model_ref(m)->has_interpretation(to_func_decl(a))) {
|
||||
return Z3_TRUE;
|
||||
} else {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_func_interp(c, m, f);
|
||||
|
|
243
src/api/api_opt.cpp
Normal file
243
src/api/api_opt.cpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_opt.cpp
|
||||
|
||||
Abstract:
|
||||
API for optimization
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2013-12-3.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_stats.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"api_model.h"
|
||||
#include"opt_context.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct Z3_optimize_ref : public api::object {
|
||||
opt::context* m_opt;
|
||||
Z3_optimize_ref():m_opt(0) {}
|
||||
virtual ~Z3_optimize_ref() { dealloc(m_opt); }
|
||||
};
|
||||
inline Z3_optimize_ref * to_optimize(Z3_optimize o) { return reinterpret_cast<Z3_optimize_ref *>(o); }
|
||||
inline Z3_optimize of_optimize(Z3_optimize_ref * o) { return reinterpret_cast<Z3_optimize>(o); }
|
||||
inline opt::context* to_optimize_ptr(Z3_optimize o) { return to_optimize(o)->m_opt; }
|
||||
|
||||
Z3_optimize Z3_API Z3_mk_optimize(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_optimize(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_optimize_ref * o = alloc(Z3_optimize_ref);
|
||||
o->m_opt = alloc(opt::context,mk_c(c)->m());
|
||||
mk_c(c)->save_object(o);
|
||||
RETURN_Z3(of_optimize(o));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_inc_ref(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_inc_ref(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
to_optimize(o)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_dec_ref(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_dec_ref(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
to_optimize(o)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_assert(c, o, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_optimize_ptr(o)->add_hard_constraint(to_expr(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_assert_soft(c, o, a, weight, id);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,0);
|
||||
rational w(weight);
|
||||
return to_optimize_ptr(o)->add_soft_constraint(to_expr(a), w, to_symbol(id));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_maximize(c, o, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t,0);
|
||||
return to_optimize_ptr(o)->add_objective(to_app(t), true);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_minimize(c, o, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t,0);
|
||||
return to_optimize_ptr(o)->add_objective(to_app(t), false);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_push(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
to_optimize_ptr(d)->push();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_pop(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
to_optimize_ptr(d)->pop(1);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
||||
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_check(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
lbool r = l_undef;
|
||||
cancel_eh<opt::context> eh(*to_optimize_ptr(o));
|
||||
unsigned timeout = to_optimize_ptr(o)->get_params().get_uint("timeout", mk_c(c)->get_timeout());
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
r = to_optimize_ptr(o)->optimize();
|
||||
}
|
||||
catch (z3_exception& ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
r = l_undef;
|
||||
}
|
||||
// to_optimize_ref(d).cleanup();
|
||||
}
|
||||
return of_lbool(r);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_model(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
model_ref _m;
|
||||
to_optimize_ptr(o)->get_model(_m);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
if (_m) {
|
||||
m_ref->m_model = _m;
|
||||
}
|
||||
else {
|
||||
m_ref->m_model = alloc(model, mk_c(c)->m());
|
||||
}
|
||||
mk_c(c)->save_object(m_ref);
|
||||
RETURN_Z3(of_model(m_ref));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_set_params(c, o, p);
|
||||
RESET_ERROR_CODE();
|
||||
param_descrs descrs;
|
||||
to_optimize_ptr(o)->collect_param_descrs(descrs);
|
||||
to_params(p)->m_params.validate(descrs);
|
||||
params_ref pr = to_param_ref(p);
|
||||
to_optimize_ptr(o)->updt_params(pr);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_param_descrs(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
mk_c(c)->save_object(d);
|
||||
to_optimize_ptr(o)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// get lower value or current approximation
|
||||
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_lower(c, o, idx);
|
||||
RESET_ERROR_CODE();
|
||||
expr_ref e = to_optimize_ptr(o)->get_lower(idx);
|
||||
mk_c(c)->save_ast_trail(e);
|
||||
RETURN_Z3(of_expr(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// get upper or current approximation
|
||||
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_upper(c, o, idx);
|
||||
RESET_ERROR_CODE();
|
||||
expr_ref e = to_optimize_ptr(o)->get_upper(idx);
|
||||
mk_c(c)->save_ast_trail(e);
|
||||
RETURN_Z3(of_expr(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_optimize_to_string(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_to_string(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->mk_external_string(to_optimize_ptr(o)->to_string());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_optimize_get_help(Z3_context c, Z3_optimize d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_help(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
param_descrs descrs;
|
||||
to_optimize_ptr(d)->collect_param_descrs(descrs);
|
||||
descrs.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_stats Z3_API Z3_optimize_get_statistics(Z3_context c,Z3_optimize d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_statistics(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
to_optimize_ptr(d)->collect_statistics(st->m_stats);
|
||||
mk_c(c)->save_object(st);
|
||||
Z3_stats r = of_stats(st);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
61
src/api/api_pb.cpp
Normal file
61
src/api/api_pb.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_pb.cpp
|
||||
|
||||
Abstract:
|
||||
API for pb theory
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2013-11-13.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"pb_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_atmost(c, num_args, args, k);
|
||||
RESET_ERROR_CODE();
|
||||
parameter param(k);
|
||||
pb_util util(mk_c(c)->m());
|
||||
ast* a = util.mk_at_most_k(num_args, to_exprs(args), k);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
|
||||
RESET_ERROR_CODE();
|
||||
pb_util util(mk_c(c)->m());
|
||||
vector<rational> coeffs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
coeffs.push_back(rational(_coeffs[i]));
|
||||
}
|
||||
ast* a = util.mk_le(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
};
|
|
@ -1543,6 +1543,62 @@ namespace z3 {
|
|||
}
|
||||
};
|
||||
|
||||
class optimize : public object {
|
||||
Z3_optimize m_opt;
|
||||
public:
|
||||
class handle {
|
||||
unsigned m_h;
|
||||
public:
|
||||
handle(unsigned h): m_h(h) {}
|
||||
unsigned h() const { return m_h; }
|
||||
};
|
||||
optimize(context& c):object(c) { m_opt = Z3_mk_optimize(c); Z3_optimize_inc_ref(c, m_opt); }
|
||||
~optimize() { Z3_optimize_dec_ref(ctx(), m_opt); }
|
||||
operator Z3_optimize() const { return m_opt; }
|
||||
void add(expr const& e) {
|
||||
assert(e.is_bool());
|
||||
Z3_optimize_assert(ctx(), m_opt, e);
|
||||
}
|
||||
handle add(expr const& e, unsigned weight) {
|
||||
assert(e.is_bool());
|
||||
std::stringstream strm;
|
||||
strm << weight;
|
||||
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, strm.str().c_str(), 0));
|
||||
}
|
||||
handle add(expr const& e, char const* weight) {
|
||||
assert(e.is_bool());
|
||||
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, weight, 0));
|
||||
}
|
||||
handle maximize(expr const& e) {
|
||||
return handle(Z3_optimize_maximize(ctx(), m_opt, e));
|
||||
}
|
||||
handle minimize(expr const& e) {
|
||||
return handle(Z3_optimize_minimize(ctx(), m_opt, e));
|
||||
}
|
||||
void push() {
|
||||
Z3_optimize_push(ctx(), m_opt);
|
||||
}
|
||||
void pop() {
|
||||
Z3_optimize_pop(ctx(), m_opt);
|
||||
}
|
||||
check_result check() { Z3_lbool r = Z3_optimize_check(ctx(), m_opt); check_error(); return to_check_result(r); }
|
||||
model get_model() const { Z3_model m = Z3_optimize_get_model(ctx(), m_opt); check_error(); return model(ctx(), m); }
|
||||
void set(params const & p) { Z3_optimize_set_params(ctx(), m_opt, p); check_error(); }
|
||||
expr lower(handle const& h) {
|
||||
Z3_ast r = Z3_optimize_get_lower(ctx(), m_opt, h.h());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr upper(handle const& h) {
|
||||
Z3_ast r = Z3_optimize_get_upper(ctx(), m_opt, h.h());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
stats statistics() const { Z3_stats r = Z3_optimize_get_statistics(ctx(), m_opt); check_error(); return stats(ctx(), r); }
|
||||
friend std::ostream & operator<<(std::ostream & out, optimize const & s) { out << Z3_optimize_to_string(s.ctx(), s.m_opt); return out; }
|
||||
std::string help() const { char const * r = Z3_optimize_get_help(ctx(), m_opt); check_error(); return r; }
|
||||
};
|
||||
|
||||
inline tactic fail_if(probe const & p) {
|
||||
Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
|
||||
p.check_error();
|
||||
|
|
|
@ -449,6 +449,19 @@ namespace Microsoft.Z3
|
|||
return MkDatatypeSorts(MkSymbols(names), c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update a datatype field at expression t with value v.
|
||||
/// The function performs a record update at t. The field
|
||||
/// that is passed in as argument is updated with value v,
|
||||
/// the remainig fields of t are unchanged.
|
||||
/// </summary>
|
||||
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
|
||||
{
|
||||
return Expr.Create(this, Native.Z3_datatype_update_field(
|
||||
nCtx, field.NativeObject,
|
||||
t.NativeObject, v.NativeObject));
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
@ -2251,6 +2264,36 @@ namespace Microsoft.Z3
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region Pseudo-Boolean constraints
|
||||
|
||||
/// <summary>
|
||||
/// Create an at-most-k constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkAtMost(BoolExpr[] args, uint k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args), k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean less-or-equal constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkPBLe(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(coeffs != null);
|
||||
Contract.Requires(args.Length == coeffs.Length);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args),
|
||||
coeffs, k));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Numerals
|
||||
|
||||
#region General Numerals
|
||||
|
@ -3438,6 +3481,18 @@ namespace Microsoft.Z3
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region Optimization
|
||||
/// <summary>
|
||||
/// Create an Optimization context.
|
||||
/// </summary>
|
||||
public Optimize MkOptimize()
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Optimize>() != null);
|
||||
|
||||
return new Optimize(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Floating-Point Arithmetic
|
||||
|
||||
#region Rounding Modes
|
||||
|
@ -4383,6 +4438,7 @@ namespace Microsoft.Z3
|
|||
Contract.Invariant(m_Statistics_DRQ != null);
|
||||
Contract.Invariant(m_Tactic_DRQ != null);
|
||||
Contract.Invariant(m_Fixedpoint_DRQ != null);
|
||||
Contract.Invariant(m_Optimize_DRQ != null);
|
||||
}
|
||||
|
||||
readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue();
|
||||
|
@ -4400,6 +4456,7 @@ namespace Microsoft.Z3
|
|||
readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(10);
|
||||
readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue(10);
|
||||
readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(10);
|
||||
readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue(10);
|
||||
|
||||
/// <summary>
|
||||
/// AST DRQ
|
||||
|
@ -4476,6 +4533,11 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
public IDecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Optimize DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
|
||||
|
||||
|
||||
internal long refCount = 0;
|
||||
|
||||
|
@ -4518,6 +4580,7 @@ namespace Microsoft.Z3
|
|||
Statistics_DRQ.Clear(this);
|
||||
Tactic_DRQ.Clear(this);
|
||||
Fixedpoint_DRQ.Clear(this);
|
||||
Optimize_DRQ.Clear(this);
|
||||
|
||||
m_boolSort = null;
|
||||
m_intSort = null;
|
||||
|
|
111
src/api/dotnet/Deprecated.cs
Normal file
111
src/api/dotnet/Deprecated.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Deprecated.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Expose deprecated features for use from the managed API
|
||||
those who use them for experiments.
|
||||
|
||||
Author:
|
||||
|
||||
Christoph Wintersteiger (cwinter) 2012-03-15
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// The main interaction with Z3 happens via the Context.
|
||||
/// </summary>
|
||||
[ContractVerification(true)]
|
||||
public class Deprecated
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Creates a backtracking point.
|
||||
/// </summary>
|
||||
/// <seealso cref="Pop"/>
|
||||
public static void Push(Context ctx) {
|
||||
Native.Z3_push(ctx.nCtx);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backtracks <paramref name="n"/> backtracking points.
|
||||
/// </summary>
|
||||
/// <remarks>Note that an exception is thrown if <paramref name="n"/> is not smaller than <c>NumScopes</c></remarks>
|
||||
/// <seealso cref="Push"/>
|
||||
public static void Pop(Context ctx, uint n = 1) {
|
||||
Native.Z3_pop(ctx.nCtx, n);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a constraint (or multiple) into the solver.
|
||||
/// </summary>
|
||||
public static void Assert(Context ctx, params BoolExpr[] constraints)
|
||||
{
|
||||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
|
||||
ctx.CheckContextMatch(constraints);
|
||||
foreach (BoolExpr a in constraints)
|
||||
{
|
||||
Native.Z3_assert_cnstr(ctx.nCtx, a.NativeObject);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Checks whether the assertions in the context are consistent or not.
|
||||
/// </summary>
|
||||
public static Status Check(Context ctx, List<BoolExpr> core, ref Model model, ref Expr proof, params Expr[] assumptions)
|
||||
{
|
||||
Z3_lbool r;
|
||||
model = null;
|
||||
proof = null;
|
||||
if (assumptions == null || assumptions.Length == 0)
|
||||
r = (Z3_lbool)Native.Z3_check(ctx.nCtx);
|
||||
else {
|
||||
IntPtr mdl = IntPtr.Zero, prf = IntPtr.Zero;
|
||||
uint core_size = 0;
|
||||
IntPtr[] native_core = new IntPtr[assumptions.Length];
|
||||
r = (Z3_lbool)Native.Z3_check_assumptions(ctx.nCtx,
|
||||
(uint)assumptions.Length, AST.ArrayToNative(assumptions),
|
||||
ref mdl, ref prf, ref core_size, native_core);
|
||||
|
||||
for (uint i = 0; i < core_size; i++)
|
||||
core.Add((BoolExpr)Expr.Create(ctx, native_core[i]));
|
||||
if (mdl != IntPtr.Zero) {
|
||||
model = new Model(ctx, mdl);
|
||||
}
|
||||
if (prf != IntPtr.Zero) {
|
||||
proof = Expr.Create(ctx, prf);
|
||||
}
|
||||
|
||||
}
|
||||
switch (r)
|
||||
{
|
||||
case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE;
|
||||
case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE;
|
||||
default: return Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an assignment to atomic propositions for a satisfiable context.
|
||||
/// </summary>
|
||||
public static BoolExpr GetAssignment(Context ctx)
|
||||
{
|
||||
IntPtr x = Native.Z3_get_context_assignment(ctx.nCtx);
|
||||
return (BoolExpr)Expr.Create(ctx, x);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -304,6 +304,19 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixedpoint statistics.
|
||||
/// </summary>
|
||||
public Statistics Statistics
|
||||
{
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Statistics>() != null);
|
||||
|
||||
return new Statistics(Context, Native.Z3_fixedpoint_get_statistics(Context.nCtx, NativeObject));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an SMT-LIB2 file with fixedpoint rules.
|
||||
/// Add the rules to the current fixedpoint context.
|
||||
/// Return the set of queries in the file.
|
||||
|
|
298
src/api/dotnet/Optimize.cs
Normal file
298
src/api/dotnet/Optimize.cs
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Optimize.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 Managed API: Optimizes
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2013-12-03
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// Object for managing optimizization context
|
||||
/// </summary>
|
||||
[ContractVerification(true)]
|
||||
public class Optimize : Z3Object
|
||||
{
|
||||
/// <summary>
|
||||
/// A string that describes all available optimize solver parameters.
|
||||
/// </summary>
|
||||
public string Help
|
||||
{
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<string>() != null);
|
||||
return Native.Z3_optimize_get_help(Context.nCtx, NativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the optimize solver parameters.
|
||||
/// </summary>
|
||||
public Params Parameters
|
||||
{
|
||||
set
|
||||
{
|
||||
Contract.Requires(value != null);
|
||||
Context.CheckContextMatch(value);
|
||||
Native.Z3_optimize_set_params(Context.nCtx, NativeObject, value.NativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves parameter descriptions for Optimize solver.
|
||||
/// </summary>
|
||||
public ParamDescrs ParameterDescriptions
|
||||
{
|
||||
get { return new ParamDescrs(Context, Native.Z3_optimize_get_param_descrs(Context.nCtx, NativeObject)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a constraint (or multiple) into the optimize solver.
|
||||
/// </summary>
|
||||
public void Assert(params BoolExpr[] constraints)
|
||||
{
|
||||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
|
||||
Context.CheckContextMatch(constraints);
|
||||
foreach (BoolExpr a in constraints)
|
||||
{
|
||||
Native.Z3_optimize_assert(Context.nCtx, NativeObject, a.NativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alias for Assert.
|
||||
/// </summary>
|
||||
public void Add(params BoolExpr[] constraints)
|
||||
{
|
||||
Assert(constraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle to objectives returned by objective functions.
|
||||
/// </summary>
|
||||
public class Handle
|
||||
{
|
||||
Optimize opt;
|
||||
uint handle;
|
||||
internal Handle(Optimize opt, uint h)
|
||||
{
|
||||
this.opt = opt;
|
||||
this.handle = h;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a lower bound for the objective handle.
|
||||
/// </summary>
|
||||
public ArithExpr Lower
|
||||
{
|
||||
get { return opt.GetLower(handle); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve an upper bound for the objective handle.
|
||||
/// </summary>
|
||||
public ArithExpr Upper
|
||||
{
|
||||
get { return opt.GetUpper(handle); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the value of an objective.
|
||||
/// </summary>
|
||||
public ArithExpr Value
|
||||
{
|
||||
get { return Lower; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert soft constraint
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return an objective which associates with the group of constraints.
|
||||
/// </remarks>
|
||||
public Handle AssertSoft(BoolExpr constraint, uint weight, string group)
|
||||
{
|
||||
Context.CheckContextMatch(constraint);
|
||||
Symbol s = Context.MkSymbol(group);
|
||||
return new Handle(this, Native.Z3_optimize_assert_soft(Context.nCtx, NativeObject, constraint.NativeObject, weight.ToString(), s.NativeObject));
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Check satisfiability of asserted constraints.
|
||||
/// Produce a model that (when the objectives are bounded and
|
||||
/// don't use strict inequalities) meets the objectives.
|
||||
/// </summary>
|
||||
///
|
||||
public Status Check() {
|
||||
Z3_lbool r = (Z3_lbool)Native.Z3_optimize_check(Context.nCtx, NativeObject);
|
||||
switch (r)
|
||||
{
|
||||
case Z3_lbool.Z3_L_TRUE:
|
||||
return Status.SATISFIABLE;
|
||||
case Z3_lbool.Z3_L_FALSE:
|
||||
return Status.UNSATISFIABLE;
|
||||
default:
|
||||
return Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a backtracking point.
|
||||
/// </summary>
|
||||
/// <seealso cref="Pop"/>
|
||||
public void Push()
|
||||
{
|
||||
Native.Z3_optimize_push(Context.nCtx, NativeObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backtrack one backtracking point.
|
||||
/// </summary>
|
||||
/// <remarks>Note that an exception is thrown if Pop is called without a corresponding <c>Push</c></remarks>
|
||||
/// <seealso cref="Push"/>
|
||||
public void Pop()
|
||||
{
|
||||
Native.Z3_optimize_pop(Context.nCtx, NativeObject);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The model of the last <c>Check</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The result is <c>null</c> if <c>Check</c> was not invoked before,
|
||||
/// if its results was not <c>SATISFIABLE</c>, or if model production is not enabled.
|
||||
/// </remarks>
|
||||
public Model Model
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr x = Native.Z3_optimize_get_model(Context.nCtx, NativeObject);
|
||||
if (x == IntPtr.Zero)
|
||||
return null;
|
||||
else
|
||||
return new Model(Context, x);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declare an arithmetical maximization objective.
|
||||
/// Return a handle to the objective. The handle is used as
|
||||
/// to retrieve the values of objectives after calling Check.
|
||||
/// </summary>
|
||||
public Handle MkMaximize(ArithExpr e)
|
||||
{
|
||||
return new Handle(this, Native.Z3_optimize_maximize(Context.nCtx, NativeObject, e.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declare an arithmetical minimization objective.
|
||||
/// Similar to MkMaximize.
|
||||
/// </summary>
|
||||
public Handle MkMinimize(ArithExpr e)
|
||||
{
|
||||
return new Handle(this, Native.Z3_optimize_minimize(Context.nCtx, NativeObject, e.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a lower bound for the objective handle.
|
||||
/// </summary>
|
||||
private ArithExpr GetLower(uint index)
|
||||
{
|
||||
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_lower(Context.nCtx, NativeObject, index));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve an upper bound for the objective handle.
|
||||
/// </summary>
|
||||
private ArithExpr GetUpper(uint index)
|
||||
{
|
||||
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_upper(Context.nCtx, NativeObject, index));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Print the context to a string (SMT-LIB parseable benchmark).
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Native.Z3_optimize_to_string(Context.nCtx, NativeObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optimize statistics.
|
||||
/// </summary>
|
||||
public Statistics Statistics
|
||||
{
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Statistics>() != null);
|
||||
|
||||
return new Statistics(Context, Native.Z3_optimize_get_statistics(Context.nCtx, NativeObject));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Internal
|
||||
internal Optimize(Context ctx, IntPtr obj)
|
||||
: base(ctx, obj)
|
||||
{
|
||||
Contract.Requires(ctx != null);
|
||||
}
|
||||
internal Optimize(Context ctx)
|
||||
: base(ctx, Native.Z3_mk_optimize(ctx.nCtx))
|
||||
{
|
||||
Contract.Requires(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_optimize_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_optimize_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Optimize_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Optimize_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -79,6 +79,7 @@ namespace Microsoft.Z3
|
|||
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a parameter setting.
|
||||
/// </summary>
|
||||
|
@ -118,6 +119,7 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
public void Add(string name, string value)
|
||||
{
|
||||
Contract.Requires(name != null);
|
||||
Contract.Requires(value != null);
|
||||
|
||||
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);
|
||||
|
|
|
@ -361,6 +361,23 @@ public class Context extends IDisposable
|
|||
return mkDatatypeSorts(mkSymbols(names), c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a datatype field at expression t with value v.
|
||||
* The function performs a record update at t. The field
|
||||
* that is passed in as argument is updated with value v,
|
||||
* the remainig fields of t are unchanged.
|
||||
**/
|
||||
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
|
||||
throws Z3Exception
|
||||
{
|
||||
return Expr.create
|
||||
(this,
|
||||
Native.datatypeUpdateField
|
||||
(nCtx(), field.getNativeObject(),
|
||||
t.getNativeObject(), v.getNativeObject()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new function declaration.
|
||||
**/
|
||||
|
|
|
@ -322,7 +322,19 @@ public class Fixedpoint extends Z3Object
|
|||
return res;
|
||||
}
|
||||
|
||||
Fixedpoint(Context ctx, long obj)
|
||||
/**
|
||||
* Fixedpoint statistics.
|
||||
*
|
||||
* @throws Z3Exception
|
||||
**/
|
||||
public Statistics getStatistics() throws Z3Exception
|
||||
{
|
||||
return new Statistics(getContext(), Native.fixedpointGetStatistics(
|
||||
getContext().nCtx(), getNativeObject()));
|
||||
}
|
||||
|
||||
|
||||
Fixedpoint(Context ctx, long obj) throws Z3Exception
|
||||
{
|
||||
super(ctx, obj);
|
||||
}
|
||||
|
|
|
@ -2965,3 +2965,4 @@ let enable_trace ( tag : string ) =
|
|||
let disable_trace ( tag : string ) =
|
||||
(Z3native.enable_trace tag)
|
||||
|
||||
|
||||
|
|
|
@ -3355,3 +3355,5 @@ val enable_trace : string -> unit
|
|||
*)
|
||||
val disable_trace : string -> unit
|
||||
|
||||
|
||||
|
||||
|
|
18972
src/api/ml/z3_stubs.c
Normal file
18972
src/api/ml/z3_stubs.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -301,7 +301,6 @@ class AstRef(Z3PPObject):
|
|||
"""Return unique identifier for object. It can be used for hash-tables and maps."""
|
||||
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
||||
|
||||
|
||||
def ctx_ref(self):
|
||||
"""Return a reference to the C context where this AST node is stored."""
|
||||
return self.ctx.ref()
|
||||
|
@ -455,7 +454,6 @@ class SortRef(AstRef):
|
|||
def get_id(self):
|
||||
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
|
||||
|
||||
|
||||
def kind(self):
|
||||
"""Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
|
||||
|
||||
|
@ -555,6 +553,8 @@ def _to_sort_ref(s, ctx):
|
|||
return ArraySortRef(s, ctx)
|
||||
elif k == Z3_DATATYPE_SORT:
|
||||
return DatatypeSortRef(s, ctx)
|
||||
elif k == Z3_FINITE_DOMAIN_SORT:
|
||||
return FiniteDomainSortRef(s, ctx)
|
||||
elif k == Z3_FLOATING_POINT_SORT:
|
||||
return FPSortRef(s, ctx)
|
||||
elif k == Z3_ROUNDING_MODE_SORT:
|
||||
|
@ -6085,8 +6085,6 @@ class Solver(Z3PPObject):
|
|||
e = BoolVal(True, self.ctx).as_ast()
|
||||
return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
|
||||
|
||||
|
||||
|
||||
def SolverFor(logic, ctx=None):
|
||||
"""Create a solver customized for the given logic.
|
||||
|
||||
|
@ -6347,6 +6345,166 @@ class Fixedpoint(Z3PPObject):
|
|||
else:
|
||||
return Exists(self.vars, fml)
|
||||
|
||||
|
||||
#########################################
|
||||
#
|
||||
# Finite domain sorts
|
||||
#
|
||||
#########################################
|
||||
|
||||
class FiniteDomainSortRef(SortRef):
|
||||
"""Finite domain sort."""
|
||||
|
||||
def size(self):
|
||||
"""Return the size of the finite domain sort"""
|
||||
r = (ctype.c_ulonglong * 1)()
|
||||
if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast(), r):
|
||||
return r[0]
|
||||
else:
|
||||
raise Z3Exception("Failed to retrieve finite domain sort size")
|
||||
|
||||
def FiniteDomainSort(name, sz, ctx=None):
|
||||
"""Create a named finite domain sort of a given size sz"""
|
||||
ctx = _get_ctx(ctx)
|
||||
return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
|
||||
|
||||
#########################################
|
||||
#
|
||||
# Optimize
|
||||
#
|
||||
#########################################
|
||||
|
||||
class OptimizeObjective:
|
||||
def __init__(self, opt, value, is_max):
|
||||
self._opt = opt
|
||||
self._value = value
|
||||
self._is_max = is_max
|
||||
|
||||
def lower(self):
|
||||
opt = self._opt
|
||||
return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
|
||||
|
||||
def upper(self):
|
||||
opt = self._opt
|
||||
return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
|
||||
|
||||
def value(self):
|
||||
if self._is_max:
|
||||
return self.upper()
|
||||
else:
|
||||
return self.lower()
|
||||
|
||||
class Optimize(Z3PPObject):
|
||||
"""Optimize API provides methods for solving using objective functions and weighted soft constraints"""
|
||||
|
||||
def __init__(self, ctx=None):
|
||||
self.ctx = _get_ctx(ctx)
|
||||
self.optimize = Z3_mk_optimize(self.ctx.ref())
|
||||
Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
|
||||
|
||||
def __del__(self):
|
||||
if self.optimize != None:
|
||||
Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
|
||||
|
||||
def set(self, *args, **keys):
|
||||
"""Set a configuration option. The method `help()` return a string containing all available options.
|
||||
"""
|
||||
p = args2params(args, keys, self.ctx)
|
||||
Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
|
||||
|
||||
def help(self):
|
||||
"""Display a string describing all available options."""
|
||||
print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
|
||||
|
||||
def param_descrs(self):
|
||||
"""Return the parameter description set."""
|
||||
return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
|
||||
|
||||
def assert_exprs(self, *args):
|
||||
"""Assert constraints as background axioms for the optimize solver."""
|
||||
args = _get_args(args)
|
||||
for arg in args:
|
||||
if isinstance(arg, Goal) or isinstance(arg, AstVector):
|
||||
for f in arg:
|
||||
Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
|
||||
else:
|
||||
Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
|
||||
|
||||
def add(self, *args):
|
||||
"""Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
|
||||
self.assert_exprs(*args)
|
||||
|
||||
def add_soft(self, arg, weight = "1", id = None):
|
||||
"""Add soft constraint with optional weight and optional identifier.
|
||||
If no weight is supplied, then the penalty for violating the soft constraint
|
||||
is 1.
|
||||
Soft constraints are grouped by identifiers. Soft constraints that are
|
||||
added without identifiers are grouped by default.
|
||||
"""
|
||||
if _is_int(weight):
|
||||
weight = "%d" % weight
|
||||
if not isinstance(weight, str):
|
||||
raise Z3Exception("weight should be a string or an integer")
|
||||
if id == None:
|
||||
id = ""
|
||||
id = to_symbol(id, self.ctx)
|
||||
v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, arg.as_ast(), weight, id)
|
||||
return OptimizeObjective(self, v, False)
|
||||
|
||||
def maximize(self, arg):
|
||||
"""Add objective function to maximize."""
|
||||
return OptimizeObjective(self, Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()), True)
|
||||
|
||||
def minimize(self, arg):
|
||||
"""Add objective function to minimize."""
|
||||
return OptimizeObjective(self, Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()), False)
|
||||
|
||||
def push(self):
|
||||
"""create a backtracking point for added rules, facts and assertions"""
|
||||
Z3_optimize_push(self.ctx.ref(), self.optimize)
|
||||
|
||||
def pop(self):
|
||||
"""restore to previously created backtracking point"""
|
||||
Z3_optimize_pop(self.ctx.ref(), self.optimize)
|
||||
|
||||
def check(self):
|
||||
"""Check satisfiability while optimizing objective functions."""
|
||||
return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize))
|
||||
|
||||
def model(self):
|
||||
"""Return a model for the last check()."""
|
||||
try:
|
||||
return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
|
||||
except Z3Exception:
|
||||
raise Z3Exception("model is not available")
|
||||
|
||||
def lower(self, obj):
|
||||
if not isinstance(obj, OptimizeObjective):
|
||||
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
|
||||
return obj.lower()
|
||||
|
||||
def upper(self, obj):
|
||||
if not isinstance(obj, OptimizeObjective):
|
||||
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
|
||||
return obj.upper()
|
||||
|
||||
def __repr__(self):
|
||||
"""Return a formatted string with all added rules and constraints."""
|
||||
return self.sexpr()
|
||||
|
||||
def sexpr(self):
|
||||
"""Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
|
||||
"""
|
||||
return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
|
||||
|
||||
def statistics(self):
|
||||
"""Return statistics for the last `query()`.
|
||||
"""
|
||||
return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
|
||||
|
||||
|
||||
|
||||
|
||||
#########################################
|
||||
#
|
||||
# ApplyResult
|
||||
|
|
|
@ -1017,6 +1017,8 @@ class Formatter:
|
|||
return self.pp_seq(a.assertions(), 0, [])
|
||||
elif isinstance(a, z3.Fixedpoint):
|
||||
return a.sexpr()
|
||||
elif isinstance(a, z3.Optimize):
|
||||
return a.sexpr()
|
||||
elif isinstance(a, z3.ApplyResult):
|
||||
return self.pp_seq_seq(a, 0, [])
|
||||
elif isinstance(a, z3.ModelRef):
|
||||
|
|
|
@ -78,6 +78,10 @@ class FixedpointObj(ctypes.c_void_p):
|
|||
def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
|
||||
def from_param(obj): return obj
|
||||
|
||||
class OptimizeObj(ctypes.c_void_p):
|
||||
def __init__(self, optimize): self._as_parameter_ = optimize
|
||||
def from_param(obj): return obj
|
||||
|
||||
class ModelObj(ctypes.c_void_p):
|
||||
def __init__(self, model): self._as_parameter_ = model
|
||||
def from_param(obj): return obj
|
||||
|
|
468
src/api/python/z3util.py
Normal file
468
src/api/python/z3util.py
Normal file
|
@ -0,0 +1,468 @@
|
|||
"""
|
||||
Usage:
|
||||
import common_z3 as CM_Z3
|
||||
"""
|
||||
|
||||
import common as CM
|
||||
from z3 import *
|
||||
|
||||
def get_z3_version(as_str=False):
|
||||
major = ctypes.c_uint(0)
|
||||
minor = ctypes.c_uint(0)
|
||||
build = ctypes.c_uint(0)
|
||||
rev = ctypes.c_uint(0)
|
||||
Z3_get_version(major,minor,build,rev)
|
||||
rs = map(int,(major.value,minor.value,build.value,rev.value))
|
||||
if as_str:
|
||||
return "{}.{}.{}.{}".format(*rs)
|
||||
else:
|
||||
return rs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def ehash(v):
|
||||
"""
|
||||
Returns a 'stronger' hash value than the default hash() method.
|
||||
The result from hash() is not enough to distinguish between 2
|
||||
z3 expressions in some cases.
|
||||
|
||||
>>> x1 = Bool('x'); x2 = Bool('x'); x3 = Int('x')
|
||||
>>> print x1.hash(),x2.hash(),x3.hash() #BAD: all same hash values
|
||||
783810685 783810685 783810685
|
||||
>>> print ehash(x1), ehash(x2), ehash(x3)
|
||||
x_783810685_1 x_783810685_1 x_783810685_2
|
||||
|
||||
"""
|
||||
if __debug__:
|
||||
assert is_expr(v)
|
||||
|
||||
return "{}_{}_{}".format(str(v),v.hash(),v.sort_kind())
|
||||
|
||||
|
||||
"""
|
||||
In Z3, variables are caleld *uninterpreted* consts and
|
||||
variables are *interpreted* consts.
|
||||
"""
|
||||
|
||||
def is_expr_var(v):
|
||||
"""
|
||||
EXAMPLES:
|
||||
|
||||
>>> is_expr_var(Int('7'))
|
||||
True
|
||||
>>> is_expr_var(IntVal('7'))
|
||||
False
|
||||
>>> is_expr_var(Bool('y'))
|
||||
True
|
||||
>>> is_expr_var(Int('x') + 7 == Int('y'))
|
||||
False
|
||||
>>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off'])
|
||||
>>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff)
|
||||
>>> is_expr_var(LOnOff)
|
||||
False
|
||||
>>> is_expr_var(On)
|
||||
False
|
||||
>>> is_expr_var(Block)
|
||||
True
|
||||
>>> is_expr_var(SafetyInjection)
|
||||
True
|
||||
"""
|
||||
|
||||
return is_const(v) and v.decl().kind()==Z3_OP_UNINTERPRETED
|
||||
|
||||
def is_expr_val(v):
|
||||
"""
|
||||
EXAMPLES:
|
||||
|
||||
>>> is_expr_val(Int('7'))
|
||||
False
|
||||
>>> is_expr_val(IntVal('7'))
|
||||
True
|
||||
>>> is_expr_val(Bool('y'))
|
||||
False
|
||||
>>> is_expr_val(Int('x') + 7 == Int('y'))
|
||||
False
|
||||
>>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off'])
|
||||
>>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff)
|
||||
>>> is_expr_val(LOnOff)
|
||||
False
|
||||
>>> is_expr_val(On)
|
||||
True
|
||||
>>> is_expr_val(Block)
|
||||
False
|
||||
>>> is_expr_val(SafetyInjection)
|
||||
False
|
||||
"""
|
||||
return is_const(v) and v.decl().kind()!=Z3_OP_UNINTERPRETED
|
||||
|
||||
|
||||
|
||||
|
||||
def get_vars(f,rs=[]):
|
||||
"""
|
||||
>>> x,y = Ints('x y')
|
||||
>>> a,b = Bools('a b')
|
||||
>>> get_vars(Implies(And(x+y==0,x*2==10),Or(a,Implies(a,b==False))))
|
||||
[x, y, a, b]
|
||||
|
||||
"""
|
||||
if __debug__:
|
||||
assert is_expr(f)
|
||||
|
||||
if is_const(f):
|
||||
if is_expr_val(f):
|
||||
return rs
|
||||
else: #variable
|
||||
return CM.vset(rs + [f],str)
|
||||
|
||||
else:
|
||||
for f_ in f.children():
|
||||
rs = get_vars(f_,rs)
|
||||
|
||||
return CM.vset(rs,str)
|
||||
|
||||
|
||||
|
||||
def mk_var(name,vsort):
|
||||
if vsort.kind() == Z3_INT_SORT:
|
||||
v = Int(name)
|
||||
elif vsort.kind() == Z3_REAL_SORT:
|
||||
v = Real(name)
|
||||
elif vsort.kind() == Z3_BOOL_SORT:
|
||||
v = Bool(name)
|
||||
elif vsort.kind() == Z3_DATATYPE_SORT:
|
||||
v = Const(name,vsort)
|
||||
|
||||
else:
|
||||
assert False, 'Cannot handle this sort (s: %sid: %d)'\
|
||||
%(vsort,vsort.kind())
|
||||
|
||||
return v
|
||||
|
||||
|
||||
|
||||
def prove(claim,assume=None,verbose=0):
|
||||
"""
|
||||
>>> r,m = prove(BoolVal(True),verbose=0); r,model_str(m,as_str=False)
|
||||
(True, None)
|
||||
|
||||
#infinite counter example when proving contradiction
|
||||
>>> r,m = prove(BoolVal(False)); r,model_str(m,as_str=False)
|
||||
(False, [])
|
||||
|
||||
>>> x,y,z=Bools('x y z')
|
||||
>>> r,m = prove(And(x,Not(x))); r,model_str(m,as_str=True)
|
||||
(False, '[]')
|
||||
|
||||
>>> r,m = prove(True,assume=And(x,Not(x)),verbose=0)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: Assumption is alway False!
|
||||
|
||||
>>> r,m = prove(Implies(x,x),assume=y,verbose=2); r,model_str(m,as_str=False)
|
||||
assume:
|
||||
y
|
||||
claim:
|
||||
Implies(x, x)
|
||||
to_prove:
|
||||
Implies(y, Implies(x, x))
|
||||
(True, None)
|
||||
|
||||
>>> r,m = prove(And(x,True),assume=y,verbose=0); r,model_str(m,as_str=False)
|
||||
(False, [(x, False), (y, True)])
|
||||
|
||||
>>> r,m = prove(And(x,y),assume=y,verbose=0)
|
||||
>>> print r
|
||||
False
|
||||
>>> print model_str(m,as_str=True)
|
||||
x = False
|
||||
y = True
|
||||
|
||||
>>> a,b = Ints('a b')
|
||||
>>> r,m = prove(a**b == b**a,assume=None,verbose=0)
|
||||
E: cannot solve !
|
||||
>>> r is None and m is None
|
||||
True
|
||||
|
||||
"""
|
||||
|
||||
if __debug__:
|
||||
assert not assume or is_expr(assume)
|
||||
|
||||
|
||||
to_prove = claim
|
||||
if assume:
|
||||
if __debug__:
|
||||
is_proved,_ = prove(Not(assume))
|
||||
|
||||
def _f():
|
||||
emsg = "Assumption is alway False!"
|
||||
if verbose >= 2:
|
||||
emsg = "{}\n{}".format(assume,emsg)
|
||||
return emsg
|
||||
|
||||
assert is_proved==False, _f()
|
||||
|
||||
to_prove = Implies(assume,to_prove)
|
||||
|
||||
|
||||
|
||||
if verbose >= 2:
|
||||
print 'assume: '
|
||||
print assume
|
||||
print 'claim: '
|
||||
print claim
|
||||
print 'to_prove: '
|
||||
print to_prove
|
||||
|
||||
f = Not(to_prove)
|
||||
|
||||
models = get_models(f,k=1)
|
||||
if models is None: #unknown
|
||||
print 'E: cannot solve !'
|
||||
return None, None
|
||||
elif models == False: #unsat
|
||||
return True,None
|
||||
else: #sat
|
||||
if __debug__:
|
||||
assert isinstance(models,list)
|
||||
|
||||
if models:
|
||||
return False, models[0] #the first counterexample
|
||||
else:
|
||||
return False, [] #infinite counterexample,models
|
||||
|
||||
|
||||
def get_models(f,k):
|
||||
"""
|
||||
Returns the first k models satisfiying f.
|
||||
If f is not satisfiable, returns False.
|
||||
If f cannot be solved, returns None
|
||||
If f is satisfiable, returns the first k models
|
||||
Note that if f is a tautology, e.g.\ True, then the result is []
|
||||
|
||||
Based on http://stackoverflow.com/questions/11867611/z3py-checking-all-solutions-for-equation
|
||||
|
||||
EXAMPLES:
|
||||
>>> x, y = Ints('x y')
|
||||
>>> len(get_models(And(0<=x,x <= 4),k=11))
|
||||
5
|
||||
>>> get_models(And(0<=x**y,x <= 1),k=2) is None
|
||||
True
|
||||
>>> get_models(And(0<=x,x <= -1),k=2)
|
||||
False
|
||||
>>> len(get_models(x+y==7,5))
|
||||
5
|
||||
>>> len(get_models(And(x<=5,x>=1),7))
|
||||
5
|
||||
>>> get_models(And(x<=0,x>=5),7)
|
||||
False
|
||||
|
||||
>>> x = Bool('x')
|
||||
>>> get_models(And(x,Not(x)),k=1)
|
||||
False
|
||||
>>> get_models(Implies(x,x),k=1)
|
||||
[]
|
||||
>>> get_models(BoolVal(True),k=1)
|
||||
[]
|
||||
|
||||
|
||||
|
||||
"""
|
||||
|
||||
if __debug__:
|
||||
assert is_expr(f)
|
||||
assert k>=1
|
||||
|
||||
|
||||
|
||||
s = Solver()
|
||||
s.add(f)
|
||||
|
||||
models = []
|
||||
i = 0
|
||||
while s.check() == sat and i < k:
|
||||
i = i + 1
|
||||
|
||||
m = s.model()
|
||||
|
||||
if not m: #if m == []
|
||||
break
|
||||
|
||||
models.append(m)
|
||||
|
||||
|
||||
#create new constraint to block the current model
|
||||
block = Not(And([v() == m[v] for v in m]))
|
||||
s.add(block)
|
||||
|
||||
|
||||
if s.check() == unknown:
|
||||
return None
|
||||
elif s.check() == unsat and i==0:
|
||||
return False
|
||||
else:
|
||||
return models
|
||||
|
||||
def is_tautology(claim,verbose=0):
|
||||
"""
|
||||
>>> is_tautology(Implies(Bool('x'),Bool('x')))
|
||||
True
|
||||
|
||||
>>> is_tautology(Implies(Bool('x'),Bool('y')))
|
||||
False
|
||||
|
||||
>>> is_tautology(BoolVal(True))
|
||||
True
|
||||
|
||||
>>> is_tautology(BoolVal(False))
|
||||
False
|
||||
|
||||
"""
|
||||
return prove(claim=claim,assume=None,verbose=verbose)[0]
|
||||
|
||||
|
||||
def is_contradiction(claim,verbose=0):
|
||||
"""
|
||||
>>> x,y=Bools('x y')
|
||||
>>> is_contradiction(BoolVal(False))
|
||||
True
|
||||
|
||||
>>> is_contradiction(BoolVal(True))
|
||||
False
|
||||
|
||||
>>> is_contradiction(x)
|
||||
False
|
||||
|
||||
>>> is_contradiction(Implies(x,y))
|
||||
False
|
||||
|
||||
>>> is_contradiction(Implies(x,x))
|
||||
False
|
||||
|
||||
>>> is_contradiction(And(x,Not(x)))
|
||||
True
|
||||
"""
|
||||
|
||||
return prove(claim=Not(claim),assume=None,verbose=verbose)[0]
|
||||
|
||||
|
||||
def exact_one_model(f):
|
||||
"""
|
||||
return True if f has exactly 1 model, False otherwise.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
>>> x, y = Ints('x y')
|
||||
>>> exact_one_model(And(0<=x**y,x <= 0))
|
||||
False
|
||||
|
||||
>>> exact_one_model(And(0<=x,x <= 0))
|
||||
True
|
||||
|
||||
>>> exact_one_model(And(0<=x,x <= 1))
|
||||
False
|
||||
|
||||
>>> exact_one_model(And(0<=x,x <= -1))
|
||||
False
|
||||
"""
|
||||
|
||||
models = get_models(f,k=2)
|
||||
if isinstance(models,list):
|
||||
return len(models)==1
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def myBinOp(op,*L):
|
||||
"""
|
||||
>>> myAnd(*[Bool('x'),Bool('y')])
|
||||
And(x, y)
|
||||
|
||||
>>> myAnd(*[Bool('x'),None])
|
||||
x
|
||||
|
||||
>>> myAnd(*[Bool('x')])
|
||||
x
|
||||
|
||||
>>> myAnd(*[])
|
||||
|
||||
>>> myAnd(Bool('x'),Bool('y'))
|
||||
And(x, y)
|
||||
|
||||
>>> myAnd(*[Bool('x'),Bool('y')])
|
||||
And(x, y)
|
||||
|
||||
>>> myAnd([Bool('x'),Bool('y')])
|
||||
And(x, y)
|
||||
|
||||
>>> myAnd((Bool('x'),Bool('y')))
|
||||
And(x, y)
|
||||
|
||||
>>> myAnd(*[Bool('x'),Bool('y'),True])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError
|
||||
"""
|
||||
|
||||
if __debug__:
|
||||
assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES
|
||||
|
||||
if len(L)==1 and (isinstance(L[0],list) or isinstance(L[0],tuple)):
|
||||
L = L[0]
|
||||
|
||||
if __debug__:
|
||||
assert all(not isinstance(l,bool) for l in L)
|
||||
|
||||
L = [l for l in L if is_expr(l)]
|
||||
if L:
|
||||
if len(L)==1:
|
||||
return L[0]
|
||||
else:
|
||||
if op == Z3_OP_OR:
|
||||
return Or(L)
|
||||
elif op == Z3_OP_AND:
|
||||
return And(L)
|
||||
else: #IMPLIES
|
||||
return Implies(L[0],L[1])
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def myAnd(*L): return myBinOp(Z3_OP_AND,*L)
|
||||
def myOr(*L): return myBinOp(Z3_OP_OR,*L)
|
||||
def myImplies(a,b):return myBinOp(Z3_OP_IMPLIES,[a,b])
|
||||
|
||||
|
||||
|
||||
Iff = lambda f,g: And(Implies(f,g),Implies(g,f))
|
||||
|
||||
|
||||
|
||||
def model_str(m,as_str=True):
|
||||
"""
|
||||
Returned a 'sorted' model (so that it's easier to see)
|
||||
The model is sorted by its key,
|
||||
e.g. if the model is y = 3 , x = 10, then the result is
|
||||
x = 10, y = 3
|
||||
|
||||
EXAMPLES:
|
||||
see doctest exampels from function prove()
|
||||
|
||||
"""
|
||||
if __debug__:
|
||||
assert m is None or m == [] or isinstance(m,ModelRef)
|
||||
|
||||
if m :
|
||||
vs = [(v,m[v]) for v in m]
|
||||
vs = sorted(vs,key=lambda (a,_): str(a))
|
||||
if as_str:
|
||||
return '\n'.join(['{} = {}'.format(k,v) for (k,v) in vs])
|
||||
else:
|
||||
return vs
|
||||
else:
|
||||
return str(m) if as_str else m
|
||||
|
263
src/api/z3_api.h
263
src/api/z3_api.h
|
@ -47,6 +47,7 @@ DEFINE_TYPE(Z3_func_interp);
|
|||
#define Z3_func_interp_opt Z3_func_interp
|
||||
DEFINE_TYPE(Z3_func_entry);
|
||||
DEFINE_TYPE(Z3_fixedpoint);
|
||||
DEFINE_TYPE(Z3_optimize);
|
||||
DEFINE_TYPE(Z3_rcf_num);
|
||||
DEFINE_VOID(Z3_theory_data);
|
||||
#endif
|
||||
|
@ -85,6 +86,7 @@ DEFINE_VOID(Z3_theory_data);
|
|||
- \c Z3_func_interp: interpretation of a function in a model.
|
||||
- \c Z3_func_entry: representation of the value of a \c Z3_func_interp at a particular point.
|
||||
- \c Z3_fixedpoint: context for the recursive predicate solver.
|
||||
- \c Z3_optimize: context for solving optimization queries.
|
||||
- \c Z3_ast_vector: vector of \c Z3_ast objects.
|
||||
- \c Z3_ast_map: mapping from \c Z3_ast to \c Z3_ast objects.
|
||||
- \c Z3_goal: set of formulas that can be solved and/or transformed using tactics and solvers.
|
||||
|
@ -877,6 +879,17 @@ typedef enum
|
|||
|
||||
- Z3_OP_DT_ACCESSOR: datatype accessor.
|
||||
|
||||
- Z3_OP_DT_UPDATE_FIELD: datatype field update.
|
||||
|
||||
- Z3_OP_PB_AT_MOST: Cardinality constraint.
|
||||
E.g., x + y + z <= 2
|
||||
|
||||
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
|
||||
Example 2*x + 3*y <= 4
|
||||
|
||||
- Z3_OP_PB_GE: Generalized Pseudo-Boolean cardinality constraint.
|
||||
Example 2*x + 3*y + 2*z >= 4
|
||||
|
||||
- Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN: Floating-point rounding mode RNE
|
||||
|
||||
- Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY: Floating-point rounding mode RNA
|
||||
|
@ -1141,6 +1154,12 @@ typedef enum {
|
|||
Z3_OP_DT_CONSTRUCTOR=0x800,
|
||||
Z3_OP_DT_RECOGNISER,
|
||||
Z3_OP_DT_ACCESSOR,
|
||||
Z3_OP_DT_UPDATE_FIELD,
|
||||
|
||||
// Pseudo Booleans
|
||||
Z3_OP_PB_AT_MOST=0x900,
|
||||
Z3_OP_PB_LE,
|
||||
Z3_OP_PB_GE,
|
||||
|
||||
// Floating-Point Arithmetic
|
||||
Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN,
|
||||
|
@ -1327,6 +1346,7 @@ typedef enum
|
|||
def_Type('FUNC_INTERP', 'Z3_func_interp', 'FuncInterpObj')
|
||||
def_Type('FUNC_ENTRY', 'Z3_func_entry', 'FuncEntryObj')
|
||||
def_Type('FIXEDPOINT', 'Z3_fixedpoint', 'FixedpointObj')
|
||||
def_Type('OPTIMIZE', 'Z3_optimize', 'OptimizeObj')
|
||||
def_Type('PARAM_DESCRS', 'Z3_param_descrs', 'ParamDescrs')
|
||||
def_Type('RCF_NUM', 'Z3_rcf_num', 'RCFNumObj')
|
||||
*/
|
||||
|
@ -3868,6 +3888,28 @@ END_MLAPI_EXCLUDE
|
|||
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(
|
||||
__in Z3_context c, __in Z3_sort t, unsigned idx_c, unsigned idx_a);
|
||||
|
||||
/**
|
||||
\brief Update record field with a value.
|
||||
|
||||
This corresponds to the 'with' construct in OCaml.
|
||||
It has the effect of updating a record field with a given value.
|
||||
The remaining fields are left unchanged. It is the record
|
||||
equivalent of an array store (see \sa Z3_mk_store).
|
||||
If the datatype has more than one constructor, then the update function
|
||||
behaves as identity if there is a miss-match between the accessor and
|
||||
constructor. For example ((_ update-field car) nil 1) is nil,
|
||||
while ((_ update-field car) (cons 2 nil) 1) is (cons 1 nil).
|
||||
|
||||
|
||||
\pre Z3_get_sort_kind(Z3_get_sort(c, t)) == Z3_get_domain(c, field_access, 1) == Z3_DATATYPE_SORT
|
||||
\pre Z3_get_sort(c, value) == Z3_get_range(c, field_access)
|
||||
|
||||
|
||||
def_API('Z3_datatype_update_field', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(AST), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_datatype_update_field(
|
||||
__in Z3_context c, __in Z3_func_decl field_access,
|
||||
__in Z3_ast t, __in Z3_ast value);
|
||||
|
||||
/**
|
||||
\brief Return arity of relation.
|
||||
|
@ -3893,6 +3935,29 @@ END_MLAPI_EXCLUDE
|
|||
Z3_sort Z3_API Z3_get_relation_column(__in Z3_context c, __in Z3_sort s, unsigned col);
|
||||
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
Encode p1 + p2 + ... + pn <= k
|
||||
|
||||
def_API('Z3_mk_atmost', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(__in Z3_context c, __in unsigned num_args,
|
||||
__in_ecount(num_args) Z3_ast const args[], __in unsigned k);
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
Encode k1*p1 + k2*p2 + ... + kn*pn <= k
|
||||
|
||||
def_API('Z3_mk_pble', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pble(__in Z3_context c, __in unsigned num_args,
|
||||
__in_ecount(num_args) Z3_ast const args[], __in_ecount(num_args) int coeffs[],
|
||||
__in int k);
|
||||
|
||||
/**
|
||||
\mlonly {3 {L Function Declarations}} \endmlonly
|
||||
*/
|
||||
|
@ -4659,6 +4724,13 @@ END_MLAPI_EXCLUDE
|
|||
*/
|
||||
Z3_ast_opt Z3_API Z3_model_get_const_interp(__in Z3_context c, __in Z3_model m, __in Z3_func_decl a);
|
||||
|
||||
/**
|
||||
\brief Test if there exists an interpretation (i.e., assignment) for \c a in the model \c m.
|
||||
|
||||
def_API('Z3_model_has_interp', BOOL, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL)))
|
||||
*/
|
||||
Z3_bool Z3_API Z3_model_has_interp(__in Z3_context c, __in Z3_model m, __in Z3_func_decl a);
|
||||
|
||||
/**
|
||||
\brief Return the interpretation of the function \c f in the model \c m.
|
||||
Return \mlonly [None], \endmlonly \conly \c NULL,
|
||||
|
@ -6039,6 +6111,197 @@ END_MLAPI_EXCLUDE
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef CorML4
|
||||
/**
|
||||
@name Optimize facilities
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
\brief Create a new optimize context.
|
||||
|
||||
\conly \remark User must use #Z3_optimize_inc_ref and #Z3_optimize_dec_ref to manage optimize objects.
|
||||
\conly Even if the context was created using #Z3_mk_context instead of #Z3_mk_context_rc.
|
||||
|
||||
def_API('Z3_mk_optimize', OPTIMIZE, (_in(CONTEXT), ))
|
||||
*/
|
||||
Z3_optimize Z3_API Z3_mk_optimize(__in Z3_context c);
|
||||
|
||||
#ifdef Conly
|
||||
/**
|
||||
\brief Increment the reference counter of the given optimize context
|
||||
|
||||
def_API('Z3_optimize_inc_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_inc_ref(__in Z3_context c,__in Z3_optimize d);
|
||||
|
||||
/**
|
||||
\brief Decrement the reference counter of the given optimize context.
|
||||
|
||||
def_API('Z3_optimize_dec_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_dec_ref(__in Z3_context c,__in Z3_optimize d);
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Assert hard constraint to the optimization context.
|
||||
|
||||
def_API('Z3_optimize_assert', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a);
|
||||
|
||||
|
||||
/**
|
||||
\brief Assert soft constraint to the optimization context.
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param a - formula
|
||||
\param weight - a positive weight, penalty for violating soft constraint
|
||||
\param id - optional identifier to group soft constraints
|
||||
|
||||
def_API('Z3_optimize_assert_soft', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST), _in(STRING), _in(SYMBOL)))
|
||||
*/
|
||||
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id);
|
||||
|
||||
|
||||
/**
|
||||
\brief Add a maximization constraint.
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param a - arithmetical term
|
||||
def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
|
||||
*/
|
||||
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t);
|
||||
|
||||
/**
|
||||
\brief Add a minimization constraint.
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param a - arithmetical term
|
||||
|
||||
def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
|
||||
*/
|
||||
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t);
|
||||
|
||||
|
||||
/**
|
||||
\brief Create a backtracking point.
|
||||
|
||||
The optimize solver contains a set of rules, added facts and assertions.
|
||||
The set of rules, facts and assertions are restored upon calling #Z3_optimize_pop.
|
||||
|
||||
\sa Z3_optimize_pop
|
||||
|
||||
def_API('Z3_optimize_push', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d);
|
||||
|
||||
/**
|
||||
\brief Backtrack one level.
|
||||
|
||||
\sa Z3_optimize_push
|
||||
|
||||
\pre The number of calls to pop cannot exceed calls to push.
|
||||
|
||||
def_API('Z3_optimize_pop', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d);
|
||||
|
||||
/**
|
||||
\brief Check consistency and produce optimal values.
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
|
||||
def_API('Z3_optimize_check', INT, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o);
|
||||
|
||||
|
||||
/**
|
||||
\brief Retrieve the model for the last #Z3_optimize_check
|
||||
|
||||
The error handler is invoked if a model is not available because
|
||||
the commands above were not invoked for the given optimization
|
||||
solver, or if the result was \c Z3_L_FALSE.
|
||||
|
||||
def_API('Z3_optimize_get_model', MODEL, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o);
|
||||
|
||||
/**
|
||||
\brief Set parameters on optimization context.
|
||||
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param p - parameters
|
||||
|
||||
def_API('Z3_optimize_set_params', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(PARAMS)))
|
||||
*/
|
||||
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p);
|
||||
|
||||
/**
|
||||
\brief Return the parameter description set for the given optimize object.
|
||||
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
|
||||
def_API('Z3_optimize_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o);
|
||||
|
||||
/**
|
||||
\brief Retrieve lower bound value or approximation for the i'th optimization objective.
|
||||
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param idx - index of optimization objective
|
||||
|
||||
def_API('Z3_optimize_get_lower', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx);
|
||||
|
||||
/**
|
||||
\brief Retrieve upper bound value or approximation for the i'th optimization objective.
|
||||
|
||||
\param c - context
|
||||
\param o - optimization context
|
||||
\param idx - index of optimization objective
|
||||
|
||||
def_API('Z3_optimize_get_upper', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx);
|
||||
|
||||
/**
|
||||
\brief Print the current context as a string.
|
||||
\param c - context.
|
||||
\param o - optimization context.
|
||||
|
||||
def_API('Z3_optimize_to_string', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_optimize_to_string(
|
||||
__in Z3_context c,
|
||||
__in Z3_optimize o);
|
||||
|
||||
|
||||
/**
|
||||
\brief Return a string containing a description of parameters accepted by optimize.
|
||||
|
||||
def_API('Z3_optimize_get_help', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_optimize_get_help(__in Z3_context c, __in Z3_optimize t);
|
||||
|
||||
/**
|
||||
\brief Retrieve statistics information from the last call to #Z3_optimize_check
|
||||
|
||||
def_API('Z3_optimize_get_statistics', STATS, (_in(CONTEXT), _in(OPTIMIZE)))
|
||||
*/
|
||||
Z3_stats Z3_API Z3_optimize_get_statistics(__in Z3_context c,__in Z3_optimize d);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CorML4
|
||||
/*@}*/
|
||||
|
||||
|
|
|
@ -22,12 +22,14 @@ Notes:
|
|||
#include"stream_buffer.h"
|
||||
#include"symbol.h"
|
||||
#include"trace.h"
|
||||
#include<sstream>
|
||||
|
||||
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");
|
||||
throw z3_replayer_exception("invalid argument reference1");
|
||||
}
|
||||
|
||||
struct z3_replayer::imp {
|
||||
|
@ -45,7 +47,38 @@ struct z3_replayer::imp {
|
|||
size_t_map<void *> m_heap;
|
||||
svector<z3_replayer_cmd> m_cmds;
|
||||
|
||||
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT };
|
||||
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT };
|
||||
|
||||
char const* kind2string(value_kind k) const {
|
||||
switch (k) {
|
||||
case INT64: return "int64";
|
||||
case UINT64: return "uint64";
|
||||
case DOUBLE: return "double";
|
||||
case STRING: return "string";
|
||||
case SYMBOL: return "symbol";
|
||||
case OBJECT: return "object";
|
||||
case UINT_ARRAY: return "uint_array";
|
||||
case INT_ARRAY: return "int_array";
|
||||
case SYMBOL_ARRAY: return "symbol_array";
|
||||
case OBJECT_ARRAY: return "object_array";
|
||||
case FLOAT: return "float";
|
||||
default: UNREACHABLE(); return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void check_arg(unsigned pos, value_kind k) const {
|
||||
if (pos >= m_args.size()) {
|
||||
TRACE("z3_replayer", tout << "too few arguments " << m_args.size() << " expecting " << kind2string(k) << "\n";);
|
||||
throw z3_replayer_exception("invalid argument reference2");
|
||||
}
|
||||
if (m_args[pos].m_kind != k) {
|
||||
std::stringstream strm;
|
||||
strm << "expecting " << kind2string(k) << " at position "
|
||||
<< pos << " but got " << kind2string(m_args[pos].m_kind);
|
||||
throw z3_replayer_exception(strm.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
struct value {
|
||||
value_kind m_kind;
|
||||
|
@ -71,6 +104,7 @@ struct z3_replayer::imp {
|
|||
vector<ptr_vector<void> > m_obj_arrays;
|
||||
vector<svector<Z3_symbol> > m_sym_arrays;
|
||||
vector<unsigned_vector> m_unsigned_arrays;
|
||||
vector<svector<int> > m_int_arrays;
|
||||
|
||||
imp(z3_replayer & o, std::istream & in):
|
||||
m_owner(o),
|
||||
|
@ -321,6 +355,15 @@ struct z3_replayer::imp {
|
|||
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
|
||||
}
|
||||
}
|
||||
if (k == INT64) {
|
||||
aidx = m_int_arrays.size();
|
||||
nk = INT_ARRAY;
|
||||
m_int_arrays.push_back(svector<int>());
|
||||
svector<int> & v = m_int_arrays.back();
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
v.push_back(static_cast<int>(m_args[i].m_int));
|
||||
}
|
||||
}
|
||||
else if (k == SYMBOL) {
|
||||
aidx = m_sym_arrays.size();
|
||||
nk = SYMBOL_ARRAY;
|
||||
|
@ -489,8 +532,7 @@ struct z3_replayer::imp {
|
|||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, OBJECT);
|
||||
m_heap.insert(m_ptr, m_args[pos].m_obj);
|
||||
break;
|
||||
}
|
||||
|
@ -499,8 +541,7 @@ struct z3_replayer::imp {
|
|||
// @ obj_id array_pos idx
|
||||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, OBJECT_ARRAY);
|
||||
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
ptr_vector<void> & v = m_obj_arrays[aidx];
|
||||
skip_blank(); read_uint64();
|
||||
|
@ -525,26 +566,22 @@ struct z3_replayer::imp {
|
|||
}
|
||||
|
||||
int get_int(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, INT64);
|
||||
return static_cast<int>(m_args[pos].m_int);
|
||||
}
|
||||
|
||||
__int64 get_int64(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, INT64);
|
||||
return m_args[pos].m_int;
|
||||
}
|
||||
|
||||
unsigned get_uint(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, UINT64);
|
||||
return static_cast<unsigned>(m_args[pos].m_uint);
|
||||
}
|
||||
|
||||
__uint64 get_uint64(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, UINT64);
|
||||
return m_args[pos].m_uint;
|
||||
}
|
||||
|
||||
|
@ -555,46 +592,45 @@ struct z3_replayer::imp {
|
|||
}
|
||||
|
||||
double get_double(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, DOUBLE);
|
||||
return m_args[pos].m_double;
|
||||
}
|
||||
|
||||
Z3_string get_str(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, STRING);
|
||||
return m_args[pos].m_str;
|
||||
}
|
||||
|
||||
Z3_symbol get_symbol(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, SYMBOL);
|
||||
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
|
||||
}
|
||||
|
||||
void * get_obj(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, OBJECT);
|
||||
return m_args[pos].m_obj;
|
||||
}
|
||||
|
||||
unsigned * get_uint_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, UINT_ARRAY);
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
return m_unsigned_arrays[idx].c_ptr();
|
||||
}
|
||||
|
||||
int * get_int_array(unsigned pos) const {
|
||||
check_arg(pos, INT_ARRAY);
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
return m_int_arrays[idx].c_ptr();
|
||||
}
|
||||
|
||||
Z3_symbol * get_symbol_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, SYMBOL_ARRAY);
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
return m_sym_arrays[idx].c_ptr();
|
||||
}
|
||||
|
||||
void ** get_obj_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, OBJECT_ARRAY);
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
ptr_vector<void> const & v = m_obj_arrays[idx];
|
||||
TRACE("z3_replayer_bug", tout << "pos: " << pos << ", idx: " << idx << " size(): " << v.size() << "\n";
|
||||
|
@ -603,38 +639,32 @@ struct z3_replayer::imp {
|
|||
}
|
||||
|
||||
int * get_int_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, INT64);
|
||||
return reinterpret_cast<int*>(&(m_args[pos].m_int));
|
||||
}
|
||||
|
||||
__int64 * get_int64_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, INT64);
|
||||
return &(m_args[pos].m_int);
|
||||
}
|
||||
|
||||
unsigned * get_uint_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, UINT64);
|
||||
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
|
||||
}
|
||||
|
||||
__uint64 * get_uint64_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, UINT64);
|
||||
return &(m_args[pos].m_uint);
|
||||
}
|
||||
|
||||
Z3_string * get_str_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, STRING);
|
||||
return &(m_args[pos].m_str);
|
||||
}
|
||||
|
||||
void ** get_obj_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
check_arg(pos, OBJECT);
|
||||
return &(m_args[pos].m_obj);
|
||||
}
|
||||
|
||||
|
@ -653,6 +683,7 @@ struct z3_replayer::imp {
|
|||
m_obj_arrays.reset();
|
||||
m_sym_arrays.reset();
|
||||
m_unsigned_arrays.reset();
|
||||
m_int_arrays.reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -715,6 +746,10 @@ unsigned * z3_replayer::get_uint_array(unsigned pos) const {
|
|||
return m_imp->get_uint_array(pos);
|
||||
}
|
||||
|
||||
int * z3_replayer::get_int_array(unsigned pos) const {
|
||||
return m_imp->get_int_array(pos);
|
||||
}
|
||||
|
||||
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
|
||||
return m_imp->get_symbol_array(pos);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
void * get_obj(unsigned pos) const;
|
||||
|
||||
unsigned * get_uint_array(unsigned pos) const;
|
||||
int * get_int_array(unsigned pos) const;
|
||||
Z3_symbol * get_symbol_array(unsigned pos) const;
|
||||
void ** get_obj_array(unsigned pos) const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue