3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 04:43:39 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-10-14 15:16:22 -07:00
commit e9d615e309
204 changed files with 4620 additions and 2435 deletions

View file

@ -468,7 +468,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_symbol_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
CHECK_VALID_AST(d, nullptr);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
@ -486,7 +486,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_sort_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
CHECK_VALID_AST(d, nullptr);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
@ -504,7 +504,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_ast_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
CHECK_VALID_AST(d, nullptr);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
@ -522,7 +522,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_func_decl_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
CHECK_VALID_AST(d, nullptr);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
@ -596,7 +596,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_domain(c, d, i);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
CHECK_VALID_AST(d, nullptr);
if (i >= to_func_decl(d)->get_arity()) {
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);

View file

@ -19,7 +19,7 @@ Revision History:
--*/
#include<typeinfo>
#include "api/api_context.h"
#include "util/version.h"
#include "util/z3_version.h"
#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
#include "api/api_log_macros.h"

View file

@ -379,10 +379,8 @@ extern "C" {
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]);
}
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();
ptr_vector<expr>::const_iterator end = ctx.end_assertions();
for (; it != end; ++it) {
to_fixedpoint_ref(d)->ctx().assert_expr(*it);
for (expr * e : ctx.assertions()) {
to_fixedpoint_ref(d)->ctx().assert_expr(e);
}
return of_ast_vector(v);
@ -717,5 +715,4 @@ extern "C" {
Z3_CATCH_RETURN(nullptr);
}
};

View file

@ -1,113 +0,0 @@
/*++
Copyright (c) 2017 Arie Gurfinkel
Module Name:
api_datalog_spacer.inc
Abstract:
Spacer-specific datalog API
Author:
Arie Gurfinkel (arie)
Notes:
this file is included at the bottom of api_datalog.cpp
--*/
Z3_lbool Z3_API Z3_fixedpoint_query_from_lvl (Z3_context c, Z3_fixedpoint d, Z3_ast q, unsigned lvl) {
Z3_TRY;
LOG_Z3_fixedpoint_query_from_lvl (c, d, q, lvl);
RESET_ERROR_CODE();
lbool r = l_undef;
unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
unsigned rlimit = to_fixedpoint(d)->m_params.get_uint("rlimit", mk_c(c)->get_rlimit());
{
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
api::context::set_interruptable si(*(mk_c(c)), eh);
scoped_timer timer(timeout, &eh);
try {
r = to_fixedpoint_ref(d)->ctx().query_from_lvl (to_expr(q), lvl);
}
catch (z3_exception& ex) {
mk_c(c)->handle_exception(ex);
r = l_undef;
}
to_fixedpoint_ref(d)->ctx().cleanup();
}
return of_lbool(r);
Z3_CATCH_RETURN(Z3_L_UNDEF);
}
Z3_ast Z3_API Z3_fixedpoint_get_ground_sat_answer(Z3_context c, Z3_fixedpoint d) {
Z3_TRY;
LOG_Z3_fixedpoint_get_ground_sat_answer(c, d);
RESET_ERROR_CODE();
expr* e = to_fixedpoint_ref(d)->ctx().get_ground_sat_answer();
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(nullptr);
}
Z3_ast_vector Z3_API Z3_fixedpoint_get_rules_along_trace(
Z3_context c,
Z3_fixedpoint d)
{
Z3_TRY;
LOG_Z3_fixedpoint_get_rules_along_trace(c, d);
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
svector<symbol> names;
to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names);
for (unsigned i = 0; i < rules.size(); ++i) {
v->m_ast_vector.push_back(rules[i].get());
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(nullptr);
}
Z3_symbol Z3_API Z3_fixedpoint_get_rule_names_along_trace(
Z3_context c,
Z3_fixedpoint d)
{
Z3_TRY;
LOG_Z3_fixedpoint_get_rule_names_along_trace(c, d);
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
svector<symbol> names;
std::stringstream ss;
to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names);
for (unsigned i = 0; i < names.size(); ++i) {
ss << ";" << names[i].str();
}
RETURN_Z3(of_symbol(symbol(ss.str().substr(1).c_str())));
Z3_CATCH_RETURN(nullptr);
}
void Z3_API Z3_fixedpoint_add_invariant(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred, Z3_ast property) {
Z3_TRY;
LOG_Z3_fixedpoint_add_invariant(c, d, pred, property);
RESET_ERROR_CODE();
to_fixedpoint_ref(d)->ctx ().add_invariant(to_func_decl(pred), to_expr(property));
Z3_CATCH;
}
Z3_ast Z3_API Z3_fixedpoint_get_reachable(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred) {
Z3_TRY;
LOG_Z3_fixedpoint_get_reachable(c, d, pred);
RESET_ERROR_CODE();
expr_ref r = to_fixedpoint_ref(d)->ctx().get_reachable(to_func_decl(pred));
mk_c(c)->save_ast_trail(r);
RETURN_Z3(of_expr(r.get()));
Z3_CATCH_RETURN(nullptr);
}

View file

