Z3
src/api/c++/z3++.h
Go to the documentation of this file.
00001 /*++
00002 Copyright (c) 2012 Microsoft Corporation
00003 
00004     Thin C++ layer on top of the Z3 C API.
00005     Main features:
00006       - Smart pointers for all Z3 objects.
00007       - Object-Oriented interface.
00008       - Operator overloading.
00009       - Exceptions for signining Z3 errors
00010 
00011     The C API can be used simultaneously with the C++ layer.
00012     However, if you use the C API directly, you will have to check the error conditions manually.
00013     Of course, you can invoke the method check_error() of the context object.
00014 Author:
00015 
00016     Leonardo (leonardo) 2012-03-28
00017 
00018 Notes:
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) { /* do nothing */ }
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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                 // operator is not supported by given arguments.
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     // Basic functions for creating quantified formulas.
01058     // The C API should be used for creating quantifiers with patterns, weights, many variables, etc.
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines