00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef Z3PP_H_
00022 #define Z3PP_H_
00023
00024 #include<cassert>
00025 #include<iostream>
00026 #include<string>
00027 #include<sstream>
00028 #include<z3.h>
00029 #include<limits.h>
00030
00036
00041
00045 namespace z3 {
00046
00047 class exception;
00048 class config;
00049 class context;
00050 class symbol;
00051 class params;
00052 class ast;
00053 class sort;
00054 class func_decl;
00055 class expr;
00056 class solver;
00057 class goal;
00058 class tactic;
00059 class probe;
00060 class model;
00061 class func_interp;
00062 class func_entry;
00063 class statistics;
00064 class apply_result;
00065 class fixedpoint;
00066 template<typename T> class ast_vector_tpl;
00067 typedef ast_vector_tpl<ast> ast_vector;
00068 typedef ast_vector_tpl<expr> expr_vector;
00069 typedef ast_vector_tpl<sort> sort_vector;
00070 typedef ast_vector_tpl<func_decl> func_decl_vector;
00071
00072 inline void set_param(char const * param, char const * value) { Z3_global_param_set(param, value); }
00073 inline void set_param(char const * param, bool value) { Z3_global_param_set(param, value ? "true" : "false"); }
00074 inline void set_param(char const * param, int value) { std::ostringstream oss; oss << value; Z3_global_param_set(param, oss.str().c_str()); }
00075 inline void reset_params() { Z3_global_param_reset_all(); }
00076
00080 class exception {
00081 std::string m_msg;
00082 public:
00083 exception(char const * msg):m_msg(msg) {}
00084 char const * msg() const { return m_msg.c_str(); }
00085 friend std::ostream & operator<<(std::ostream & out, exception const & e) { out << e.msg(); return out; }
00086 };
00087
00088
00089
00093 class config {
00094 Z3_config m_cfg;
00095 config(config const & s);
00096 config & operator=(config const & s);
00097 public:
00098 config() { m_cfg = Z3_mk_config(); }
00099 ~config() { Z3_del_config(m_cfg); }
00100 operator Z3_config() const { return m_cfg; }
00104 void set(char const * param, char const * value) { Z3_set_param_value(m_cfg, param, value); }
00108 void set(char const * param, bool value) { Z3_set_param_value(m_cfg, param, value ? "true" : "false"); }
00112 void set(char const * param, int value) {
00113 std::ostringstream oss;
00114 oss << value;
00115 Z3_set_param_value(m_cfg, param, oss.str().c_str());
00116 }
00117 };
00118
00122 class context {
00123 Z3_context m_ctx;
00124 static void error_handler(Z3_context c, Z3_error_code e) { }
00125 void init(config & c) {
00126 m_ctx = Z3_mk_context_rc(c);
00127 Z3_set_error_handler(m_ctx, error_handler);
00128 Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
00129 }
00130 context(context const & s);
00131 context & operator=(context const & s);
00132 public:
00133 context() { config c; init(c); }
00134 context(config & c) { init(c); }
00135 ~context() { Z3_del_context(m_ctx); }
00136 operator Z3_context() const { return m_ctx; }
00137
00141 void check_error() const {
00142 Z3_error_code e = Z3_get_error_code(m_ctx);
00143 if (e != Z3_OK)
00144 throw exception(Z3_get_error_msg_ex(m_ctx, e));
00145 }
00146
00150 void set(char const * param, char const * value) { Z3_update_param_value(m_ctx, param, value); }
00154 void set(char const * param, bool value) { Z3_update_param_value(m_ctx, param, value ? "true" : "false"); }
00158 void set(char const * param, int value) {
00159 std::ostringstream oss;
00160 oss << value;
00161 Z3_update_param_value(m_ctx, param, oss.str().c_str());
00162 }
00163
00168 void interrupt() { Z3_interrupt(m_ctx); }
00169
00173 symbol str_symbol(char const * s);
00177 symbol int_symbol(int n);
00181 sort bool_sort();
00185 sort int_sort();
00189 sort real_sort();
00193 sort bv_sort(unsigned sz);
00199 sort array_sort(sort d, sort r);
00205 sort enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts);
00209 sort uninterpreted_sort(char const* name);
00210 sort uninterpreted_sort(symbol const& name);
00211
00212 func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range);
00213 func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range);
00214 func_decl function(symbol const& name, sort_vector const& domain, sort const& range);
00215 func_decl function(char const * name, sort_vector const& domain, sort const& range);
00216 func_decl function(char const * name, sort const & domain, sort const & range);
00217 func_decl function(char const * name, sort const & d1, sort const & d2, sort const & range);
00218 func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range);
00219 func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range);
00220 func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range);
00221
00222 expr constant(symbol const & name, sort const & s);
00223 expr constant(char const * name, sort const & s);
00224 expr bool_const(char const * name);
00225 expr int_const(char const * name);
00226 expr real_const(char const * name);
00227 expr bv_const(char const * name, unsigned sz);
00228
00229 expr bool_val(bool b);
00230
00231 expr int_val(int n);
00232 expr int_val(unsigned n);
00233 expr int_val(__int64 n);
00234 expr int_val(__uint64 n);
00235 expr int_val(char const * n);
00236
00237 expr real_val(int n, int d);
00238 expr real_val(int n);
00239 expr real_val(unsigned n);
00240 expr real_val(__int64 n);
00241 expr real_val(__uint64 n);
00242 expr real_val(char const * n);
00243
00244 expr bv_val(int n, unsigned sz);
00245 expr bv_val(unsigned n, unsigned sz);
00246 expr bv_val(__int64 n, unsigned sz);
00247 expr bv_val(__uint64 n, unsigned sz);
00248 expr bv_val(char const * n, unsigned sz);
00249
00250 expr num_val(int n, sort const & s);
00251 };
00252
00253 template<typename T>
00254 class array {
00255 T * m_array;
00256 unsigned m_size;
00257 array(array const & s);
00258 array & operator=(array const & s);
00259 public:
00260 array(unsigned sz):m_size(sz) { m_array = new T[sz]; }
00261 template<typename T2>
00262 array(ast_vector_tpl<T2> const & v);
00263 ~array() { delete[] m_array; }
00264 unsigned size() const { return m_size; }
00265 T & operator[](int i) { assert(0 <= i); assert(static_cast<unsigned>(i) < m_size); return m_array[i]; }
00266 T const & operator[](int i) const { assert(0 <= i); assert(static_cast<unsigned>(i) < m_size); return m_array[i]; }
00267 T const * ptr() const { return m_array; }
00268 T * ptr() { return m_array; }
00269 };
00270
00271 class object {
00272 protected:
00273 context * m_ctx;
00274 public:
00275 object(context & c):m_ctx(&c) {}
00276 object(object const & s):m_ctx(s.m_ctx) {}
00277 context & ctx() const { return *m_ctx; }
00278 void check_error() const { m_ctx->check_error(); }
00279 friend void check_context(object const & a, object const & b);
00280 };
00281 inline void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); }
00282
00283 class symbol : public object {
00284 Z3_symbol m_sym;
00285 public:
00286 symbol(context & c, Z3_symbol s):object(c), m_sym(s) {}
00287 symbol(symbol const & s):object(s), m_sym(s.m_sym) {}
00288 symbol & operator=(symbol const & s) { m_ctx = s.m_ctx; m_sym = s.m_sym; return *this; }
00289 operator Z3_symbol() const { return m_sym; }
00290 Z3_symbol_kind kind() const { return Z3_get_symbol_kind(ctx(), m_sym); }
00291 std::string str() const { assert(kind() == Z3_STRING_SYMBOL); return Z3_get_symbol_string(ctx(), m_sym); }
00292 int to_int() const { assert(kind() == Z3_INT_SYMBOL); return Z3_get_symbol_int(ctx(), m_sym); }
00293 friend std::ostream & operator<<(std::ostream & out, symbol const & s) {
00294 if (s.kind() == Z3_INT_SYMBOL)
00295 out << "k!" << s.to_int();
00296 else
00297 out << s.str().c_str();
00298 return out;
00299 }
00300 };
00301
00302
00303 class params : public object {
00304 Z3_params m_params;
00305 public:
00306 params(context & c):object(c) { m_params = Z3_mk_params(c); Z3_params_inc_ref(ctx(), m_params); }
00307 params(params const & s):object(s), m_params(s.m_params) { Z3_params_inc_ref(ctx(), m_params); }
00308 ~params() { Z3_params_dec_ref(ctx(), m_params); }
00309 operator Z3_params() const { return m_params; }
00310 params & operator=(params const & s) {
00311 Z3_params_inc_ref(s.ctx(), s.m_params);
00312 Z3_params_dec_ref(ctx(), m_params);
00313 m_ctx = s.m_ctx;
00314 m_params = s.m_params;
00315 return *this;
00316 }
00317 void set(char const * k, bool b) { Z3_params_set_bool(ctx(), m_params, ctx().str_symbol(k), b); }
00318 void set(char const * k, unsigned n) { Z3_params_set_uint(ctx(), m_params, ctx().str_symbol(k), n); }
00319 void set(char const * k, double n) { Z3_params_set_double(ctx(), m_params, ctx().str_symbol(k), n); }
00320 void set(char const * k, symbol const & s) { Z3_params_set_symbol(ctx(), m_params, ctx().str_symbol(k), s); }
00321 friend std::ostream & operator<<(std::ostream & out, params const & p) {
00322 out << Z3_params_to_string(p.ctx(), p); return out;
00323 }
00324 };
00325
00326 class ast : public object {
00327 protected:
00328 Z3_ast m_ast;
00329 public:
00330 ast(context & c):object(c), m_ast(0) {}
00331 ast(context & c, Z3_ast n):object(c), m_ast(n) { Z3_inc_ref(ctx(), m_ast); }
00332 ast(ast const & s):object(s), m_ast(s.m_ast) { Z3_inc_ref(ctx(), m_ast); }
00333 ~ast() { if (m_ast) Z3_dec_ref(*m_ctx, m_ast); }
00334 operator Z3_ast() const { return m_ast; }
00335 operator bool() const { return m_ast != 0; }
00336 ast & operator=(ast const & s) { Z3_inc_ref(s.ctx(), s.m_ast); if (m_ast) Z3_dec_ref(ctx(), m_ast); m_ctx = s.m_ctx; m_ast = s.m_ast; return *this; }
00337 Z3_ast_kind kind() const { Z3_ast_kind r = Z3_get_ast_kind(ctx(), m_ast); check_error(); return r; }
00338 unsigned hash() const { unsigned r = Z3_get_ast_hash(ctx(), m_ast); check_error(); return r; }
00339 friend std::ostream & operator<<(std::ostream & out, ast const & n) {
00340 out << Z3_ast_to_string(n.ctx(), n.m_ast); return out;
00341 }
00342
00346 friend bool eq(ast const & a, ast const & b);
00347 };
00348
00349 inline bool eq(ast const & a, ast const & b) { return Z3_is_eq_ast(a.ctx(), a, b) != 0; }
00350
00351
00355 class sort : public ast {
00356 public:
00357 sort(context & c):ast(c) {}
00358 sort(context & c, Z3_sort s):ast(c, reinterpret_cast<Z3_ast>(s)) {}
00359 sort(sort const & s):ast(s) {}
00360 operator Z3_sort() const { return reinterpret_cast<Z3_sort>(m_ast); }
00364 sort & operator=(sort const & s) { return static_cast<sort&>(ast::operator=(s)); }
00368 Z3_sort_kind sort_kind() const { return Z3_get_sort_kind(*m_ctx, *this); }
00369
00373 bool is_bool() const { return sort_kind() == Z3_BOOL_SORT; }
00377 bool is_int() const { return sort_kind() == Z3_INT_SORT; }
00381 bool is_real() const { return sort_kind() == Z3_REAL_SORT; }
00385 bool is_arith() const { return is_int() || is_real(); }
00389 bool is_bv() const { return sort_kind() == Z3_BV_SORT; }
00393 bool is_array() const { return sort_kind() == Z3_ARRAY_SORT; }
00397 bool is_datatype() const { return sort_kind() == Z3_DATATYPE_SORT; }
00401 bool is_relation() const { return sort_kind() == Z3_RELATION_SORT; }
00405 bool is_finite_domain() const { return sort_kind() == Z3_FINITE_DOMAIN_SORT; }
00406
00412 unsigned bv_size() const { assert(is_bv()); unsigned r = Z3_get_bv_sort_size(ctx(), *this); check_error(); return r; }
00413
00419 sort array_domain() const { assert(is_array()); Z3_sort s = Z3_get_array_sort_domain(ctx(), *this); check_error(); return sort(ctx(), s); }
00425 sort array_range() const { assert(is_array()); Z3_sort s = Z3_get_array_sort_range(ctx(), *this); check_error(); return sort(ctx(), s); }
00426 };
00427
00432 class func_decl : public ast {
00433 public:
00434 func_decl(context & c):ast(c) {}
00435 func_decl(context & c, Z3_func_decl n):ast(c, reinterpret_cast<Z3_ast>(n)) {}
00436 func_decl(func_decl const & s):ast(s) {}
00437 operator Z3_func_decl() const { return reinterpret_cast<Z3_func_decl>(m_ast); }
00438 func_decl & operator=(func_decl const & s) { return static_cast<func_decl&>(ast::operator=(s)); }
00439
00440 unsigned arity() const { return Z3_get_arity(ctx(), *this); }
00441 sort domain(unsigned i) const { assert(i < arity()); Z3_sort r = Z3_get_domain(ctx(), *this, i); check_error(); return sort(ctx(), r); }
00442 sort range() const { Z3_sort r = Z3_get_range(ctx(), *this); check_error(); return sort(ctx(), r); }
00443 symbol name() const { Z3_symbol s = Z3_get_decl_name(ctx(), *this); check_error(); return symbol(ctx(), s); }
00444 Z3_decl_kind decl_kind() const { return Z3_get_decl_kind(ctx(), *this); }
00445
00446 bool is_const() const { return arity() == 0; }
00447
00448 expr operator()() const;
00449 expr operator()(unsigned n, expr const * args) const;
00450 expr operator()(expr_vector const& v) const;
00451 expr operator()(expr const & a) const;
00452 expr operator()(int a) const;
00453 expr operator()(expr const & a1, expr const & a2) const;
00454 expr operator()(expr const & a1, int a2) const;
00455 expr operator()(int a1, expr const & a2) const;
00456 expr operator()(expr const & a1, expr const & a2, expr const & a3) const;
00457 expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const;
00458 expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const;
00459 };
00460
00465 class expr : public ast {
00466 public:
00467 expr(context & c):ast(c) {}
00468 expr(context & c, Z3_ast n):ast(c, reinterpret_cast<Z3_ast>(n)) {}
00469 expr(expr const & n):ast(n) {}
00470 expr & operator=(expr const & n) { return static_cast<expr&>(ast::operator=(n)); }
00471
00475 sort get_sort() const { Z3_sort s = Z3_get_sort(*m_ctx, m_ast); check_error(); return sort(*m_ctx, s); }
00476
00480 bool is_bool() const { return get_sort().is_bool(); }
00484 bool is_int() const { return get_sort().is_int(); }
00488 bool is_real() const { return get_sort().is_real(); }
00492 bool is_arith() const { return get_sort().is_arith(); }
00496 bool is_bv() const { return get_sort().is_bv(); }
00500 bool is_array() const { return get_sort().is_array(); }
00504 bool is_datatype() const { return get_sort().is_datatype(); }
00508 bool is_relation() const { return get_sort().is_relation(); }
00517 bool is_finite_domain() const { return get_sort().is_finite_domain(); }
00518
00522 bool is_numeral() const { return kind() == Z3_NUMERAL_AST; }
00526 bool is_app() const { return kind() == Z3_APP_AST || kind() == Z3_NUMERAL_AST; }
00530 bool is_const() const { return is_app() && num_args() == 0; }
00534 bool is_quantifier() const { return kind() == Z3_QUANTIFIER_AST; }
00538 bool is_var() const { return kind() == Z3_VAR_AST; }
00539
00543 bool is_well_sorted() const { bool r = Z3_is_well_sorted(ctx(), m_ast) != 0; check_error(); return r; }
00544
00545 operator Z3_app() const { assert(is_app()); return reinterpret_cast<Z3_app>(m_ast); }
00546
00553 func_decl decl() const { Z3_func_decl f = Z3_get_app_decl(ctx(), *this); check_error(); return func_decl(ctx(), f); }
00560 unsigned num_args() const { unsigned r = Z3_get_app_num_args(ctx(), *this); check_error(); return r; }
00568 expr arg(unsigned i) const { Z3_ast r = Z3_get_app_arg(ctx(), *this, i); check_error(); return expr(ctx(), r); }
00569
00575 expr body() const { assert(is_quantifier()); Z3_ast r = Z3_get_quantifier_body(ctx(), *this); check_error(); return expr(ctx(), r); }
00576
00582 friend expr operator!(expr const & a) {
00583 assert(a.is_bool());
00584 Z3_ast r = Z3_mk_not(a.ctx(), a);
00585 a.check_error();
00586 return expr(a.ctx(), r);
00587 }
00588
00589
00596 friend expr operator&&(expr const & a, expr const & b) {
00597 check_context(a, b);
00598 assert(a.is_bool() && b.is_bool());
00599 Z3_ast args[2] = { a, b };
00600 Z3_ast r = Z3_mk_and(a.ctx(), 2, args);
00601 a.check_error();
00602 return expr(a.ctx(), r);
00603 }
00604
00605
00612 friend expr operator&&(expr const & a, bool b) { return a && a.ctx().bool_val(b); }
00619 friend expr operator&&(bool a, expr const & b) { return b.ctx().bool_val(a) && b; }
00620
00627 friend expr operator||(expr const & a, expr const & b) {
00628 check_context(a, b);
00629 assert(a.is_bool() && b.is_bool());
00630 Z3_ast args[2] = { a, b };
00631 Z3_ast r = Z3_mk_or(a.ctx(), 2, args);
00632 a.check_error();
00633 return expr(a.ctx(), r);
00634 }
00641 friend expr operator||(expr const & a, bool b) { return a || a.ctx().bool_val(b); }
00648 friend expr operator||(bool a, expr const & b) { return b.ctx().bool_val(a) || b; }
00649
00650 friend expr implies(expr const & a, expr const & b) {
00651 check_context(a, b);
00652 assert(a.is_bool() && b.is_bool());
00653 Z3_ast r = Z3_mk_implies(a.ctx(), a, b);
00654 a.check_error();
00655 return expr(a.ctx(), r);
00656 }
00657 friend expr implies(expr const & a, bool b);
00658 friend expr implies(bool a, expr const & b);
00659
00660 friend expr ite(expr const & c, expr const & t, expr const & e);
00661
00662 friend expr distinct(expr_vector const& args);
00663 friend expr concat(expr const& a, expr const& b);
00664
00665 friend expr operator==(expr const & a, expr const & b) {
00666 check_context(a, b);
00667 Z3_ast r = Z3_mk_eq(a.ctx(), a, b);
00668 a.check_error();
00669 return expr(a.ctx(), r);
00670 }
00671 friend expr operator==(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a == a.ctx().num_val(b, a.get_sort()); }
00672 friend expr operator==(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) == b; }
00673
00674 friend expr operator!=(expr const & a, expr const & b) {
00675 check_context(a, b);
00676 Z3_ast args[2] = { a, b };
00677 Z3_ast r = Z3_mk_distinct(a.ctx(), 2, args);
00678 a.check_error();
00679 return expr(a.ctx(), r);
00680 }
00681 friend expr operator!=(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a != a.ctx().num_val(b, a.get_sort()); }
00682 friend expr operator!=(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) != b; }
00683
00684 friend expr operator+(expr const & a, expr const & b) {
00685 check_context(a, b);
00686 Z3_ast r = 0;
00687 if (a.is_arith() && b.is_arith()) {
00688 Z3_ast args[2] = { a, b };
00689 r = Z3_mk_add(a.ctx(), 2, args);
00690 }
00691 else if (a.is_bv() && b.is_bv()) {
00692 r = Z3_mk_bvadd(a.ctx(), a, b);
00693 }
00694 else {
00695
00696 assert(false);
00697 }
00698 a.check_error();
00699 return expr(a.ctx(), r);
00700 }
00701 friend expr operator+(expr const & a, int b) { return a + a.ctx().num_val(b, a.get_sort()); }
00702 friend expr operator+(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) + b; }
00703
00704 friend expr operator*(expr const & a, expr const & b) {
00705 check_context(a, b);
00706 Z3_ast r = 0;
00707 if (a.is_arith() && b.is_arith()) {
00708 Z3_ast args[2] = { a, b };
00709 r = Z3_mk_mul(a.ctx(), 2, args);
00710 }
00711 else if (a.is_bv() && b.is_bv()) {
00712 r = Z3_mk_bvmul(a.ctx(), a, b);
00713 }
00714 else {
00715
00716 assert(false);
00717 }
00718 a.check_error();
00719 return expr(a.ctx(), r);
00720 }
00721 friend expr operator*(expr const & a, int b) { return a * a.ctx().num_val(b, a.get_sort()); }
00722 friend expr operator*(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) * b; }
00723
00727 friend expr pw(expr const & a, expr const & b);
00728 friend expr pw(expr const & a, int b);
00729 friend expr pw(int a, expr const & b);
00730
00731 friend expr operator/(expr const & a, expr const & b) {
00732 check_context(a, b);
00733 Z3_ast r = 0;
00734 if (a.is_arith() && b.is_arith()) {
00735 r = Z3_mk_div(a.ctx(), a, b);
00736 }
00737 else if (a.is_bv() && b.is_bv()) {
00738 r = Z3_mk_bvsdiv(a.ctx(), a, b);
00739 }
00740 else {
00741
00742 assert(false);
00743 }
00744 a.check_error();
00745 return expr(a.ctx(), r);
00746 }
00747 friend expr operator/(expr const & a, int b) { return a / a.ctx().num_val(b, a.get_sort()); }
00748 friend expr operator/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; }
00749
00750 friend expr operator-(expr const & a) {
00751 Z3_ast r = 0;
00752 if (a.is_arith()) {
00753 r = Z3_mk_unary_minus(a.ctx(), a);
00754 }
00755 else if (a.is_bv()) {
00756 r = Z3_mk_bvneg(a.ctx(), a);
00757 }
00758 else {
00759
00760 assert(false);
00761 }
00762 a.check_error();
00763 return expr(a.ctx(), r);
00764 }
00765
00766 friend expr operator-(expr const & a, expr const & b) {
00767 check_context(a, b);
00768 Z3_ast r = 0;
00769 if (a.is_arith() && b.is_arith()) {
00770 Z3_ast args[2] = { a, b };
00771 r = Z3_mk_sub(a.ctx(), 2, args);
00772 }
00773 else if (a.is_bv() && b.is_bv()) {
00774 r = Z3_mk_bvsub(a.ctx(), a, b);
00775 }
00776 else {
00777
00778 assert(false);
00779 }
00780 a.check_error();
00781 return expr(a.ctx(), r);
00782 }
00783 friend expr operator-(expr const & a, int b) { return a - a.ctx().num_val(b, a.get_sort()); }
00784 friend expr operator-(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) - b; }
00785
00786 friend expr operator<=(expr const & a, expr const & b) {
00787 check_context(a, b);
00788 Z3_ast r = 0;
00789 if (a.is_arith() && b.is_arith()) {
00790 r = Z3_mk_le(a.ctx(), a, b);
00791 }
00792 else if (a.is_bv() && b.is_bv()) {
00793 r = Z3_mk_bvsle(a.ctx(), a, b);
00794 }
00795 else {
00796
00797 assert(false);
00798 }
00799 a.check_error();
00800 return expr(a.ctx(), r);
00801 }
00802 friend expr operator<=(expr const & a, int b) { return a <= a.ctx().num_val(b, a.get_sort()); }
00803 friend expr operator<=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) <= b; }
00804
00805 friend expr operator>=(expr const & a, expr const & b) {
00806 check_context(a, b);
00807 Z3_ast r = 0;
00808 if (a.is_arith() && b.is_arith()) {
00809 r = Z3_mk_ge(a.ctx(), a, b);
00810 }
00811 else if (a.is_bv() && b.is_bv()) {
00812 r = Z3_mk_bvsge(a.ctx(), a, b);
00813 }
00814 else {
00815
00816 assert(false);
00817 }
00818 a.check_error();
00819 return expr(a.ctx(), r);
00820 }
00821 friend expr operator>=(expr const & a, int b) { return a >= a.ctx().num_val(b, a.get_sort()); }
00822 friend expr operator>=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) >= b; }
00823
00824 friend expr operator<(expr const & a, expr const & b) {
00825 check_context(a, b);
00826 Z3_ast r = 0;
00827 if (a.is_arith() && b.is_arith()) {
00828 r = Z3_mk_lt(a.ctx(), a, b);
00829 }
00830 else if (a.is_bv() && b.is_bv()) {
00831 r = Z3_mk_bvslt(a.ctx(), a, b);
00832 }
00833 else {
00834
00835 assert(false);
00836 }
00837 a.check_error();
00838 return expr(a.ctx(), r);
00839 }
00840 friend expr operator<(expr const & a, int b) { return a < a.ctx().num_val(b, a.get_sort()); }
00841 friend expr operator<(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) < b; }
00842
00843 friend expr operator>(expr const & a, expr const & b) {
00844 check_context(a, b);
00845 Z3_ast r = 0;
00846 if (a.is_arith() && b.is_arith()) {
00847 r = Z3_mk_gt(a.ctx(), a, b);
00848 }
00849 else if (a.is_bv() && b.is_bv()) {
00850 r = Z3_mk_bvsgt(a.ctx(), a, b);
00851 }
00852 else {
00853
00854 assert(false);
00855 }
00856 a.check_error();
00857 return expr(a.ctx(), r);
00858 }
00859 friend expr operator>(expr const & a, int b) { return a > a.ctx().num_val(b, a.get_sort()); }
00860 friend expr operator>(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) > b; }
00861
00862 friend expr operator&(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvand(a.ctx(), a, b); return expr(a.ctx(), r); }
00863 friend expr operator&(expr const & a, int b) { return a & a.ctx().num_val(b, a.get_sort()); }
00864 friend expr operator&(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) & b; }
00865
00866 friend expr operator^(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvxor(a.ctx(), a, b); return expr(a.ctx(), r); }
00867 friend expr operator^(expr const & a, int b) { return a ^ a.ctx().num_val(b, a.get_sort()); }
00868 friend expr operator^(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) ^ b; }
00869
00870 friend expr operator|(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvor(a.ctx(), a, b); return expr(a.ctx(), r); }
00871 friend expr operator|(expr const & a, int b) { return a | a.ctx().num_val(b, a.get_sort()); }
00872 friend expr operator|(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) | b; }
00873
00874 friend expr operator~(expr const & a) { Z3_ast r = Z3_mk_bvnot(a.ctx(), a); return expr(a.ctx(), r); }
00875 expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); return expr(ctx(), r); }
00876 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)); }
00877 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)); }
00878
00882 expr simplify() const { Z3_ast r = Z3_simplify(ctx(), m_ast); check_error(); return expr(ctx(), r); }
00886 expr simplify(params const & p) const { Z3_ast r = Z3_simplify_ex(ctx(), m_ast, p); check_error(); return expr(ctx(), r); }
00887
00891 expr substitute(expr_vector const& src, expr_vector const& dst);
00892
00896 expr substitute(expr_vector const& dst);
00897
00898 };
00899
00900 inline expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); }
00901 inline expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); }
00902
00903 inline expr pw(expr const & a, expr const & b) {
00904 assert(a.is_arith() && b.is_arith());
00905 check_context(a, b);
00906 Z3_ast r = Z3_mk_power(a.ctx(), a, b);
00907 a.check_error();
00908 return expr(a.ctx(), r);
00909 }
00910 inline expr pw(expr const & a, int b) { return pw(a, a.ctx().num_val(b, a.get_sort())); }
00911 inline expr pw(int a, expr const & b) { return pw(b.ctx().num_val(a, b.get_sort()), b); }
00912
00913
00914
00915
00916
00923 inline expr ite(expr const & c, expr const & t, expr const & e) {
00924 check_context(c, t); check_context(c, e);
00925 assert(c.is_bool());
00926 Z3_ast r = Z3_mk_ite(c.ctx(), c, t, e);
00927 c.check_error();
00928 return expr(c.ctx(), r);
00929 }
00930
00931
00936 inline expr to_expr(context & c, Z3_ast a) {
00937 c.check_error();
00938 assert(Z3_get_ast_kind(c, a) == Z3_APP_AST ||
00939 Z3_get_ast_kind(c, a) == Z3_NUMERAL_AST ||
00940 Z3_get_ast_kind(c, a) == Z3_VAR_AST ||
00941 Z3_get_ast_kind(c, a) == Z3_QUANTIFIER_AST);
00942 return expr(c, a);
00943 }
00944
00945 inline sort to_sort(context & c, Z3_sort s) {
00946 c.check_error();
00947 return sort(c, s);
00948 }
00949
00950 inline func_decl to_func_decl(context & c, Z3_func_decl f) {
00951 c.check_error();
00952 return func_decl(c, f);
00953 }
00954
00958 inline expr ule(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvule(a.ctx(), a, b)); }
00959 inline expr ule(expr const & a, int b) { return ule(a, a.ctx().num_val(b, a.get_sort())); }
00960 inline expr ule(int a, expr const & b) { return ule(b.ctx().num_val(a, b.get_sort()), b); }
00964 inline expr ult(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvult(a.ctx(), a, b)); }
00965 inline expr ult(expr const & a, int b) { return ult(a, a.ctx().num_val(b, a.get_sort())); }
00966 inline expr ult(int a, expr const & b) { return ult(b.ctx().num_val(a, b.get_sort()), b); }
00970 inline expr uge(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvuge(a.ctx(), a, b)); }
00971 inline expr uge(expr const & a, int b) { return uge(a, a.ctx().num_val(b, a.get_sort())); }
00972 inline expr uge(int a, expr const & b) { return uge(b.ctx().num_val(a, b.get_sort()), b); }
00976 inline expr ugt(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvugt(a.ctx(), a, b)); }
00977 inline expr ugt(expr const & a, int b) { return ugt(a, a.ctx().num_val(b, a.get_sort())); }
00978 inline expr ugt(int a, expr const & b) { return ugt(b.ctx().num_val(a, b.get_sort()), b); }
00982 inline expr udiv(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvudiv(a.ctx(), a, b)); }
00983 inline expr udiv(expr const & a, int b) { return udiv(a, a.ctx().num_val(b, a.get_sort())); }
00984 inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); }
00985
00986 template<typename T> class cast_ast;
00987
00988 template<> class cast_ast<ast> {
00989 public:
00990 ast operator()(context & c, Z3_ast a) { return ast(c, a); }
00991 };
00992
00993 template<> class cast_ast<expr> {
00994 public:
00995 expr operator()(context & c, Z3_ast a) {
00996 assert(Z3_get_ast_kind(c, a) == Z3_NUMERAL_AST ||
00997 Z3_get_ast_kind(c, a) == Z3_APP_AST ||
00998 Z3_get_ast_kind(c, a) == Z3_QUANTIFIER_AST ||
00999 Z3_get_ast_kind(c, a) == Z3_VAR_AST);
01000 return expr(c, a);
01001 }
01002 };
01003
01004 template<> class cast_ast<sort> {
01005 public:
01006 sort operator()(context & c, Z3_ast a) {
01007 assert(Z3_get_ast_kind(c, a) == Z3_SORT_AST);
01008 return sort(c, reinterpret_cast<Z3_sort>(a));
01009 }
01010 };
01011
01012 template<> class cast_ast<func_decl> {
01013 public:
01014 func_decl operator()(context & c, Z3_ast a) {
01015 assert(Z3_get_ast_kind(c, a) == Z3_FUNC_DECL_AST);
01016 return func_decl(c, reinterpret_cast<Z3_func_decl>(a));
01017 }
01018 };
01019
01020 template<typename T>
01021 class ast_vector_tpl : public object {
01022 Z3_ast_vector m_vector;
01023 void init(Z3_ast_vector v) { Z3_ast_vector_inc_ref(ctx(), v); m_vector = v; }
01024 public:
01025 ast_vector_tpl(context & c):object(c) { init(Z3_mk_ast_vector(c)); }
01026 ast_vector_tpl(context & c, Z3_ast_vector v):object(c) { init(v); }
01027 ast_vector_tpl(ast_vector_tpl const & s):object(s), m_vector(s.m_vector) { Z3_ast_vector_inc_ref(ctx(), m_vector); }
01028 ~ast_vector_tpl() { Z3_ast_vector_dec_ref(ctx(), m_vector); }
01029 operator Z3_ast_vector() const { return m_vector; }
01030 unsigned size() const { return Z3_ast_vector_size(ctx(), m_vector); }
01031 T operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_ast_vector_get(ctx(), m_vector, i); check_error(); return cast_ast<T>()(ctx(), r); }
01032 void push_back(T const & e) { Z3_ast_vector_push(ctx(), m_vector, e); check_error(); }
01033 void resize(unsigned sz) { Z3_ast_vector_resize(ctx(), m_vector, sz); check_error(); }
01034 T back() const { return operator[](size() - 1); }
01035 void pop_back() { assert(size() > 0); resize(size() - 1); }
01036 bool empty() const { return size() == 0; }
01037 ast_vector_tpl & operator=(ast_vector_tpl const & s) {
01038 Z3_ast_vector_inc_ref(s.ctx(), s.m_vector);
01039 Z3_ast_vector_dec_ref(ctx(), m_vector);
01040 m_ctx = s.m_ctx;
01041 m_vector = s.m_vector;
01042 return *this;
01043 }
01044 friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; }
01045 };
01046
01047 template<typename T>
01048 template<typename T2>
01049 array<T>::array(ast_vector_tpl<T2> const & v) {
01050 m_array = new T[v.size()];
01051 m_size = v.size();
01052 for (unsigned i = 0; i < m_size; i++) {
01053 m_array[i] = v[i];
01054 }
01055 }
01056
01057
01058
01059 inline expr forall(expr const & x, expr const & b) {
01060 check_context(x, b);
01061 Z3_app vars[] = {(Z3_app) x};
01062 Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01063 }
01064 inline expr forall(expr const & x1, expr const & x2, expr const & b) {
01065 check_context(x1, b); check_context(x2, b);
01066 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
01067 Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01068 }
01069 inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
01070 check_context(x1, b); check_context(x2, b); check_context(x3, b);
01071 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
01072 Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01073 }
01074 inline expr forall(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
01075 check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
01076 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
01077 Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01078 }
01079 inline expr forall(expr_vector const & xs, expr const & b) {
01080 array<Z3_app> vars(xs);
01081 Z3_ast r = Z3_mk_forall_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01082 }
01083 inline expr exists(expr const & x, expr const & b) {
01084 check_context(x, b);
01085 Z3_app vars[] = {(Z3_app) x};
01086 Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 1, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01087 }
01088 inline expr exists(expr const & x1, expr const & x2, expr const & b) {
01089 check_context(x1, b); check_context(x2, b);
01090 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
01091 Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 2, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01092 }
01093 inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
01094 check_context(x1, b); check_context(x2, b); check_context(x3, b);
01095 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
01096 Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 3, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01097 }
01098 inline expr exists(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
01099 check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
01100 Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
01101 Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, 4, vars, 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01102 }
01103 inline expr exists(expr_vector const & xs, expr const & b) {
01104 array<Z3_app> vars(xs);
01105 Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
01106 }
01107
01108
01109 inline expr distinct(expr_vector const& args) {
01110 assert(args.size() > 0);
01111 context& ctx = args[0].ctx();
01112 array<Z3_ast> _args(args);
01113 Z3_ast r = Z3_mk_distinct(ctx, _args.size(), _args.ptr());
01114 ctx.check_error();
01115 return expr(ctx, r);
01116 }
01117
01118 inline expr concat(expr const& a, expr const& b) {
01119 check_context(a, b);
01120 Z3_ast r = Z3_mk_concat(a.ctx(), a, b);
01121 a.ctx().check_error();
01122 return expr(a.ctx(), r);
01123 }
01124
01125 class func_entry : public object {
01126 Z3_func_entry m_entry;
01127 void init(Z3_func_entry e) {
01128 m_entry = e;
01129 Z3_func_entry_inc_ref(ctx(), m_entry);
01130 }
01131 public:
01132 func_entry(context & c, Z3_func_entry e):object(c) { init(e); }
01133 func_entry(func_entry const & s):object(s) { init(s.m_entry); }
01134 ~func_entry() { Z3_func_entry_dec_ref(ctx(), m_entry); }
01135 operator Z3_func_entry() const { return m_entry; }
01136 func_entry & operator=(func_entry const & s) {
01137 Z3_func_entry_inc_ref(s.ctx(), s.m_entry);
01138 Z3_func_entry_dec_ref(ctx(), m_entry);
01139 m_ctx = s.m_ctx;
01140 m_entry = s.m_entry;
01141 return *this;
01142 }
01143 expr value() const { Z3_ast r = Z3_func_entry_get_value(ctx(), m_entry); check_error(); return expr(ctx(), r); }
01144 unsigned num_args() const { unsigned r = Z3_func_entry_get_num_args(ctx(), m_entry); check_error(); return r; }
01145 expr arg(unsigned i) const { Z3_ast r = Z3_func_entry_get_arg(ctx(), m_entry, i); check_error(); return expr(ctx(), r); }
01146 };
01147
01148 class func_interp : public object {
01149 Z3_func_interp m_interp;
01150 void init(Z3_func_interp e) {
01151 m_interp = e;
01152 Z3_func_interp_inc_ref(ctx(), m_interp);
01153 }
01154 public:
01155 func_interp(context & c, Z3_func_interp e):object(c) { init(e); }
01156 func_interp(func_interp const & s):object(s) { init(s.m_interp); }
01157 ~func_interp() { Z3_func_interp_dec_ref(ctx(), m_interp); }
01158 operator Z3_func_interp() const { return m_interp; }
01159 func_interp & operator=(func_interp const & s) {
01160 Z3_func_interp_inc_ref(s.ctx(), s.m_interp);
01161 Z3_func_interp_dec_ref(ctx(), m_interp);
01162 m_ctx = s.m_ctx;
01163 m_interp = s.m_interp;
01164 return *this;
01165 }
01166 expr else_value() const { Z3_ast r = Z3_func_interp_get_else(ctx(), m_interp); check_error(); return expr(ctx(), r); }
01167 unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; }
01168 func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); }
01169 };
01170
01171 class model : public object {
01172 Z3_model m_model;
01173 void init(Z3_model m) {
01174 m_model = m;
01175 Z3_model_inc_ref(ctx(), m);
01176 }
01177 public:
01178 model(context & c, Z3_model m):object(c) { init(m); }
01179 model(model const & s):object(s) { init(s.m_model); }
01180 ~model() { Z3_model_dec_ref(ctx(), m_model); }
01181 operator Z3_model() const { return m_model; }
01182 model & operator=(model const & s) {
01183 Z3_model_inc_ref(s.ctx(), s.m_model);
01184 Z3_model_dec_ref(ctx(), m_model);
01185 m_ctx = s.m_ctx;
01186 m_model = s.m_model;
01187 return *this;
01188 }
01189
01190 expr eval(expr const & n, bool model_completion=false) const {
01191 check_context(*this, n);
01192 Z3_ast r = 0;
01193 Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
01194 check_error();
01195 if (status == Z3_FALSE)
01196 throw exception("failed to evaluate expression");
01197 return expr(ctx(), r);
01198 }
01199
01200 unsigned num_consts() const { return Z3_model_get_num_consts(ctx(), m_model); }
01201 unsigned num_funcs() const { return Z3_model_get_num_funcs(ctx(), m_model); }
01202 func_decl get_const_decl(unsigned i) const { Z3_func_decl r = Z3_model_get_const_decl(ctx(), m_model, i); check_error(); return func_decl(ctx(), r); }
01203 func_decl get_func_decl(unsigned i) const { Z3_func_decl r = Z3_model_get_func_decl(ctx(), m_model, i); check_error(); return func_decl(ctx(), r); }
01204 unsigned size() const { return num_consts() + num_funcs(); }
01205 func_decl operator[](int i) const {
01206 assert(0 <= i);
01207 return static_cast<unsigned>(i) < num_consts() ? get_const_decl(i) : get_func_decl(i - num_consts());
01208 }
01209
01210 expr get_const_interp(func_decl c) const {
01211 check_context(*this, c);
01212 Z3_ast r = Z3_model_get_const_interp(ctx(), m_model, c);
01213 check_error();
01214 return expr(ctx(), r);
01215 }
01216 func_interp get_func_interp(func_decl f) const {
01217 check_context(*this, f);
01218 Z3_func_interp r = Z3_model_get_func_interp(ctx(), m_model, f);
01219 check_error();
01220 return func_interp(ctx(), r);
01221 }
01222
01223 friend std::ostream & operator<<(std::ostream & out, model const & m) { out << Z3_model_to_string(m.ctx(), m); return out; }
01224 };
01225
01226 class stats : public object {
01227 Z3_stats m_stats;
01228 void init(Z3_stats e) {
01229 m_stats = e;
01230 Z3_stats_inc_ref(ctx(), m_stats);
01231 }
01232 public:
01233 stats(context & c):object(c), m_stats(0) {}
01234 stats(context & c, Z3_stats e):object(c) { init(e); }
01235 stats(stats const & s):object(s) { init(s.m_stats); }
01236 ~stats() { if (m_stats) Z3_stats_dec_ref(ctx(), m_stats); }
01237 operator Z3_stats() const { return m_stats; }
01238 stats & operator=(stats const & s) {
01239 Z3_stats_inc_ref(s.ctx(), s.m_stats);
01240 if (m_stats) Z3_stats_dec_ref(ctx(), m_stats);
01241 m_ctx = s.m_ctx;
01242 m_stats = s.m_stats;
01243 return *this;
01244 }
01245 unsigned size() const { return Z3_stats_size(ctx(), m_stats); }
01246 std::string key(unsigned i) const { Z3_string s = Z3_stats_get_key(ctx(), m_stats, i); check_error(); return s; }
01247 bool is_uint(unsigned i) const { Z3_bool r = Z3_stats_is_uint(ctx(), m_stats, i); check_error(); return r != 0; }
01248 bool is_double(unsigned i) const { Z3_bool r = Z3_stats_is_double(ctx(), m_stats, i); check_error(); return r != 0; }
01249 unsigned uint_value(unsigned i) const { unsigned r = Z3_stats_get_uint_value(ctx(), m_stats, i); check_error(); return r; }
01250 double double_value(unsigned i) const { double r = Z3_stats_get_double_value(ctx(), m_stats, i); check_error(); return r; }
01251 friend std::ostream & operator<<(std::ostream & out, stats const & s) { out << Z3_stats_to_string(s.ctx(), s); return out; }
01252 };
01253
01254 enum check_result {
01255 unsat, sat, unknown
01256 };
01257
01258 inline std::ostream & operator<<(std::ostream & out, check_result r) {
01259 if (r == unsat) out << "unsat";
01260 else if (r == sat) out << "sat";
01261 else out << "unknown";
01262 return out;
01263 }
01264
01265 inline check_result to_check_result(Z3_lbool l) {
01266 if (l == Z3_L_TRUE) return sat;
01267 else if (l == Z3_L_FALSE) return unsat;
01268 return unknown;
01269 }
01270
01271 class solver : public object {
01272 Z3_solver m_solver;
01273 void init(Z3_solver s) {
01274 m_solver = s;
01275 Z3_solver_inc_ref(ctx(), s);
01276 }
01277 public:
01278 solver(context & c):object(c) { init(Z3_mk_solver(c)); }
01279 solver(context & c, Z3_solver s):object(c) { init(s); }
01280 solver(context & c, char const * logic):object(c) { init(Z3_mk_solver_for_logic(c, c.str_symbol(logic))); }
01281 solver(solver const & s):object(s) { init(s.m_solver); }
01282 ~solver() { Z3_solver_dec_ref(ctx(), m_solver); }
01283 operator Z3_solver() const { return m_solver; }
01284 solver & operator=(solver const & s) {
01285 Z3_solver_inc_ref(s.ctx(), s.m_solver);
01286 Z3_solver_dec_ref(ctx(), m_solver);
01287 m_ctx = s.m_ctx;
01288 m_solver = s.m_solver;
01289 return *this;
01290 }
01291 void set(params const & p) { Z3_solver_set_params(ctx(), m_solver, p); check_error(); }
01292 void push() { Z3_solver_push(ctx(), m_solver); check_error(); }
01293 void pop(unsigned n = 1) { Z3_solver_pop(ctx(), m_solver, n); check_error(); }
01294 void reset() { Z3_solver_reset(ctx(), m_solver); check_error(); }
01295 void add(expr const & e) { assert(e.is_bool()); Z3_solver_assert(ctx(), m_solver, e); check_error(); }
01296 void add(expr const & e, expr const & p) {
01297 assert(e.is_bool()); assert(p.is_bool()); assert(p.is_const());
01298 Z3_solver_assert_and_track(ctx(), m_solver, e, p);
01299 check_error();
01300 }
01301 void add(expr const & e, char const * p) {
01302 add(e, ctx().bool_const(p));
01303 }
01304 check_result check() { Z3_lbool r = Z3_solver_check(ctx(), m_solver); check_error(); return to_check_result(r); }
01305 check_result check(unsigned n, expr * const assumptions) {
01306 array<Z3_ast> _assumptions(n);
01307 for (unsigned i = 0; i < n; i++) {
01308 check_context(*this, assumptions[i]);
01309 _assumptions[i] = assumptions[i];
01310 }
01311 Z3_lbool r = Z3_solver_check_assumptions(ctx(), m_solver, n, _assumptions.ptr());
01312 check_error();
01313 return to_check_result(r);
01314 }
01315 check_result check(expr_vector assumptions) {
01316 unsigned n = assumptions.size();
01317 array<Z3_ast> _assumptions(n);
01318 for (unsigned i = 0; i < n; i++) {
01319 check_context(*this, assumptions[i]);
01320 _assumptions[i] = assumptions[i];
01321 }
01322 Z3_lbool r = Z3_solver_check_assumptions(ctx(), m_solver, n, _assumptions.ptr());
01323 check_error();
01324 return to_check_result(r);
01325 }
01326 model get_model() const { Z3_model m = Z3_solver_get_model(ctx(), m_solver); check_error(); return model(ctx(), m); }
01327 std::string reason_unknown() const { Z3_string r = Z3_solver_get_reason_unknown(ctx(), m_solver); check_error(); return r; }
01328 stats statistics() const { Z3_stats r = Z3_solver_get_statistics(ctx(), m_solver); check_error(); return stats(ctx(), r); }
01329 expr_vector unsat_core() const { Z3_ast_vector r = Z3_solver_get_unsat_core(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
01330 expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
01331 expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); }
01332 friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; }
01333
01334 std::string to_smt2(char const* status = "unknown") {
01335 array<Z3_ast> es(assertions());
01336 Z3_ast const* fmls = es.ptr();
01337 Z3_ast fml = 0;
01338 unsigned sz = es.size();
01339 if (sz > 0) {
01340 --sz;
01341 fml = fmls[sz];
01342 }
01343 else {
01344 fml = ctx().bool_val(true);
01345 }
01346 return std::string(Z3_benchmark_to_smtlib_string(
01347 ctx(),
01348 "", "", status, "",
01349 sz,
01350 fmls,
01351 fml));
01352 }
01353 };
01354
01355 class goal : public object {
01356 Z3_goal m_goal;
01357 void init(Z3_goal s) {
01358 m_goal = s;
01359 Z3_goal_inc_ref(ctx(), s);
01360 }
01361 public:
01362 goal(context & c, bool models=true, bool unsat_cores=false, bool proofs=false):object(c) { init(Z3_mk_goal(c, models, unsat_cores, proofs)); }
01363 goal(context & c, Z3_goal s):object(c) { init(s); }
01364 goal(goal const & s):object(s) { init(s.m_goal); }
01365 ~goal() { Z3_goal_dec_ref(ctx(), m_goal); }
01366 operator Z3_goal() const { return m_goal; }
01367 goal & operator=(goal const & s) {
01368 Z3_goal_inc_ref(s.ctx(), s.m_goal);
01369 Z3_goal_dec_ref(ctx(), m_goal);
01370 m_ctx = s.m_ctx;
01371 m_goal = s.m_goal;
01372 return *this;
01373 }
01374 void add(expr const & f) { check_context(*this, f); Z3_goal_assert(ctx(), m_goal, f); check_error(); }
01375 unsigned size() const { return Z3_goal_size(ctx(), m_goal); }
01376 expr operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_goal_formula(ctx(), m_goal, i); check_error(); return expr(ctx(), r); }
01377 Z3_goal_prec precision() const { return Z3_goal_precision(ctx(), m_goal); }
01378 bool inconsistent() const { return Z3_goal_inconsistent(ctx(), m_goal) != 0; }
01379 unsigned depth() const { return Z3_goal_depth(ctx(), m_goal); }
01380 void reset() { Z3_goal_reset(ctx(), m_goal); }
01381 unsigned num_exprs() const { return Z3_goal_num_exprs(ctx(), m_goal); }
01382 bool is_decided_sat() const { return Z3_goal_is_decided_sat(ctx(), m_goal) != 0; }
01383 bool is_decided_unsat() const { return Z3_goal_is_decided_unsat(ctx(), m_goal) != 0; }
01384 expr as_expr() const {
01385 unsigned n = size();
01386 if (n == 0)
01387 return ctx().bool_val(true);
01388 else if (n == 1)
01389 return operator[](0);
01390 else {
01391 array<Z3_ast> args(n);
01392 for (unsigned i = 0; i < n; i++)
01393 args[i] = operator[](i);
01394 return expr(ctx(), Z3_mk_and(ctx(), n, args.ptr()));
01395 }
01396 }
01397 friend std::ostream & operator<<(std::ostream & out, goal const & g) { out << Z3_goal_to_string(g.ctx(), g); return out; }
01398 };
01399
01400 class apply_result : public object {
01401 Z3_apply_result m_apply_result;
01402 void init(Z3_apply_result s) {
01403 m_apply_result = s;
01404 Z3_apply_result_inc_ref(ctx(), s);
01405 }
01406 public:
01407 apply_result(context & c, Z3_apply_result s):object(c) { init(s); }
01408 apply_result(apply_result const & s):object(s) { init(s.m_apply_result); }
01409 ~apply_result() { Z3_apply_result_dec_ref(ctx(), m_apply_result); }
01410 operator Z3_apply_result() const { return m_apply_result; }
01411 apply_result & operator=(apply_result const & s) {
01412 Z3_apply_result_inc_ref(s.ctx(), s.m_apply_result);
01413 Z3_apply_result_dec_ref(ctx(), m_apply_result);
01414 m_ctx = s.m_ctx;
01415 m_apply_result = s.m_apply_result;
01416 return *this;
01417 }
01418 unsigned size() const { return Z3_apply_result_get_num_subgoals(ctx(), m_apply_result); }
01419 goal operator[](int i) const { assert(0 <= i); Z3_goal r = Z3_apply_result_get_subgoal(ctx(), m_apply_result, i); check_error(); return goal(ctx(), r); }
01420 model convert_model(model const & m, unsigned i = 0) const {
01421 check_context(*this, m);
01422 Z3_model new_m = Z3_apply_result_convert_model(ctx(), m_apply_result, i, m);
01423 check_error();
01424 return model(ctx(), new_m);
01425 }
01426 friend std::ostream & operator<<(std::ostream & out, apply_result const & r) { out << Z3_apply_result_to_string(r.ctx(), r); return out; }
01427 };
01428
01429 class tactic : public object {
01430 Z3_tactic m_tactic;
01431 void init(Z3_tactic s) {
01432 m_tactic = s;
01433 Z3_tactic_inc_ref(ctx(), s);
01434 }
01435 public:
01436 tactic(context & c, char const * name):object(c) { Z3_tactic r = Z3_mk_tactic(c, name); check_error(); init(r); }
01437 tactic(context & c, Z3_tactic s):object(c) { init(s); }
01438 tactic(tactic const & s):object(s) { init(s.m_tactic); }
01439 ~tactic() { Z3_tactic_dec_ref(ctx(), m_tactic); }
01440 operator Z3_tactic() const { return m_tactic; }
01441 tactic & operator=(tactic const & s) {
01442 Z3_tactic_inc_ref(s.ctx(), s.m_tactic);
01443 Z3_tactic_dec_ref(ctx(), m_tactic);
01444 m_ctx = s.m_ctx;
01445 m_tactic = s.m_tactic;
01446 return *this;
01447 }
01448 solver mk_solver() const { Z3_solver r = Z3_mk_solver_from_tactic(ctx(), m_tactic); check_error(); return solver(ctx(), r); }
01449 apply_result apply(goal const & g) const {
01450 check_context(*this, g);
01451 Z3_apply_result r = Z3_tactic_apply(ctx(), m_tactic, g);
01452 check_error();
01453 return apply_result(ctx(), r);
01454 }
01455 apply_result operator()(goal const & g) const {
01456 return apply(g);
01457 }
01458 std::string help() const { char const * r = Z3_tactic_get_help(ctx(), m_tactic); check_error(); return r; }
01459 friend tactic operator&(tactic const & t1, tactic const & t2) {
01460 check_context(t1, t2);
01461 Z3_tactic r = Z3_tactic_and_then(t1.ctx(), t1, t2);
01462 t1.check_error();
01463 return tactic(t1.ctx(), r);
01464 }
01465 friend tactic operator|(tactic const & t1, tactic const & t2) {
01466 check_context(t1, t2);
01467 Z3_tactic r = Z3_tactic_or_else(t1.ctx(), t1, t2);
01468 t1.check_error();
01469 return tactic(t1.ctx(), r);
01470 }
01471 friend tactic repeat(tactic const & t, unsigned max);
01472 friend tactic with(tactic const & t, params const & p);
01473 friend tactic try_for(tactic const & t, unsigned ms);
01474 };
01475
01476 inline tactic repeat(tactic const & t, unsigned max=UINT_MAX) {
01477 Z3_tactic r = Z3_tactic_repeat(t.ctx(), t, max);
01478 t.check_error();
01479 return tactic(t.ctx(), r);
01480 }
01481
01482 inline tactic with(tactic const & t, params const & p) {
01483 Z3_tactic r = Z3_tactic_using_params(t.ctx(), t, p);
01484 t.check_error();
01485 return tactic(t.ctx(), r);
01486 }
01487 inline tactic try_for(tactic const & t, unsigned ms) {
01488 Z3_tactic r = Z3_tactic_try_for(t.ctx(), t, ms);
01489 t.check_error();
01490 return tactic(t.ctx(), r);
01491 }
01492
01493
01494 class probe : public object {
01495 Z3_probe m_probe;
01496 void init(Z3_probe s) {
01497 m_probe = s;
01498 Z3_probe_inc_ref(ctx(), s);
01499 }
01500 public:
01501 probe(context & c, char const * name):object(c) { Z3_probe r = Z3_mk_probe(c, name); check_error(); init(r); }
01502 probe(context & c, double val):object(c) { Z3_probe r = Z3_probe_const(c, val); check_error(); init(r); }
01503 probe(context & c, Z3_probe s):object(c) { init(s); }
01504 probe(probe const & s):object(s) { init(s.m_probe); }
01505 ~probe() { Z3_probe_dec_ref(ctx(), m_probe); }
01506 operator Z3_probe() const { return m_probe; }
01507 probe & operator=(probe const & s) {
01508 Z3_probe_inc_ref(s.ctx(), s.m_probe);
01509 Z3_probe_dec_ref(ctx(), m_probe);
01510 m_ctx = s.m_ctx;
01511 m_probe = s.m_probe;
01512 return *this;
01513 }
01514 double apply(goal const & g) const { double r = Z3_probe_apply(ctx(), m_probe, g); check_error(); return r; }
01515 double operator()(goal const & g) const { return apply(g); }
01516 friend probe operator<=(probe const & p1, probe const & p2) {
01517 check_context(p1, p2); Z3_probe r = Z3_probe_le(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01518 }
01519 friend probe operator<=(probe const & p1, double p2) { return p1 <= probe(p1.ctx(), p2); }
01520 friend probe operator<=(double p1, probe const & p2) { return probe(p2.ctx(), p1) <= p2; }
01521 friend probe operator>=(probe const & p1, probe const & p2) {
01522 check_context(p1, p2); Z3_probe r = Z3_probe_ge(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01523 }
01524 friend probe operator>=(probe const & p1, double p2) { return p1 >= probe(p1.ctx(), p2); }
01525 friend probe operator>=(double p1, probe const & p2) { return probe(p2.ctx(), p1) >= p2; }
01526 friend probe operator<(probe const & p1, probe const & p2) {
01527 check_context(p1, p2); Z3_probe r = Z3_probe_lt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01528 }
01529 friend probe operator<(probe const & p1, double p2) { return p1 < probe(p1.ctx(), p2); }
01530 friend probe operator<(double p1, probe const & p2) { return probe(p2.ctx(), p1) < p2; }
01531 friend probe operator>(probe const & p1, probe const & p2) {
01532 check_context(p1, p2); Z3_probe r = Z3_probe_gt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01533 }
01534 friend probe operator>(probe const & p1, double p2) { return p1 > probe(p1.ctx(), p2); }
01535 friend probe operator>(double p1, probe const & p2) { return probe(p2.ctx(), p1) > p2; }
01536 friend probe operator==(probe const & p1, probe const & p2) {
01537 check_context(p1, p2); Z3_probe r = Z3_probe_eq(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01538 }
01539 friend probe operator==(probe const & p1, double p2) { return p1 == probe(p1.ctx(), p2); }
01540 friend probe operator==(double p1, probe const & p2) { return probe(p2.ctx(), p1) == p2; }
01541 friend probe operator&&(probe const & p1, probe const & p2) {
01542 check_context(p1, p2); Z3_probe r = Z3_probe_and(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01543 }
01544 friend probe operator||(probe const & p1, probe const & p2) {
01545 check_context(p1, p2); Z3_probe r = Z3_probe_or(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r);
01546 }
01547 friend probe operator!(probe const & p) {
01548 Z3_probe r = Z3_probe_not(p.ctx(), p); p.check_error(); return probe(p.ctx(), r);
01549 }
01550 };
01551
01552 class optimize : public object {
01553 Z3_optimize m_opt;
01554 public:
01555 class handle {
01556 unsigned m_h;
01557 public:
01558 handle(unsigned h): m_h(h) {}
01559 unsigned h() const { return m_h; }
01560 };
01561 optimize(context& c):object(c) { m_opt = Z3_mk_optimize(c); Z3_optimize_inc_ref(c, m_opt); }
01562 ~optimize() { Z3_optimize_dec_ref(ctx(), m_opt); }
01563 operator Z3_optimize() const { return m_opt; }
01564 void add(expr const& e) {
01565 assert(e.is_bool());
01566 Z3_optimize_assert(ctx(), m_opt, e);
01567 }
01568 handle add(expr const& e, unsigned weight) {
01569 assert(e.is_bool());
01570 std::stringstream strm;
01571 strm << weight;
01572 return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, strm.str().c_str(), 0));
01573 }
01574 handle add(expr const& e, char const* weight) {
01575 assert(e.is_bool());
01576 return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, weight, 0));
01577 }
01578 handle maximize(expr const& e) {
01579 return handle(Z3_optimize_maximize(ctx(), m_opt, e));
01580 }
01581 handle minimize(expr const& e) {
01582 return handle(Z3_optimize_minimize(ctx(), m_opt, e));
01583 }
01584 void push() {
01585 Z3_optimize_push(ctx(), m_opt);
01586 }
01587 void pop() {
01588 Z3_optimize_pop(ctx(), m_opt);
01589 }
01590 check_result check() { Z3_lbool r = Z3_optimize_check(ctx(), m_opt); check_error(); return to_check_result(r); }
01591 model get_model() const { Z3_model m = Z3_optimize_get_model(ctx(), m_opt); check_error(); return model(ctx(), m); }
01592 void set(params const & p) { Z3_optimize_set_params(ctx(), m_opt, p); check_error(); }
01593 expr lower(handle const& h) {
01594 Z3_ast r = Z3_optimize_get_lower(ctx(), m_opt, h.h());
01595 check_error();
01596 return expr(ctx(), r);
01597 }
01598 expr upper(handle const& h) {
01599 Z3_ast r = Z3_optimize_get_upper(ctx(), m_opt, h.h());
01600 check_error();
01601 return expr(ctx(), r);
01602 }
01603 stats statistics() const { Z3_stats r = Z3_optimize_get_statistics(ctx(), m_opt); check_error(); return stats(ctx(), r); }
01604 friend std::ostream & operator<<(std::ostream & out, optimize const & s) { out << Z3_optimize_to_string(s.ctx(), s.m_opt); return out; }
01605 std::string help() const { char const * r = Z3_optimize_get_help(ctx(), m_opt); check_error(); return r; }
01606 };
01607
01608 inline tactic fail_if(probe const & p) {
01609 Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
01610 p.check_error();
01611 return tactic(p.ctx(), r);
01612 }
01613 inline tactic when(probe const & p, tactic const & t) {
01614 check_context(p, t);
01615 Z3_tactic r = Z3_tactic_when(t.ctx(), p, t);
01616 t.check_error();
01617 return tactic(t.ctx(), r);
01618 }
01619 inline tactic cond(probe const & p, tactic const & t1, tactic const & t2) {
01620 check_context(p, t1); check_context(p, t2);
01621 Z3_tactic r = Z3_tactic_cond(t1.ctx(), p, t1, t2);
01622 t1.check_error();
01623 return tactic(t1.ctx(), r);
01624 }
01625
01626 inline symbol context::str_symbol(char const * s) { Z3_symbol r = Z3_mk_string_symbol(m_ctx, s); check_error(); return symbol(*this, r); }
01627 inline symbol context::int_symbol(int n) { Z3_symbol r = Z3_mk_int_symbol(m_ctx, n); check_error(); return symbol(*this, r); }
01628
01629 inline sort context::bool_sort() { Z3_sort s = Z3_mk_bool_sort(m_ctx); check_error(); return sort(*this, s); }
01630 inline sort context::int_sort() { Z3_sort s = Z3_mk_int_sort(m_ctx); check_error(); return sort(*this, s); }
01631 inline sort context::real_sort() { Z3_sort s = Z3_mk_real_sort(m_ctx); check_error(); return sort(*this, s); }
01632 inline sort context::bv_sort(unsigned sz) { Z3_sort s = Z3_mk_bv_sort(m_ctx, sz); check_error(); return sort(*this, s); }
01633 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); }
01634 inline sort context::enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts) {
01635 array<Z3_symbol> _enum_names(n);
01636 for (unsigned i = 0; i < n; i++) { _enum_names[i] = Z3_mk_string_symbol(*this, enum_names[i]); }
01637 array<Z3_func_decl> _cs(n);
01638 array<Z3_func_decl> _ts(n);
01639 Z3_symbol _name = Z3_mk_string_symbol(*this, name);
01640 sort s = to_sort(*this, Z3_mk_enumeration_sort(*this, _name, n, _enum_names.ptr(), _cs.ptr(), _ts.ptr()));
01641 check_error();
01642 for (unsigned i = 0; i < n; i++) { cs.push_back(func_decl(*this, _cs[i])); ts.push_back(func_decl(*this, _ts[i])); }
01643 return s;
01644 }
01645 inline sort context::uninterpreted_sort(char const* name) {
01646 Z3_symbol _name = Z3_mk_string_symbol(*this, name);
01647 return to_sort(*this, Z3_mk_uninterpreted_sort(*this, _name));
01648 }
01649 inline sort context::uninterpreted_sort(symbol const& name) {
01650 return to_sort(*this, Z3_mk_uninterpreted_sort(*this, name));
01651 }
01652
01653 inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
01654 array<Z3_sort> args(arity);
01655 for (unsigned i = 0; i < arity; i++) {
01656 check_context(domain[i], range);
01657 args[i] = domain[i];
01658 }
01659 Z3_func_decl f = Z3_mk_func_decl(m_ctx, name, arity, args.ptr(), range);
01660 check_error();
01661 return func_decl(*this, f);
01662 }
01663
01664 inline func_decl context::function(char const * name, unsigned arity, sort const * domain, sort const & range) {
01665 return function(range.ctx().str_symbol(name), arity, domain, range);
01666 }
01667
01668 inline func_decl context::function(symbol const& name, sort_vector const& domain, sort const& range) {
01669 array<Z3_sort> args(domain.size());
01670 for (unsigned i = 0; i < domain.size(); i++) {
01671 check_context(domain[i], range);
01672 args[i] = domain[i];
01673 }
01674 Z3_func_decl f = Z3_mk_func_decl(m_ctx, name, domain.size(), args.ptr(), range);
01675 check_error();
01676 return func_decl(*this, f);
01677 }
01678
01679 inline func_decl context::function(char const * name, sort_vector const& domain, sort const& range) {
01680 return function(range.ctx().str_symbol(name), domain, range);
01681 }
01682
01683
01684 inline func_decl context::function(char const * name, sort const & domain, sort const & range) {
01685 check_context(domain, range);
01686 Z3_sort args[1] = { domain };
01687 Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 1, args, range);
01688 check_error();
01689 return func_decl(*this, f);
01690 }
01691
01692 inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & range) {
01693 check_context(d1, range); check_context(d2, range);
01694 Z3_sort args[2] = { d1, d2 };
01695 Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 2, args, range);
01696 check_error();
01697 return func_decl(*this, f);
01698 }
01699
01700 inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range) {
01701 check_context(d1, range); check_context(d2, range); check_context(d3, range);
01702 Z3_sort args[3] = { d1, d2, d3 };
01703 Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 3, args, range);
01704 check_error();
01705 return func_decl(*this, f);
01706 }
01707
01708 inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range) {
01709 check_context(d1, range); check_context(d2, range); check_context(d3, range); check_context(d4, range);
01710 Z3_sort args[4] = { d1, d2, d3, d4 };
01711 Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 4, args, range);
01712 check_error();
01713 return func_decl(*this, f);
01714 }
01715
01716 inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range) {
01717 check_context(d1, range); check_context(d2, range); check_context(d3, range); check_context(d4, range); check_context(d5, range);
01718 Z3_sort args[5] = { d1, d2, d3, d4, d5 };
01719 Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 5, args, range);
01720 check_error();
01721 return func_decl(*this, f);
01722 }
01723
01724 inline expr context::constant(symbol const & name, sort const & s) {
01725 Z3_ast r = Z3_mk_const(m_ctx, name, s);
01726 check_error();
01727 return expr(*this, r);
01728 }
01729 inline expr context::constant(char const * name, sort const & s) { return constant(str_symbol(name), s); }
01730 inline expr context::bool_const(char const * name) { return constant(name, bool_sort()); }
01731 inline expr context::int_const(char const * name) { return constant(name, int_sort()); }
01732 inline expr context::real_const(char const * name) { return constant(name, real_sort()); }
01733 inline expr context::bv_const(char const * name, unsigned sz) { return constant(name, bv_sort(sz)); }
01734
01735 inline expr context::bool_val(bool b) { return b ? expr(*this, Z3_mk_true(m_ctx)) : expr(*this, Z3_mk_false(m_ctx)); }
01736
01737 inline expr context::int_val(int n) { Z3_ast r = Z3_mk_int(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
01738 inline expr context::int_val(unsigned n) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
01739 inline expr context::int_val(__int64 n) { Z3_ast r = Z3_mk_int64(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
01740 inline expr context::int_val(__uint64 n) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
01741 inline expr context::int_val(char const * n) { Z3_ast r = Z3_mk_numeral(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
01742
01743 inline expr context::real_val(int n, int d) { Z3_ast r = Z3_mk_real(m_ctx, n, d); check_error(); return expr(*this, r); }
01744 inline expr context::real_val(int n) { Z3_ast r = Z3_mk_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
01745 inline expr context::real_val(unsigned n) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
01746 inline expr context::real_val(__int64 n) { Z3_ast r = Z3_mk_int64(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
01747 inline expr context::real_val(__uint64 n) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
01748 inline expr context::real_val(char const * n) { Z3_ast r = Z3_mk_numeral(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
01749
01750 inline expr context::bv_val(int n, unsigned sz) { Z3_ast r = Z3_mk_int(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
01751 inline expr context::bv_val(unsigned n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
01752 inline expr context::bv_val(__int64 n, unsigned sz) { Z3_ast r = Z3_mk_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
01753 inline expr context::bv_val(__uint64 n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
01754 inline expr context::bv_val(char const * n, unsigned sz) { Z3_ast r = Z3_mk_numeral(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
01755
01756 inline expr context::num_val(int n, sort const & s) { Z3_ast r = Z3_mk_int(m_ctx, n, s); check_error(); return expr(*this, r); }
01757
01758 inline expr func_decl::operator()(unsigned n, expr const * args) const {
01759 array<Z3_ast> _args(n);
01760 for (unsigned i = 0; i < n; i++) {
01761 check_context(*this, args[i]);
01762 _args[i] = args[i];
01763 }
01764 Z3_ast r = Z3_mk_app(ctx(), *this, n, _args.ptr());
01765 check_error();
01766 return expr(ctx(), r);
01767
01768 }
01769 inline expr func_decl::operator()(expr_vector const& args) const {
01770 array<Z3_ast> _args(args.size());
01771 for (unsigned i = 0; i < args.size(); i++) {
01772 check_context(*this, args[i]);
01773 _args[i] = args[i];
01774 }
01775 Z3_ast r = Z3_mk_app(ctx(), *this, args.size(), _args.ptr());
01776 check_error();
01777 return expr(ctx(), r);
01778 }
01779 inline expr func_decl::operator()() const {
01780 Z3_ast r = Z3_mk_app(ctx(), *this, 0, 0);
01781 ctx().check_error();
01782 return expr(ctx(), r);
01783 }
01784 inline expr func_decl::operator()(expr const & a) const {
01785 check_context(*this, a);
01786 Z3_ast args[1] = { a };
01787 Z3_ast r = Z3_mk_app(ctx(), *this, 1, args);
01788 ctx().check_error();
01789 return expr(ctx(), r);
01790 }
01791 inline expr func_decl::operator()(int a) const {
01792 Z3_ast args[1] = { ctx().num_val(a, domain(0)) };
01793 Z3_ast r = Z3_mk_app(ctx(), *this, 1, args);
01794 ctx().check_error();
01795 return expr(ctx(), r);
01796 }
01797 inline expr func_decl::operator()(expr const & a1, expr const & a2) const {
01798 check_context(*this, a1); check_context(*this, a2);
01799 Z3_ast args[2] = { a1, a2 };
01800 Z3_ast r = Z3_mk_app(ctx(), *this, 2, args);
01801 ctx().check_error();
01802 return expr(ctx(), r);
01803 }
01804 inline expr func_decl::operator()(expr const & a1, int a2) const {
01805 check_context(*this, a1);
01806 Z3_ast args[2] = { a1, ctx().num_val(a2, domain(1)) };
01807 Z3_ast r = Z3_mk_app(ctx(), *this, 2, args);
01808 ctx().check_error();
01809 return expr(ctx(), r);
01810 }
01811 inline expr func_decl::operator()(int a1, expr const & a2) const {
01812 check_context(*this, a2);
01813 Z3_ast args[2] = { ctx().num_val(a1, domain(0)), a2 };
01814 Z3_ast r = Z3_mk_app(ctx(), *this, 2, args);
01815 ctx().check_error();
01816 return expr(ctx(), r);
01817 }
01818 inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3) const {
01819 check_context(*this, a1); check_context(*this, a2); check_context(*this, a3);
01820 Z3_ast args[3] = { a1, a2, a3 };
01821 Z3_ast r = Z3_mk_app(ctx(), *this, 3, args);
01822 ctx().check_error();
01823 return expr(ctx(), r);
01824 }
01825 inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const {
01826 check_context(*this, a1); check_context(*this, a2); check_context(*this, a3); check_context(*this, a4);
01827 Z3_ast args[4] = { a1, a2, a3, a4 };
01828 Z3_ast r = Z3_mk_app(ctx(), *this, 4, args);
01829 ctx().check_error();
01830 return expr(ctx(), r);
01831 }
01832 inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const {
01833 check_context(*this, a1); check_context(*this, a2); check_context(*this, a3); check_context(*this, a4); check_context(*this, a5);
01834 Z3_ast args[5] = { a1, a2, a3, a4, a5 };
01835 Z3_ast r = Z3_mk_app(ctx(), *this, 5, args);
01836 ctx().check_error();
01837 return expr(ctx(), r);
01838 }
01839
01840 inline expr to_real(expr const & a) { Z3_ast r = Z3_mk_int2real(a.ctx(), a); a.check_error(); return expr(a.ctx(), r); }
01841
01842 inline func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
01843 return range.ctx().function(name, arity, domain, range);
01844 }
01845 inline func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range) {
01846 return range.ctx().function(name, arity, domain, range);
01847 }
01848 inline func_decl function(char const * name, sort const & domain, sort const & range) {
01849 return range.ctx().function(name, domain, range);
01850 }
01851 inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & range) {
01852 return range.ctx().function(name, d1, d2, range);
01853 }
01854 inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range) {
01855 return range.ctx().function(name, d1, d2, d3, range);
01856 }
01857 inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range) {
01858 return range.ctx().function(name, d1, d2, d3, d4, range);
01859 }
01860 inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range) {
01861 return range.ctx().function(name, d1, d2, d3, d4, d5, range);
01862 }
01863
01864 inline expr select(expr const & a, expr const & i) {
01865 check_context(a, i);
01866 Z3_ast r = Z3_mk_select(a.ctx(), a, i);
01867 a.check_error();
01868 return expr(a.ctx(), r);
01869 }
01870 inline expr select(expr const & a, int i) { return select(a, a.ctx().num_val(i, a.get_sort().array_domain())); }
01871 inline expr store(expr const & a, expr const & i, expr const & v) {
01872 check_context(a, i); check_context(a, v);
01873 Z3_ast r = Z3_mk_store(a.ctx(), a, i, v);
01874 a.check_error();
01875 return expr(a.ctx(), r);
01876 }
01877 inline expr store(expr const & a, int i, expr const & v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), v); }
01878 inline expr store(expr const & a, expr i, int v) { return store(a, i, a.ctx().num_val(v, a.get_sort().array_range())); }
01879 inline expr store(expr const & a, int i, int v) {
01880 return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), a.ctx().num_val(v, a.get_sort().array_range()));
01881 }
01882 inline expr const_array(sort const & d, expr const & v) {
01883 check_context(d, v);
01884 Z3_ast r = Z3_mk_const_array(d.ctx(), d, v);
01885 d.check_error();
01886 return expr(d.ctx(), r);
01887 }
01888
01889 inline expr expr::substitute(expr_vector const& src, expr_vector const& dst) {
01890 assert(src.size() == dst.size());
01891 array<Z3_ast> _src(src.size());
01892 array<Z3_ast> _dst(dst.size());
01893 for (unsigned i = 0; i < src.size(); ++i) {
01894 _src[i] = src[i];
01895 _dst[i] = dst[i];
01896 }
01897 Z3_ast r = Z3_substitute(ctx(), m_ast, src.size(), _src.ptr(), _dst.ptr());
01898 check_error();
01899 return expr(ctx(), r);
01900 }
01901
01902 inline expr expr::substitute(expr_vector const& dst) {
01903 array<Z3_ast> _dst(dst.size());
01904 for (unsigned i = 0; i < dst.size(); ++i) {
01905 _dst[i] = dst[i];
01906 }
01907 Z3_ast r = Z3_substitute_vars(ctx(), m_ast, dst.size(), _dst.ptr());
01908 check_error();
01909 return expr(ctx(), r);
01910 }
01911
01912
01913
01914 };
01915
01918
01919 #endif
01920