@ -163,7 +163,7 @@ extern "C" {
if (to_goal_ref(g)->mc())
(*to_goal_ref(g)->mc())(m_ref->m_model);
RETURN_Z3(of_model(m_ref));
Z3_CATCH_RETURN(0);
Z3_CATCH_RETURN(nullptr);
}
Z3_goal Z3_API Z3_goal_translate(Z3_context c, Z3_goal g, Z3_context target) {

View file

@ -19,7 +19,7 @@ Revision History:
#include "api/z3.h"
#include "api/api_log_macros.h"
#include "util/util.h"
#include "util/version.h"
#include "util/z3_version.h"
std::ostream * g_z3_log = nullptr;
bool g_z3_log_enabled = false;

View file

@ -124,10 +124,16 @@ extern "C" {
}
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o) {
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o, unsigned num_assumptions, Z3_ast const assumptions[]) {
Z3_TRY;
LOG_Z3_optimize_check(c, o);
LOG_Z3_optimize_check(c, o, num_assumptions, assumptions);
RESET_ERROR_CODE();
for (unsigned i = 0; i < num_assumptions; i++) {
if (!is_expr(to_ast(assumptions[i]))) {
SET_ERROR_CODE(Z3_INVALID_ARG, "assumption is not an expression");
return Z3_L_UNDEF;
}
}
lbool r = l_undef;
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
unsigned timeout = to_optimize_ptr(o)->get_params().get_uint("timeout", mk_c(c)->get_timeout());
@ -137,7 +143,9 @@ extern "C" {
scoped_timer timer(timeout, &eh);
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
try {
r = to_optimize_ptr(o)->optimize();
expr_ref_vector asms(mk_c(c)->m());
asms.append(num_assumptions, to_exprs(assumptions));
r = to_optimize_ptr(o)->optimize(asms);
}
catch (z3_exception& ex) {
if (!mk_c(c)->m().canceled()) {
@ -157,6 +165,22 @@ extern "C" {
Z3_CATCH_RETURN(Z3_L_UNDEF);
}
Z3_ast_vector Z3_API Z3_optimize_get_unsat_core(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_get_unsat_core(c, o);
RESET_ERROR_CODE();
expr_ref_vector core(mk_c(c)->m());
to_optimize_ptr(o)->get_unsat_core(core);
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
mk_c(c)->save_object(v);
for (expr* e : core) {
v->m_ast_vector.push_back(e);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(nullptr);
}
Z3_string Z3_API Z3_optimize_get_reason_unknown(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_to_string(c, o);
@ -330,10 +354,8 @@ extern "C" {
return;
}
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) {
to_optimize_ptr(opt)->add_hard_constraint(*it);
for (expr * e : ctx->assertions()) {
to_optimize_ptr(opt)->add_hard_constraint(e);
}
}

View file

@ -71,10 +71,8 @@ extern "C" {
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return of_ast_vector(v);
}
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) {
v->m_ast_vector.push_back(*it);
for (expr * e : ctx->assertions()) {
v->m_ast_vector.push_back(e);
}
return of_ast_vector(v);
Z3_CATCH_RETURN(nullptr);

View file

@ -1,5 +1,5 @@
/*++
Copyright (c) 2018 Microsoft Corporation
Copyright (c) Microsoft Corporation, Arie Gurfinkel 2017
Module Name:
@ -70,39 +70,39 @@ extern "C"
}
Z3_ast Z3_API Z3_qe_model_project_skolem (Z3_context c,
Z3_model m,
Z3_model mdl,
unsigned num_bounds,
Z3_app const bound[],
Z3_ast body,
Z3_ast_map map)
{
Z3_TRY;
LOG_Z3_qe_model_project_skolem (c, m, num_bounds, bound, body, map);
LOG_Z3_qe_model_project_skolem (c, mdl, num_bounds, bound, body, map);
RESET_ERROR_CODE();
ast_manager& man = mk_c(c)->m ();
app_ref_vector vars(man);
ast_manager& m = mk_c(c)->m();
app_ref_vector vars(m);
if (!to_apps(num_bounds, bound, vars)) {
RETURN_Z3(nullptr);
}
expr_ref result (mk_c(c)->m ());
expr_ref result (m);
result = to_expr (body);
model_ref model (to_model_ref (m));
expr_map emap (man);
model_ref model (to_model_ref (mdl));
expr_map emap (m);
spacer::qe_project (mk_c(c)->m (), vars, result, model, emap);
mk_c(c)->save_ast_trail (result.get ());
spacer::qe_project(m, vars, result, model, emap);
mk_c(c)->save_ast_trail(result);
obj_map<ast, ast*> &map_z3 = to_ast_map_ref(map);
for (expr_map::iterator it = emap.begin(), end = emap.end(); it != end; ++it){
man.inc_ref(&(it->get_key()));
man.inc_ref(it->get_value());
map_z3.insert(&(it->get_key()), it->get_value());
for (auto& kv : emap) {
m.inc_ref(kv.m_key);
m.inc_ref(kv.m_value);
map_z3.insert(kv.m_key, kv.m_value);
}
return of_expr (result.get ());
return of_expr (result);
Z3_CATCH_RETURN(nullptr);
}
@ -124,9 +124,9 @@ extern "C"
expr_ref result (mk_c(c)->m ());
result = mk_and (lits);
mk_c(c)->save_ast_trail (result.get ());
mk_c(c)->save_ast_trail (result);
return of_expr (result.get ());
return of_expr (result);
Z3_CATCH_RETURN(nullptr);
}
@ -138,8 +138,8 @@ extern "C"
ast_ref_vector &vVars = to_ast_vector_ref (vars);
app_ref_vector vApps (mk_c(c)->m());
for (unsigned i = 0; i < vVars.size (); ++i) {
app *a = to_app (vVars.get (i));
for (ast* v : vVars) {
app * a = to_app(v);
if (a->get_kind () != AST_APP) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
@ -162,7 +162,7 @@ extern "C"
}
}
mk_c(c)->save_ast_trail (result.get ());
mk_c(c)->save_ast_trail (result);
return of_expr (result);
Z3_CATCH_RETURN(nullptr);
}

View file

@ -155,7 +155,7 @@ extern "C" {
expr_ref result(mk_c(c)->m());
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
RETURN_Z3(nullptr);
}
sort* const* ts = reinterpret_cast<sort * const*>(types);
@ -166,7 +166,7 @@ extern "C" {
result = mk_c(c)->m().mk_lambda(names.size(), ts, names.c_ptr(), to_expr(body));
mk_c(c)->save_ast_trail(result.get());
return of_ast(result.get());
Z3_CATCH_RETURN(0);
Z3_CATCH_RETURN(nullptr);
}
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c,
@ -178,7 +178,7 @@ extern "C" {
RESET_ERROR_CODE();
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
RETURN_Z3(nullptr);
}
svector<symbol> _names;
@ -196,7 +196,7 @@ extern "C" {
result = mk_c(c)->m().mk_lambda(_vars.size(), _vars.c_ptr(), _names.c_ptr(), result);
mk_c(c)->save_ast_trail(result.get());
return of_ast(result.get());
Z3_CATCH_RETURN(0);
Z3_CATCH_RETURN(nullptr);
}

View file

@ -157,10 +157,8 @@ extern "C" {
bool initialized = to_solver(s)->m_solver.get() != nullptr;
if (!initialized)
init_solver(c, s);
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) {
to_solver_ref(s)->assert_expr(*it);
for (expr * e : ctx->assertions()) {
to_solver_ref(s)->assert_expr(e);
}
to_solver_ref(s)->set_model_converter(ctx->get_model_converter());
}
@ -179,6 +177,7 @@ extern "C" {
LOG_Z3_solver_from_file(c, s, file_name);
char const* ext = get_extension(file_name);
std::ifstream is(file_name);
init_solver(c, s);
if (!is) {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
}
@ -368,7 +367,22 @@ extern "C" {
v->m_ast_vector.push_back(f);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);
Z3_CATCH_RETURN(nullptr);
}
Z3_ast_vector Z3_API Z3_solver_get_non_units(Z3_context c, Z3_solver s) {
Z3_TRY;
LOG_Z3_solver_get_non_units(c, s);
RESET_ERROR_CODE();
init_solver(c, s);
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
mk_c(c)->save_object(v);
expr_ref_vector fmls = to_solver_ref(s)->get_non_units(mk_c(c)->m());
for (expr* f : fmls) {
v->m_ast_vector.push_back(f);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(nullptr);
}
static Z3_lbool _solver_check(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[]) {
@ -615,7 +629,7 @@ extern "C" {
}
catch (z3_exception & ex) {
mk_c(c)->handle_exception(ex);
return 0;
return nullptr;
}
}
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
@ -628,7 +642,7 @@ extern "C" {
to_ast_vector_ref(vs).push_back(a);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);
Z3_CATCH_RETURN(nullptr);
}

View file

@ -127,6 +127,14 @@ namespace z3 {
unsat, sat, unknown
};
enum rounding_mode {
RNA,
RNE,
RTP,
RTN,
RTZ
};
inline check_result to_check_result(Z3_lbool l) {
if (l == Z3_L_TRUE) return sat;
else if (l == Z3_L_FALSE) return unsat;
@ -137,12 +145,17 @@ namespace z3 {
/**
\brief A Context manages all other Z3 objects, global configuration options, etc.
*/
class context {
private:
bool m_enable_exceptions;
rounding_mode m_rounding_mode;
Z3_context m_ctx;
void init(config & c) {
m_ctx = Z3_mk_context_rc(c);
m_enable_exceptions = true;
m_rounding_mode = RNA;
Z3_set_error_handler(m_ctx, 0);
Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
}
@ -171,7 +184,7 @@ namespace z3 {
}
/**
\brief The C++ API uses by defaults exceptions on errors.
\brief The C++ API uses by defaults exceptions on errors.
For applications that don't work well with exceptions (there should be only few)
you have the ability to turn off exceptions. The tradeoffs are that applications
have to be very careful about using check_error() after calls that may result in an
@ -247,6 +260,26 @@ namespace z3 {
*/
sort array_sort(sort d, sort r);
sort array_sort(sort_vector const& d, sort r);
/**
\brief Return a floating point sort.
\c ebits is a number of exponent bits,
\c sbits is a number of significand bits,
\pre where ebits must be larger than 1 and sbits must be larger than 2.
*/
sort fpa_sort(unsigned ebits, unsigned sbits);
/**
\brief Return a FloatingPoint sort with given precision bitwidth (16, 32, 64 or 128).
*/
template<size_t precision>
sort fpa_sort();
/**
\brief Return a RoundingMode sort.
*/
sort fpa_rounding_mode();
/**
\breif Sets RoundingMode of FloatingPoints.
*/
void set_rounding_mode(rounding_mode rm);
/**
\brief Return an enumeration sort: enum_names[0], ..., enum_names[n-1].
\c cs and \c ts are output parameters. The method stores in \c cs the constants corresponding to the enumerated elements,
@ -284,6 +317,10 @@ namespace z3 {
expr int_const(char const * name);
expr real_const(char const * name);
expr bv_const(char const * name, unsigned sz);
expr fpa_const(char const * name, unsigned ebits, unsigned sbits);
template<size_t precision>
expr fpa_const(char const * name);
expr bool_val(bool b);
@ -307,6 +344,9 @@ namespace z3 {
expr bv_val(char const * n, unsigned sz);
expr bv_val(unsigned n, bool const* bits);
expr fpa_val(double n);
expr fpa_val(float n);
expr string_val(char const* s);
expr string_val(std::string const& s);
@ -465,6 +505,7 @@ namespace z3 {
public:
sort(context & c):ast(c) {}
sort(context & c, Z3_sort s):ast(c, reinterpret_cast<Z3_ast>(s)) {}
sort(context & c, Z3_ast a):ast(c, a) {}
sort(sort const & s):ast(s) {}
operator Z3_sort() const { return reinterpret_cast<Z3_sort>(m_ast); }
/**
@ -523,6 +564,10 @@ namespace z3 {
\brief Return true if this sort is a Finite domain sort.
*/
bool is_finite_domain() const { return sort_kind() == Z3_FINITE_DOMAIN_SORT; }
/**
\brief Return true if this sort is a Floating point sort.
*/
bool is_fpa() const { return sort_kind() == Z3_FLOATING_POINT_SORT; }
/**
\brief Return the size of this Bit-vector sort.
@ -531,6 +576,9 @@ namespace z3 {
*/
unsigned bv_size() const { assert(is_bv()); unsigned r = Z3_get_bv_sort_size(ctx(), *this); check_error(); return r; }
unsigned fpa_ebits() const { assert(is_fpa()); unsigned r = Z3_fpa_get_ebits(ctx(), *this); check_error(); return r; }
unsigned fpa_sbits() const { assert(is_fpa()); unsigned r = Z3_fpa_get_sbits(ctx(), *this); check_error(); return r; }
/**
\brief Return the domain of this Array sort.
@ -634,7 +682,7 @@ namespace z3 {
\brief Return true if this is a regular expression.
*/
bool is_re() const { return get_sort().is_re(); }
/**
\brief Return true if this is a Finite-domain expression.
@ -644,6 +692,10 @@ namespace z3 {
*/
bool is_finite_domain() const { return get_sort().is_finite_domain(); }
/**
\brief Return true if this is a FloatingPoint expression. .
*/
bool is_fpa() const { return get_sort().is_fpa(); }
/**
\brief Return true if this expression is a numeral.
@ -696,29 +748,29 @@ namespace z3 {
\brief Return true if this expression is well sorted (aka type correct).
*/
bool is_well_sorted() const { bool r = Z3_is_well_sorted(ctx(), m_ast) != 0; check_error(); return r; }
/**
\brief Return string representation of numeral or algebraic number
This method assumes the expression is numeral or algebraic
\pre is_numeral() || is_algebraic()
*/
std::string get_decimal_string(int precision) const {
assert(is_numeral() || is_algebraic());
return std::string(Z3_get_numeral_decimal_string(ctx(), m_ast, precision));
}
/**
\brief Return int value of numeral, throw if result cannot fit in
machine int
It only makes sense to use this function if the caller can ensure that
the result is an integer or if exceptions are enabled.
the result is an integer or if exceptions are enabled.
If exceptions are disabled, then use the is_numeral_i function.
\pre is_numeral()
*/
int get_numeral_int() const {
int get_numeral_int() const {
int result = 0;
if (!is_numeral_i(result)) {
assert(ctx().enable_exceptions());
@ -727,13 +779,13 @@ namespace z3 {
}
return result;
}
/**
\brief Return uint value of numeral, throw if result cannot fit in
machine uint
It only makes sense to use this function if the caller can ensure that
the result is an integer or if exceptions are enabled.
the result is an integer or if exceptions are enabled.
If exceptions are disabled, then use the is_numeral_u function.
\pre is_numeral()
*/
@ -747,11 +799,11 @@ namespace z3 {
}
return result;
}
/**
\brief Return \c int64_t value of numeral, throw if result cannot fit in
\c int64_t.
\pre is_numeral()
*/
int64_t get_numeral_int64() const {
@ -764,11 +816,11 @@ namespace z3 {
}
return result;
}
/**
\brief Return \c uint64_t value of numeral, throw if result cannot fit in
\c uint64_t.
\pre is_numeral()
*/
uint64_t get_numeral_uint64() const {
@ -786,7 +838,7 @@ namespace z3 {
return Z3_get_bool_value(ctx(), m_ast);
}
expr numerator() const {
expr numerator() const {
assert(is_numeral());
Z3_ast r = Z3_get_numerator(ctx(), m_ast);
check_error();
@ -794,7 +846,7 @@ namespace z3 {
}
expr denominator() const {
expr denominator() const {
assert(is_numeral());
Z3_ast r = Z3_get_denominator(ctx(), m_ast);
check_error();
@ -803,6 +855,17 @@ namespace z3 {
operator Z3_app() const { assert(is_app()); return reinterpret_cast<Z3_app>(m_ast); }
/**
\brief Return a RoundingMode sort.
*/
sort fpa_rounding_mode() {
assert(is_fpa());
Z3_sort s = ctx().fpa_rounding_mode();
check_error();
return sort(ctx(), s);
}
/**
\brief Return the declaration associated with this application.
This method assumes the expression is an application.
@ -905,7 +968,7 @@ namespace z3 {
bool is_implies() const { return is_app() && Z3_OP_IMPLIES == decl().decl_kind(); }
bool is_eq() const { return is_app() && Z3_OP_EQ == decl().decl_kind(); }
bool is_ite() const { return is_app() && Z3_OP_ITE == decl().decl_kind(); }
friend expr distinct(expr_vector const& args);
friend expr concat(expr const& a, expr const& b);
friend expr concat(expr_vector const& args);
@ -992,23 +1055,34 @@ namespace z3 {
friend expr nor(expr const& a, expr const& b);
friend expr xnor(expr const& a, expr const& b);
friend expr min(expr const& a, expr const& b);
friend expr max(expr const& a, expr const& b);
expr rotate_left(unsigned i) { Z3_ast r = Z3_mk_rotate_left(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
expr rotate_right(unsigned i) { Z3_ast r = Z3_mk_rotate_right(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
expr repeat(unsigned i) { Z3_ast r = Z3_mk_repeat(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
friend expr abs(expr const & a);
friend expr sqrt(expr const & a, expr const & rm);
friend expr operator~(expr const & a);
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); ctx().check_error(); return expr(ctx(), r); }
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); ctx().check_error(); return expr(ctx(), r); }
unsigned lo() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 1)); }
unsigned hi() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 0)); }
/**
\brief FloatingPoint fused multiply-add.
*/
friend expr fma(expr const& a, expr const& b, expr const& c);
/**
\brief sequence and regular expression operations.
+ is overloaded as sequence concatenation and regular expression union.
concat is overloaded to handle sequences and regular expressions
*/
expr extract(expr const& offset, expr const& length) const {
expr extract(expr const& offset, expr const& length) const {
check_context(*this, offset); check_context(offset, length);
Z3_ast r = Z3_mk_seq_extract(ctx(), *this, offset, length); check_error(); return expr(ctx(), r);
Z3_ast r = Z3_mk_seq_extract(ctx(), *this, offset, length); check_error(); return expr(ctx(), r);
}
expr replace(expr const& src, expr const& dst) const {
check_context(*this, src); check_context(src, dst);
@ -1049,19 +1123,19 @@ namespace z3 {
return expr(ctx(), r);
}
friend expr range(expr const& lo, expr const& hi);
friend expr range(expr const& lo, expr const& hi);
/**
\brief create a looping regular expression.
*/
expr loop(unsigned lo) {
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, 0);
check_error();
return expr(ctx(), r);
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, 0);
check_error();
return expr(ctx(), r);
}
expr loop(unsigned lo, unsigned hi) {
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, hi);
check_error();
return expr(ctx(), r);
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, hi);
check_error();
return expr(ctx(), r);
}
@ -1094,7 +1168,7 @@ namespace z3 {
inline expr implies(expr const & a, expr const & b) {
assert(a.is_bool() && b.is_bool());
assert(a.is_bool() && b.is_bool());
_Z3_MK_BIN_(a, b, Z3_mk_implies);
}
inline expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); }
@ -1109,7 +1183,13 @@ namespace z3 {
inline expr mod(expr const & a, int b) { return mod(a, a.ctx().num_val(b, a.get_sort())); }
inline expr mod(int a, expr const & b) { return mod(b.ctx().num_val(a, b.get_sort()), b); }
inline expr rem(expr const& a, expr const& b) { _Z3_MK_BIN_(a, b, Z3_mk_rem); }
inline expr rem(expr const& a, expr const& b) {
if (a.is_fpa() && b.is_fpa()) {
_Z3_MK_BIN_(a, b, Z3_mk_fpa_rem);
} else {
_Z3_MK_BIN_(a, b, Z3_mk_rem);
}
}
inline expr rem(expr const & a, int b) { return rem(a, a.ctx().num_val(b, a.get_sort())); }
inline expr rem(int a, expr const & b) { return rem(b.ctx().num_val(a, b.get_sort()), b); }
@ -1158,8 +1238,8 @@ namespace z3 {
a.check_error();
return expr(a.ctx(), r);
}
inline expr operator==(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a == a.ctx().num_val(b, a.get_sort()); }
inline expr operator==(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) == b; }
inline expr operator==(expr const & a, int b) { assert(a.is_arith() || a.is_bv() || a.is_fpa()); return a == a.ctx().num_val(b, a.get_sort()); }
inline expr operator==(int a, expr const & b) { assert(b.is_arith() || b.is_bv() || b.is_fpa()); return b.ctx().num_val(a, b.get_sort()) == b; }
inline expr operator!=(expr const & a, expr const & b) {
check_context(a, b);
@ -1168,8 +1248,8 @@ namespace z3 {
a.check_error();
return expr(a.ctx(), r);
}
inline expr operator!=(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a != a.ctx().num_val(b, a.get_sort()); }
inline expr operator!=(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) != b; }
inline expr operator!=(expr const & a, int b) { assert(a.is_arith() || a.is_bv() || a.is_fpa()); return a != a.ctx().num_val(b, a.get_sort()); }
inline expr operator!=(int a, expr const & b) { assert(b.is_arith() || b.is_bv() || b.is_fpa()); return b.ctx().num_val(a, b.get_sort()) != b; }
inline expr operator+(expr const & a, expr const & b) {
check_context(a, b);
@ -1188,6 +1268,9 @@ namespace z3 {
Z3_ast _args[2] = { a, b };
r = Z3_mk_re_union(a.ctx(), 2, _args);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_add(a.ctx(), a.ctx().fpa_rounding_mode(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1208,6 +1291,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvmul(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_mul(a.ctx(), a.ctx().fpa_rounding_mode(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1245,6 +1331,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvsdiv(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_div(a.ctx(), a.ctx().fpa_rounding_mode(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1263,6 +1352,9 @@ namespace z3 {
else if (a.is_bv()) {
r = Z3_mk_bvneg(a.ctx(), a);
}
else if (a.is_fpa()) {
r = Z3_mk_fpa_neg(a.ctx(), a);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1281,6 +1373,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvsub(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_sub(a.ctx(), a.ctx().fpa_rounding_mode(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1300,6 +1395,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvsle(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_leq(a.ctx(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1322,6 +1420,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvslt(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_lt(a.ctx(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1341,6 +1442,9 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvsgt(a.ctx(), a, b);
}
else if (a.is_fpa() && b.is_fpa()) {
r = Z3_mk_fpa_gt(a.ctx(), a, b);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1366,17 +1470,30 @@ namespace z3 {
inline expr nand(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvnand(a.ctx(), a, b); return expr(a.ctx(), r); }
inline expr nor(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvnor(a.ctx(), a, b); return expr(a.ctx(), r); }
inline expr xnor(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvxnor(a.ctx(), a, b); return expr(a.ctx(), r); }
inline expr min(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_fpa_min(a.ctx(), a, b); return expr(a.ctx(), r); }
inline expr max(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_fpa_max(a.ctx(), a, b); return expr(a.ctx(), r); }
inline expr abs(expr const & a) { Z3_ast r = Z3_mk_fpa_abs(a.ctx(), a); return expr(a.ctx(), r); }
inline expr sqrt(expr const & a, expr const& rm) {
check_context(a, rm);
assert(a.is_fpa());
Z3_ast r = Z3_mk_fpa_sqrt(a.ctx(), rm, a);
return expr(a.ctx(), r);
}
inline expr operator~(expr const & a) { Z3_ast r = Z3_mk_bvnot(a.ctx(), a); return expr(a.ctx(), r); }
inline expr fma(expr const& a, expr const& b, expr const& c, expr const& rm) {
check_context(a, b); check_context(a, c); check_context(a, rm);
assert(a.is_fpa() && b.is_fpa() && c.is_fpa());
Z3_ast r = Z3_mk_fpa_fma(a.ctx(), rm, a, b, c);
a.check_error();
return expr(a.ctx(), r);
}
/**
\brief Create the if-then-else expression <tt>ite(c, t, e)</tt>
\pre c.is_bool()
*/
inline expr ite(expr const & c, expr const & t, expr const & e) {
check_context(c, t); check_context(c, e);
assert(c.is_bool());
@ -1453,45 +1570,45 @@ namespace z3 {
inline expr smod(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsmod(a.ctx(), a, b)); }
inline expr smod(expr const & a, int b) { return smod(a, a.ctx().num_val(b, a.get_sort())); }
inline expr smod(int a, expr const & b) { return smod(b.ctx().num_val(a, b.get_sort()), b); }
/**
\brief unsigned reminder operator for bitvectors
*/
inline expr urem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvurem(a.ctx(), a, b)); }
inline expr urem(expr const & a, int b) { return urem(a, a.ctx().num_val(b, a.get_sort())); }
inline expr urem(int a, expr const & b) { return urem(b.ctx().num_val(a, b.get_sort()), b); }
/**
\brief shift left operator for bitvectors
*/
inline expr shl(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvshl(a.ctx(), a, b)); }
inline expr shl(expr const & a, int b) { return shl(a, a.ctx().num_val(b, a.get_sort())); }
inline expr shl(int a, expr const & b) { return shl(b.ctx().num_val(a, b.get_sort()), b); }
/**
\brief logic shift right operator for bitvectors
*/
inline expr lshr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvlshr(a.ctx(), a, b)); }
inline expr lshr(expr const & a, int b) { return lshr(a, a.ctx().num_val(b, a.get_sort())); }
inline expr lshr(int a, expr const & b) { return lshr(b.ctx().num_val(a, b.get_sort()), b); }
/**
\brief arithmetic shift right operator for bitvectors
*/
inline expr ashr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvashr(a.ctx(), a, b)); }
inline expr ashr(expr const & a, int b) { return ashr(a, a.ctx().num_val(b, a.get_sort())); }
inline expr ashr(int a, expr const & b) { return ashr(b.ctx().num_val(a, b.get_sort()), b); }
/**
\brief Extend the given bit-vector with zeros to the (unsigned) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
*/
inline expr zext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_zero_ext(a.ctx(), i, a)); }
/**
\brief Sign-extend of the given bit-vector to the (signed) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
*/
inline expr sext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_sign_ext(a.ctx(), i, a)); }
template<typename T> class cast_ast;
template<> class cast_ast<ast> {
@ -1563,7 +1680,7 @@ namespace z3 {
unsigned m_index;
public:
iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {}
iterator(iterator& other): m_vector(other.m_vector), m_index(other.m_index) {}
iterator(iterator& other): m_vector(other.m_vector), m_index(other.m_index) {}
iterator operator=(iterator const& other) { m_vector = other.m_vector; m_index = other.m_index; return *this; }
bool operator==(iterator const& other) {
@ -1773,7 +1890,7 @@ namespace z3 {
return expr(ctx, r);
}
inline expr mk_or(expr_vector const& args) {
inline expr mk_or(expr_vector const& args) {
array<Z3_ast> _args(args);
Z3_ast r = Z3_mk_or(args.ctx(), _args.size(), _args.ptr());
args.check_error();
@ -1852,7 +1969,7 @@ namespace z3 {
model(context & c):object(c) { init(Z3_mk_model(c)); }
model(context & c, Z3_model m):object(c) { init(m); }
model(model const & s):object(s) { init(s.m_model); }
model(model& src, context& dst, translate) : object(dst) { init(Z3_model_translate(src.ctx(), src, dst)); }
model(model& src, context& dst, translate) : object(dst) { init(Z3_model_translate(src.ctx(), src, dst)); }
~model() { Z3_model_dec_ref(ctx(), m_model); }
operator Z3_model() const { return m_model; }
model & operator=(model const & s) {
@ -1884,7 +2001,7 @@ namespace z3 {
}
// returns interpretation of constant declaration c.
// If c is not assigned any value in the model it returns
// If c is not assigned any value in the model it returns
// an expression with a null ast reference.
expr get_const_interp(func_decl c) const {
check_context(*this, c);
@ -1898,7 +2015,7 @@ namespace z3 {
check_error();
return func_interp(ctx(), r);
}
// returns true iff the model contains an interpretation
// for function f.
bool has_interp(func_decl f) const {
@ -1945,7 +2062,7 @@ namespace z3 {
bool is_uint(unsigned i) const { Z3_bool r = Z3_stats_is_uint(ctx(), m_stats, i); check_error(); return r != 0; }
bool is_double(unsigned i) const { Z3_bool r = Z3_stats_is_double(ctx(), m_stats, i); check_error(); return r != 0; }
unsigned uint_value(unsigned i) const { unsigned r = Z3_stats_get_uint_value(ctx(), m_stats, i); check_error(); return r; }
double double_value(unsigned i) const { double r = Z3_stats_get_double_value(ctx(), m_stats, i); check_error(); return r; }
double double_value(unsigned i) const { double r = Z3_stats_get_double_value(ctx(), m_stats, i); check_error(); return r; }
friend std::ostream & operator<<(std::ostream & out, stats const & s);
};
inline std::ostream & operator<<(std::ostream & out, stats const & s) { out << Z3_stats_to_string(s.ctx(), s); return out; }
@ -2001,7 +2118,7 @@ namespace z3 {
void add(expr const & e, char const * p) {
add(e, ctx().bool_const(p));
}
// fails for some compilers:
// fails for some compilers:
// void add(expr_vector const& v) { check_context(*this, v); for (expr e : v) add(e); }
void from_file(char const* file) { Z3_solver_from_file(ctx(), m_solver, file); ctx().check_parser_error(); }
void from_string(char const* s) { Z3_solver_from_string(ctx(), m_solver, s); ctx().check_parser_error(); }
@ -2038,6 +2155,8 @@ namespace z3 {
stats statistics() const { Z3_stats r = Z3_solver_get_statistics(ctx(), m_solver); check_error(); return stats(ctx(), r); }
expr_vector unsat_core() const { Z3_ast_vector r = Z3_solver_get_unsat_core(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
expr_vector non_units() const { Z3_ast_vector r = Z3_solver_get_non_units(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
expr_vector units() const { Z3_ast_vector r = Z3_solver_get_units(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); }
friend std::ostream & operator<<(std::ostream & out, solver const & s);
@ -2064,11 +2183,11 @@ namespace z3 {
param_descrs get_param_descrs() { return param_descrs(ctx(), Z3_solver_get_param_descrs(ctx(), m_solver)); }
expr_vector cube(expr_vector& vars, unsigned cutoff) {
Z3_ast_vector r = Z3_solver_cube(ctx(), m_solver, vars, cutoff);
check_error();
return expr_vector(ctx(), r);
}
expr_vector cube(expr_vector& vars, unsigned cutoff) {
Z3_ast_vector r = Z3_solver_cube(ctx(), m_solver, vars, cutoff);
check_error();
return expr_vector(ctx(), r);
}
class cube_iterator {
solver& m_solver;
@ -2116,7 +2235,7 @@ namespace z3 {
cube_iterator operator++(int) { assert(false); return *this; }
expr_vector const * operator->() const { return &(operator*()); }
expr_vector const& operator*() const { return m_cube; }
bool operator==(cube_iterator const& other) {
return other.m_end == m_end;
};
@ -2405,7 +2524,7 @@ namespace z3 {
class optimize : public object {
Z3_optimize m_opt;
public:
class handle {
unsigned m_h;
@ -2453,8 +2572,20 @@ namespace z3 {
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); }
check_result check() { Z3_lbool r = Z3_optimize_check(ctx(), m_opt, 0, 0); check_error(); return to_check_result(r); }
check_result check(expr_vector const& asms) {
unsigned n = asms.size();
array<Z3_ast> _asms(n);
for (unsigned i = 0; i < n; i++) {
check_context(*this, asms[i]);
_asms[i] = asms[i];
}
Z3_lbool r = Z3_optimize_check(ctx(), m_opt, n, _asms.ptr());
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); }
expr_vector unsat_core() const { Z3_ast_vector r = Z3_optimize_get_unsat_core(ctx(), m_opt); check_error(); return expr_vector(ctx(), r); }
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());
@ -2481,25 +2612,25 @@ namespace z3 {
public:
fixedpoint(context& c):object(c) { m_fp = Z3_mk_fixedpoint(c); Z3_fixedpoint_inc_ref(c, m_fp); }
~fixedpoint() { Z3_fixedpoint_dec_ref(ctx(), m_fp); }
operator Z3_fixedpoint() const { return m_fp; }
operator Z3_fixedpoint() const { return m_fp; }
void from_string(char const* s) { Z3_fixedpoint_from_string(ctx(), m_fp, s); check_error(); }
void from_file(char const* s) { Z3_fixedpoint_from_file(ctx(), m_fp, s); check_error(); }
void add_rule(expr& rule, symbol const& name) { Z3_fixedpoint_add_rule(ctx(), m_fp, rule, name); check_error(); }
void add_fact(func_decl& f, unsigned * args) { Z3_fixedpoint_add_fact(ctx(), m_fp, f, f.arity(), args); check_error(); }
check_result query(expr& q) { Z3_lbool r = Z3_fixedpoint_query(ctx(), m_fp, q); check_error(); return to_check_result(r); }
check_result query(func_decl_vector& relations) {
check_result query(func_decl_vector& relations) {
array<Z3_func_decl> rs(relations);
Z3_lbool r = Z3_fixedpoint_query_relations(ctx(), m_fp, rs.size(), rs.ptr());
check_error();
return to_check_result(r);
Z3_lbool r = Z3_fixedpoint_query_relations(ctx(), m_fp, rs.size(), rs.ptr());
check_error();
return to_check_result(r);
}
expr get_answer() { Z3_ast r = Z3_fixedpoint_get_answer(ctx(), m_fp); check_error(); return expr(ctx(), r); }
std::string reason_unknown() { return Z3_fixedpoint_get_reason_unknown(ctx(), m_fp); }
void update_rule(expr& rule, symbol const& name) { Z3_fixedpoint_update_rule(ctx(), m_fp, rule, name); check_error(); }
unsigned get_num_levels(func_decl& p) { unsigned r = Z3_fixedpoint_get_num_levels(ctx(), m_fp, p); check_error(); return r; }
expr get_cover_delta(int level, func_decl& p) {
Z3_ast r = Z3_fixedpoint_get_cover_delta(ctx(), m_fp, level, p);
check_error();
expr get_cover_delta(int level, func_decl& p) {
Z3_ast r = Z3_fixedpoint_get_cover_delta(ctx(), m_fp, level, p);
check_error();
return expr(ctx(), r);
}
void add_cover(int level, func_decl& p, expr& property) { Z3_fixedpoint_add_cover(ctx(), m_fp, level, p, property); check_error(); }
@ -2513,7 +2644,7 @@ namespace z3 {
std::string to_string() { return Z3_fixedpoint_to_string(ctx(), m_fp, 0, 0); }
std::string to_string(expr_vector const& queries) {
array<Z3_ast> qs(queries);
return Z3_fixedpoint_to_string(ctx(), m_fp, qs.size(), qs.ptr());
return Z3_fixedpoint_to_string(ctx(), m_fp, qs.size(), qs.ptr());
}
void push() { Z3_fixedpoint_push(ctx(), m_fp); check_error(); }
void pop() { Z3_fixedpoint_pop(ctx(), m_fp); check_error(); }
@ -2548,11 +2679,37 @@ namespace z3 {
inline sort context::string_sort() { Z3_sort s = Z3_mk_string_sort(m_ctx); check_error(); return sort(*this, s); }
inline sort context::seq_sort(sort& s) { Z3_sort r = Z3_mk_seq_sort(m_ctx, s); check_error(); return sort(*this, r); }
inline sort context::re_sort(sort& s) { Z3_sort r = Z3_mk_re_sort(m_ctx, s); check_error(); return sort(*this, r); }
inline sort context::fpa_sort(unsigned ebits, unsigned sbits) { Z3_sort s = Z3_mk_fpa_sort(m_ctx, ebits, sbits); check_error(); return sort(*this, s); }
template<>
inline sort context::fpa_sort<16>() { return fpa_sort(5, 11); }
template<>
inline sort context::fpa_sort<32>() { return fpa_sort(8, 24); }
template<>
inline sort context::fpa_sort<64>() { return fpa_sort(11, 53); }
template<>
inline sort context::fpa_sort<128>() { return fpa_sort(15, 113); }
inline sort context::fpa_rounding_mode() {
switch (m_rounding_mode) {
case RNA: return sort(*this, Z3_mk_fpa_rna(m_ctx));
case RNE: return sort(*this, Z3_mk_fpa_rne(m_ctx));
case RTP: return sort(*this, Z3_mk_fpa_rtp(m_ctx));
case RTN: return sort(*this, Z3_mk_fpa_rtn(m_ctx));
case RTZ: return sort(*this, Z3_mk_fpa_rtz(m_ctx));
default: return sort(*this);
}
}
inline void context::set_rounding_mode(rounding_mode rm) { m_rounding_mode = rm; }
inline sort context::array_sort(sort d, sort r) { Z3_sort s = Z3_mk_array_sort(m_ctx, d, r); check_error(); return sort(*this, s); }
inline sort context::array_sort(sort_vector const& d, sort r) {
array<Z3_sort> dom(d);
Z3_sort s = Z3_mk_array_sort_n(m_ctx, dom.size(), dom.ptr(), r); check_error(); return sort(*this, s);
Z3_sort s = Z3_mk_array_sort_n(m_ctx, dom.size(), dom.ptr(), r); check_error(); return sort(*this, s);
}
inline sort context::enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts) {
array<Z3_symbol> _enum_names(n);
@ -2667,6 +2824,10 @@ namespace z3 {
inline expr context::int_const(char const * name) { return constant(name, int_sort()); }
inline expr context::real_const(char const * name) { return constant(name, real_sort()); }
inline expr context::bv_const(char const * name, unsigned sz) { return constant(name, bv_sort(sz)); }
inline expr context::fpa_const(char const * name, unsigned ebits, unsigned sbits) { return constant(name, fpa_sort(ebits, sbits)); }
template<size_t precision>
inline expr context::fpa_const(char const * name) { return constant(name, fpa_sort<precision>()); }
inline expr context::bool_val(bool b) { return b ? expr(*this, Z3_mk_true(m_ctx)) : expr(*this, Z3_mk_false(m_ctx)); }
@ -2688,12 +2849,15 @@ namespace z3 {
inline expr context::bv_val(int64_t n, unsigned sz) { sort s = bv_sort(sz); Z3_ast r = Z3_mk_int64(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr context::bv_val(uint64_t n, unsigned sz) { sort s = bv_sort(sz); Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr context::bv_val(char const * n, unsigned sz) { sort s = bv_sort(sz); Z3_ast r = Z3_mk_numeral(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr context::bv_val(unsigned n, bool const* bits) {
inline expr context::bv_val(unsigned n, bool const* bits) {
array<Z3_bool> _bits(n);
for (unsigned i = 0; i < n; ++i) _bits[i] = bits[i] ? 1 : 0;
Z3_ast r = Z3_mk_bv_numeral(m_ctx, n, _bits.ptr()); check_error(); return expr(*this, r);
Z3_ast r = Z3_mk_bv_numeral(m_ctx, n, _bits.ptr()); check_error(); return expr(*this, r);
}
inline expr context::fpa_val(double n) { sort s = fpa_sort<64>(); Z3_ast r = Z3_mk_fpa_numeral_double(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr context::fpa_val(float n) { sort s = fpa_sort<32>(); Z3_ast r = Z3_mk_fpa_numeral_float(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr context::string_val(char const* s) { Z3_ast r = Z3_mk_string(m_ctx, s); check_error(); return expr(*this, r); }
inline expr context::string_val(std::string const& s) { Z3_ast r = Z3_mk_string(m_ctx, s.c_str()); check_error(); return expr(*this, r); }
@ -2817,8 +2981,8 @@ namespace z3 {
a.check_error();
return expr(a.ctx(), r);
}
inline expr select(expr const & a, int i) {
return select(a, a.ctx().num_val(i, a.get_sort().array_domain()));
inline expr select(expr const & a, int i) {
return select(a, a.ctx().num_val(i, a.get_sort().array_domain()));
}
inline expr select(expr const & a, expr_vector const & i) {
check_context(a, i);
@ -2848,10 +3012,10 @@ namespace z3 {
return expr(a.ctx(), r);
}
inline expr as_array(func_decl & f) {
Z3_ast r = Z3_mk_as_array(f.ctx(), f);
f.check_error();
return expr(f.ctx(), r);
inline expr as_array(func_decl & f) {
Z3_ast r = Z3_mk_as_array(f.ctx(), f);
f.check_error();
return expr(f.ctx(), r);
}
#define MK_EXPR1(_fn, _arg) \
@ -2883,21 +3047,21 @@ namespace z3 {
inline expr set_del(expr const& s, expr const& e) {
MK_EXPR2(Z3_mk_set_del, s, e);
}
}
inline expr set_union(expr const& a, expr const& b) {
check_context(a, b);
check_context(a, b);
Z3_ast es[2] = { a, b };
Z3_ast r = Z3_mk_set_union(a.ctx(), 2, es);
a.check_error();
a.check_error();
return expr(a.ctx(), r);
}
inline expr set_intersect(expr const& a, expr const& b) {
check_context(a, b);
check_context(a, b);
Z3_ast es[2] = { a, b };
Z3_ast r = Z3_mk_set_intersect(a.ctx(), 2, es);
a.check_error();
a.check_error();
return expr(a.ctx(), r);
}
@ -2981,10 +3145,10 @@ namespace z3 {
MK_EXPR1(Z3_mk_re_complement, a);
}
inline expr range(expr const& lo, expr const& hi) {
check_context(lo, hi);
Z3_ast r = Z3_mk_re_range(lo.ctx(), lo, hi);
lo.check_error();
return expr(lo.ctx(), r);
check_context(lo, hi);
Z3_ast r = Z3_mk_re_range(lo.ctx(), lo, hi);
lo.check_error();
return expr(lo.ctx(), r);
}
@ -2995,7 +3159,7 @@ namespace z3 {
Z3_ast_vector r = Z3_parse_smtlib2_string(*this, s, 0, 0, 0, 0, 0, 0);
check_error();
return expr_vector(*this, r);
}
inline expr_vector context::parse_file(char const* s) {
Z3_ast_vector r = Z3_parse_smtlib2_file(*this, s, 0, 0, 0, 0, 0, 0);

View file

@ -147,11 +147,6 @@ if (DOTNET_TOOLCHAIN_IS_WINDOWS)
"/nostdlib+"
"/reference:mscorlib.dll"
)
# FIXME: This flag only works when the working directory of csc.exe is
# the directory containing the ``libz3`` target. I can't get this to work
# correctly with multi-configuration generators (i.e. Visual Studio) so
# just don't set the flag for now.
#list(APPEND CSC_FLAGS "/linkresource:$<TARGET_FILE_NAME:libz3>")
elseif (DOTNET_TOOLCHAIN_IS_MONO)
# We need to give the assembly a strong name so that it can be installed
# into the GAC.

View file

@ -183,9 +183,9 @@ namespace Microsoft.Z3
/// don't use strict inequalities) meets the objectives.
/// </summary>
///
public Status Check()
public Status Check(params Expr[] assumptions)
{
Z3_lbool r = (Z3_lbool)Native.Z3_optimize_check(Context.nCtx, NativeObject);
Z3_lbool r = (Z3_lbool)Native.Z3_optimize_check(Context.nCtx, NativeObject, (uint)assumptions.Length, AST.ArrayToNative(assumptions));
switch (r)
{
case Z3_lbool.Z3_L_TRUE:
@ -236,6 +236,25 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// The unsat core of the last <c>Check</c>.
/// </summary>
/// <remarks>
/// The unsat core is a subset of <c>assumptions</c>
/// The result is empty if <c>Check</c> was not invoked before,
/// if its results was not <c>UNSATISFIABLE</c>, or if core production is disabled.
/// </remarks>
public BoolExpr[] UnsatCore
{
get
{
Contract.Ensures(Contract.Result<Expr[]>() != null);
ASTVector core = new ASTVector(Context, Native.Z3_optimize_get_unsat_core(Context.nCtx, NativeObject));
return core.ToBoolExprArray();
}
}
/// <summary>
/// Declare an arithmetical maximization objective.
/// Return a handle to the objective. The handle is used as

View file

@ -1976,6 +1976,22 @@ public class Context implements AutoCloseable {
{
return (SeqExpr) Expr.create(this, Native.mkString(nCtx(), s));
}
/**
* Convert an integer expression to a string.
*/
public SeqExpr intToString(Expr e)
{
return (SeqExpr) Expr.create(this, Native.mkIntToStr(nCtx(), e.getNativeObject()));
}
/**
* Convert an integer expression to a string.
*/
public IntExpr stringToInt(Expr e)
{
return (IntExpr) Expr.create(this, Native.mkStrToInt(nCtx(), e.getNativeObject()));
}
/**
* Concatenate sequences.

View file

@ -161,9 +161,23 @@ public class Optimize extends Z3Object {
* Produce a model that (when the objectives are bounded and
* don't use strict inequalities) meets the objectives.
**/
public Status Check()
public Status Check(Expr... assumptions)
{
Z3_lbool r = Z3_lbool.fromInt(Native.optimizeCheck(getContext().nCtx(), getNativeObject()));
Z3_lbool r;
if (assumptions == null) {
r = Z3_lbool.fromInt(
Native.optimizeCheck(
getContext().nCtx(),
getNativeObject(), 0, null));
}
else {
r = Z3_lbool.fromInt(
Native.optimizeCheck(
getContext().nCtx(),
getNativeObject(),
assumptions.length,
AST.arrayToNative(assumptions)));
}
switch (r) {
case Z3_L_TRUE:
return Status.SATISFIABLE;
@ -209,6 +223,21 @@ public class Optimize extends Z3Object {
}
}
/**
* The unsat core of the last {@code Check}.
* Remarks: The unsat core
* is a subset of {@code Assumptions} The result is empty if
* {@code Check} was not invoked before, if its results was not
* {@code UNSATISFIABLE}, or if core production is disabled.
*
* @throws Z3Exception
**/
public BoolExpr[] getUnsatCore()
{
ASTVector core = new ASTVector(getContext(), Native.optimizeGetUnsatCore(getContext().nCtx(), getNativeObject()));
return core.ToBoolExprArray();
}
/**
* Declare an arithmetical maximization objective.
* Return a handle to the objective. The handle is used as

View file

@ -43,6 +43,14 @@ let mk_list f n =
in
mk_list' 0 []
let check_int32 v = v = Int32.to_int (Int32.of_int v)
let mk_int_expr ctx v ty =
if not (check_int32 v) then
Z3native.mk_numeral ctx (string_of_int v) ty
else
Z3native.mk_int ctx v ty
let mk_context (settings:(string * string) list) =
let cfg = Z3native.mk_config () in
let f e = Z3native.set_param_value cfg (fst e) (snd e) in
@ -531,7 +539,7 @@ end = struct
let mk_fresh_const (ctx:context) (prefix:string) (range:Sort.sort) = Z3native.mk_fresh_const ctx prefix range
let mk_app (ctx:context) (f:FuncDecl.func_decl) (args:expr list) = expr_of_func_app ctx f args
let mk_numeral_string (ctx:context) (v:string) (ty:Sort.sort) = Z3native.mk_numeral ctx v ty
let mk_numeral_int (ctx:context) (v:int) (ty:Sort.sort) = Z3native.mk_int ctx v ty
let mk_numeral_int (ctx:context) (v:int) (ty:Sort.sort) = mk_int_expr ctx v ty
let equal (a:expr) (b:expr) = AST.equal a b
let compare (a:expr) (b:expr) = AST.compare a b
end
@ -1036,7 +1044,7 @@ struct
let mk_mod = Z3native.mk_mod
let mk_rem = Z3native.mk_rem
let mk_numeral_s (ctx:context) (v:string) = Z3native.mk_numeral ctx v (mk_sort ctx)
let mk_numeral_i (ctx:context) (v:int) = Z3native.mk_int ctx v (mk_sort ctx)
let mk_numeral_i (ctx:context) (v:int) = mk_int_expr ctx v (mk_sort ctx)
let mk_int2real = Z3native.mk_int2real
let mk_int2bv = Z3native.mk_int2bv
end
@ -1061,11 +1069,13 @@ struct
let mk_numeral_nd (ctx:context) (num:int) (den:int) =
if den = 0 then
raise (Error "Denominator is zero")
else if not (check_int32 num) || not (check_int32 den) then
raise (Error "numerals don't fit in 32 bits")
else
Z3native.mk_real ctx num den
let mk_numeral_s (ctx:context) (v:string) = Z3native.mk_numeral ctx v (mk_sort ctx)
let mk_numeral_i (ctx:context) (v:int) = Z3native.mk_int ctx v (mk_sort ctx)
let mk_numeral_i (ctx:context) (v:int) = mk_int_expr ctx v (mk_sort ctx)
let mk_is_integer = Z3native.mk_is_int
let mk_real2int = Z3native.mk_real2int
@ -1155,11 +1165,6 @@ struct
let is_bv_xor3 (x:expr) = (AST.is_app x) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) = OP_XOR3)
let get_size (x:Sort.sort) = Z3native.get_bv_sort_size (Sort.gc x) x
let get_int (x:expr) =
match Z3native.get_numeral_int (Expr.gc x) x with
| true, v -> v
| false, _ -> raise (Error "Conversion failed.")
let numeral_to_string (x:expr) = Z3native.get_numeral_string (Expr.gc x) x
let mk_const (ctx:context) (name:Symbol.symbol) (size:int) =
Expr.mk_const ctx name (mk_sort ctx size)
@ -1810,8 +1815,10 @@ struct
| _ -> UNKNOWN
let get_model x =
let q = Z3native.solver_get_model (gc x) x in
if Z3native.is_null_model q then None else Some q
try
let q = Z3native.solver_get_model (gc x) x in
if Z3native.is_null_model q then None else Some q
with | _ -> None
let get_proof x =
let q = Z3native.solver_get_proof (gc x) x in
@ -1940,15 +1947,17 @@ struct
let minimize (x:optimize) (e:Expr.expr) = mk_handle x (Z3native.optimize_minimize (gc x) x e)
let check (x:optimize) =
let r = lbool_of_int (Z3native.optimize_check (gc x) x) in
let r = lbool_of_int (Z3native.optimize_check (gc x) x) 0 [] in
match r with
| L_TRUE -> Solver.SATISFIABLE
| L_FALSE -> Solver.UNSATISFIABLE
| _ -> Solver.UNKNOWN
let get_model (x:optimize) =
let q = Z3native.optimize_get_model (gc x) x in
if Z3native.is_null_model q then None else Some q
try
let q = Z3native.optimize_get_model (gc x) x in
if Z3native.is_null_model q then None else Some q
with | _ -> None
let get_lower (x:handle) = Z3native.optimize_get_lower (gc x.opt) x.opt x.h
let get_upper (x:handle) = Z3native.optimize_get_upper (gc x.opt) x.opt x.h

View file

@ -1152,9 +1152,6 @@ sig
(** Create a new integer sort. *)
val mk_sort : context -> Sort.sort
(** Retrieve the int value. *)
val get_int : Expr.expr -> int
(** Get a big_int from an integer numeral *)
val get_big_int : Expr.expr -> Big_int.big_int
@ -1543,9 +1540,6 @@ sig
(** The size of a bit-vector sort. *)
val get_size : Sort.sort -> int
(** Retrieve the int value. *)
val get_int : Expr.expr -> int
(** Returns a string representation of a numeral. *)
val numeral_to_string : Expr.expr -> string
@ -3413,10 +3407,10 @@ sig
(** Parse the given string using the SMT-LIB2 parser.
@return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *)
val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr
val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> AST.ASTVector.ast_vector
(** Parse the given file using the SMT-LIB2 parser. *)
val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr
val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> AST.ASTVector.ast_vector
end

View file

@ -12,8 +12,8 @@ If you are using a 64-bit Python interpreter, you should use
msbuild /p:configuration=external /p:platform=x64
On Linux and OSX, you must install Z3Py, before trying example.py.
To install Z3Py on Linux and OSX, you should execute the following
On Linux and macOS, you must install Z3Py, before trying example.py.
To install Z3Py on Linux and macOS, you should execute the following
command in the Z3 root directory
sudo make install-z3py

View file

@ -73,7 +73,7 @@ def _build_z3():
if subprocess.call(['nmake'], env=build_env,
cwd=BUILD_DIR) != 0:
raise LibError("Unable to build Z3.")
else: # linux and osx
else: # linux and macOS
if subprocess.call(['make', '-j', str(multiprocessing.cpu_count())],
env=build_env, cwd=BUILD_DIR) != 0:
raise LibError("Unable to build Z3.")

View file

@ -1258,6 +1258,11 @@ def Consts(names, sort):
names = names.split(" ")
return [Const(name, sort) for name in names]
def FreshConst(sort, prefix='c'):
"""Create a fresh constant of a specified sort"""
ctx = _get_ctx(sort.ctx)
return _to_expr_ref(Z3_mk_fresh_const(ctx.ref(), prefix, sort.ast), ctx)
def Var(idx, s):
"""Create a Z3 free variable. Free variables are used to create quantified formulas.
@ -1744,7 +1749,9 @@ class QuantifierRef(BoolRef):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def sort(self):
"""Return the Boolean sort."""
"""Return the Boolean sort or sort of Lambda."""
if self.is_lambda():
return _sort(self.ctx, self.as_ast())
return BoolSort(self.ctx)
def is_forall(self):
@ -2176,6 +2183,8 @@ class ArithRef(ExprRef):
>>> (x * y).sort()
Real
"""
if isinstance(other, BoolRef):
return If(other, self, 0)
a, b = _coerce_exprs(self, other)
return ArithRef(_mk_bin(Z3_mk_mul, a, b), self.ctx)
@ -4278,7 +4287,7 @@ def get_map_func(a):
_z3_assert(is_map(a), "Z3 array map expression expected.")
return FuncDeclRef(Z3_to_func_decl(a.ctx_ref(), Z3_get_decl_ast_parameter(a.ctx_ref(), a.decl().ast, 0)), a.ctx)
def ArraySort(d, r):
def ArraySort(*sig):
"""Return the Z3 array sort with the given domain and range sorts.
>>> A = ArraySort(IntSort(), BoolSort())
@ -4292,12 +4301,23 @@ def ArraySort(d, r):
>>> AA
Array(Int, Array(Int, Bool))
"""
sig = _get_args(sig)
if __debug__:
_z3_assert(is_sort(d), "Z3 sort expected")
_z3_assert(is_sort(r), "Z3 sort expected")
_z3_assert(d.ctx == r.ctx, "Context mismatch")
_z3_assert(len(sig) > 1, "At least two arguments expected")
arity = len(sig) - 1
r = sig[arity]
d = sig[0]
if __debug__:
for s in sig:
_z3_assert(is_sort(s), "Z3 sort expected")
_z3_assert(s.ctx == r.ctx, "Context mismatch")
ctx = d.ctx
return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
if len(sig) == 2:
return ArraySortRef(Z3_mk_array_sort(ctx.ref(), d.ast, r.ast), ctx)
dom = (Sort * arity)()
for i in range(arity):
dom[i] = sig[i].ast
return ArraySortRef(Z3_mk_array_sort_n(ctx.ref(), arity, dom, r.ast), ctx)
def Array(name, dom, rng):
"""Return an array constant named `name` with the given domain and range sorts.
@ -6603,7 +6623,12 @@ class Solver(Z3PPObject):
_handle_parse_error(e, self.ctx)
def cube(self, vars = None):
"""Get set of cubes"""
"""Get set of cubes
The method takes an optional set of variables that restrict which
variables may be used as a starting point for cubing.
If vars is not None, then the first case split is based on a variable in
this set.
"""
self.cube_vs = AstVector(None, self.ctx)
if vars is not None:
for v in vars:
@ -6619,19 +6644,15 @@ class Solver(Z3PPObject):
return
def cube_vars(self):
"""Access the set of variables that were touched by the most recently generated cube.
This set of variables can be used as a starting point for additional cubes.
The idea is that variables that appear in clauses that are reduced by the most recent
cube are likely more useful to cube on."""
return self.cube_vs
def proof(self):
"""Return a proof for the last `check()`. Proof construction must be enabled."""
return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
def from_file(self, filename):
"""Parse assertions from a file"""
Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
def from_string(self, s):
"""Parse assertions from a string"""
Z3_solver_from_string(self.ctx.ref(), self.solver, s)
def assertions(self):
"""Return an AST vector containing all added constraints.
@ -6652,6 +6673,11 @@ class Solver(Z3PPObject):
"""
return AstVector(Z3_solver_get_units(self.ctx.ref(), self.solver), self.ctx)
def non_units(self):
"""Return an AST vector containing all atomic formulas in solver state that are not units.
"""
return AstVector(Z3_solver_get_non_units(self.ctx.ref(), self.solver), self.ctx)
def statistics(self):
"""Return statistics for the last `check()`.
@ -7285,10 +7311,15 @@ class Optimize(Z3PPObject):
"""restore to previously created backtracking point"""
Z3_optimize_pop(self.ctx.ref(), self.optimize)
def check(self):
def check(self, *assumptions):
"""Check satisfiability while optimizing objective functions."""
return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize))
assumptions = _get_args(assumptions)
num = len(assumptions)
_assumptions = (Ast * num)()
for i in range(num):
_assumptions[i] = assumptions[i].as_ast()
return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize, num, _assumptions))
def reason_unknown(self):
"""Return a string that describes why the last `check()` returned `unknown`."""
return Z3_optimize_get_reason_unknown(self.ctx.ref(), self.optimize)
@ -7300,6 +7331,9 @@ class Optimize(Z3PPObject):
except Z3Exception:
raise Z3Exception("model is not available")
def unsat_core(self):
return AstVector(Z3_optimize_get_unsat_core(self.ctx.ref(), self.optimize), self.ctx)
def lower(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
@ -8040,7 +8074,7 @@ def substitute(t, *m):
"""
if isinstance(m, tuple):
m1 = _get_args(m)
if isinstance(m1, list):
if isinstance(m1, list) and all(isinstance(p, tuple) for p in m1):
m = m1
if __debug__:
_z3_assert(is_expr(t), "Z3 expression expected")

View file

@ -6121,6 +6121,14 @@ extern "C" {
*/
Z3_ast_vector Z3_API Z3_solver_get_units(Z3_context c, Z3_solver s);
/**
\brief Return the set of non units in the solver state.
def_API('Z3_solver_get_non_units', AST_VECTOR, (_in(CONTEXT), _in(SOLVER)))
*/
Z3_ast_vector Z3_API Z3_solver_get_non_units(Z3_context c, Z3_solver s);
/**
\brief Check whether the assertions in a given solver are consistent or not.

View file

@ -117,10 +117,12 @@ extern "C" {
\brief Check consistency and produce optimal values.
\param c - context
\param o - optimization context
\param num_assumptions - number of additional assumptions
\param assumptions - the additional assumptions
def_API('Z3_optimize_check', INT, (_in(CONTEXT), _in(OPTIMIZE)))
def_API('Z3_optimize_check', INT, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT), _in_array(2, AST)))
*/
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o);
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o, unsigned num_assumptions, Z3_ast const assumptions[]);
/**
@ -143,6 +145,14 @@ extern "C" {
*/
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o);
/**
\brief Retrieve the unsat core for the last #Z3_optimize_chec
The unsat core is a subset of the assumptions \c a.
def_API('Z3_optimize_get_unsat_core', AST_VECTOR, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_ast_vector Z3_API Z3_optimize_get_unsat_core(Z3_context c, Z3_optimize o);
/**
\brief Set parameters on optimization context.