Home Docs Download Mail FAQ Awards Status MSR

Z3 An Efficient SMT Solver

C API examples


Auxiliary Functions

void exitf (const char *message)
 exit gracefully in case of error.
void unreachable ()
 exit if unreachable code was reached.
void error_handler (Z3_error_code e)
 Simpler error handler.
void throw_z3_error (Z3_error_code c)
 Low tech exceptions.
Z3_context mk_context_custom (Z3_config cfg, Z3_error_handler err)
 Create a logical context.
Z3_context mk_context ()
 Create a logical context.
Z3_ast mk_var (Z3_context ctx, const char *name, Z3_type_ast ty)
 Create a variable using the given name and type.
Z3_ast mk_bool_var (Z3_context ctx, const char *name)
 Create a boolean variable using the given name.
Z3_ast mk_int_var (Z3_context ctx, const char *name)
 Create an integer variable using the given name.
Z3_ast mk_int (Z3_context ctx, int v)
 Create a Z3 integer node using a C int.
Z3_ast mk_real_var (Z3_context ctx, const char *name)
 Create a real variable using the given name.
Z3_ast mk_unary_app (Z3_context ctx, Z3_const_decl_ast f, Z3_ast x)
 Create the unary function application: (f x).
Z3_ast mk_binary_app (Z3_context ctx, Z3_const_decl_ast f, Z3_ast x, Z3_ast y)
 Create the binary function application: (f x y).
void check (Z3_context ctx, Z3_lbool expected_result)
 Check whether the logical context is satisfiable, and compare the result with the expected result. If the context is satisfiable, then display the model.
void prove (Z3_context ctx, Z3_ast f, Z3_bool is_valid)
 Prove that the constraints already asserted into the logical context implies the given formula. The result of the proof is displayed.
void assert_inj_axiom (Z3_context ctx, Z3_const_decl_ast f, unsigned i)
 Assert the axiom: function f is injective in the i-th argument.
void assert_comm_axiom (Z3_context ctx, Z3_const_decl_ast f)
 Assert the axiom: function f is commutative.
Z3_ast mk_tuple_update (Z3_context c, Z3_ast t, unsigned i, Z3_ast new_val)
 Z3 does not support explicitly tuple updates. They can be easily implemented as macros. The argument t must have tuple type. A tuple update is a new tuple where field i has value new_val, and all other fields have the value of the respective field of t.
void display_symbol (Z3_context c, FILE *out, Z3_symbol s)
 Display a symbol in the given output stream.
void display_type (Z3_context c, FILE *out, Z3_type_ast ty)
 Display the given type.
void display_value (Z3_context c, FILE *out, Z3_value v)
 Custom value pretty printer.
void display_function_interpretations (Z3_context c, FILE *out, Z3_model m)
 Custom function interpretations pretty printer.
void display_model (Z3_context c, FILE *out, Z3_model m)
 Custom model pretty printer.
void check2 (Z3_context ctx, Z3_lbool expected_result)
 Similar to check, but uses display_model instead of Z3_model_to_string.
void display_version ()
 Display Z3 version in the standard output.

Examples

void simple_example ()
 "Hello world" example: create a Z3 logical context, and delete it.
void demorgan ()
void find_model_example1 ()
 Find a model for x xor y.
void find_model_example2 ()
 Find a model for x < y + 1, x > 2. Then, assert not(x = y), and find another model.
void prove_example1 ()
 Prove x = y implies g(x) = g(y), and disprove x = y implies g(g(x)) = g(y).
void prove_example2 ()
 Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . Then, show that z < -1 is not implied.
void push_pop_example1 ()
 Show how push & pop can be used to create "backtracking" points.
void quantifier_example1 ()
 Prove that f(x, y) = f(w, v) implies y = v when f is injective in the second argument.
void array_example1 ()
 Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)).
void array_example2 ()
 Show that distinct(a_0, ... , a_n) is unsatisfiable when a_i's are arrays from boolean to boolean and n > 4.
void array_example3 ()
 Simple array type construction/deconstruction example.
void tuple_example1 ()
 Simple tuple type example. It creates a tuple that is a pair of real numbers.
void bitvector_example1 ()
 Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers.
void bitvector_example2 ()
 Find x and y such that: x ^ y - 103 == x * y.
void eval_example1 ()
 Demonstrate how to use Z3_eval.
void two_contexts_example1 ()
 Several logical context can be used simultaneously.
void error_code_example1 ()
 Demonstrates how error codes can be read insted of registering an error handler.
void error_code_example2 ()
 Demonstrates how error handlers can be used.
void parser_example1 ()
 Demonstrates how to use the SMTLIB parser.
void parser_example2 ()
 Demonstrates how to initialize the parser symbol table.
void parser_example3 ()
 Demonstrates how to initialize the parser symbol table.
void parser_example4 ()
 Display the declarations, assumptions and formulas in a SMT-LIB string.
void parser_example5 ()
 Demonstrates how to handle parser errors using Z3 error handling support.
void ite_example ()
 Test ite-term (if-then-else terms).
void simplifier_example ()
 Simplifier example.
void print_term (Z3_context ctx, struct bound_list *bound_vars, Z3_ast t)
void traverse_term_example ()

Function Documentation

void array_example1 (  ) 

Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)).

This example demonstrates how to use the array theory.

Definition at line 1068 of file test_capi.c.

01069 {
01070     Z3_context ctx;
01071     Z3_type_ast int_type, array_type;
01072     Z3_ast a1, a2, i1, v1, i2, v2, i3;
01073     Z3_ast st1, st2, sel1, sel2;
01074     Z3_ast antecedent, consequent;
01075     Z3_ast ds[3];
01076     Z3_ast thm;
01077 
01078     printf("\narray_example1\n");
01079 
01080     ctx = mk_context();
01081 
01082     int_type    = Z3_mk_int_type(ctx);
01083     array_type  = Z3_mk_array_type(ctx, int_type, int_type);
01084 
01085     a1          = mk_var(ctx, "a1", array_type);
01086     a2          = mk_var(ctx, "a2", array_type);
01087     i1          = mk_var(ctx, "i1", int_type);
01088     i2          = mk_var(ctx, "i2", int_type);
01089     i3          = mk_var(ctx, "i3", int_type);
01090     v1          = mk_var(ctx, "v1", int_type);
01091     v2          = mk_var(ctx, "v2", int_type);
01092     
01093     st1         = Z3_mk_store(ctx, a1, i1, v1);
01094     st2         = Z3_mk_store(ctx, a2, i2, v2);
01095     
01096     sel1        = Z3_mk_select(ctx, a1, i3);
01097     sel2        = Z3_mk_select(ctx, a2, i3);
01098 
01099     /* create antecedent */
01100     antecedent  = Z3_mk_eq(ctx, st1, st2);
01101 
01102     /* create consequent: i1 = i3 or  i2 = i3 or select(a1, i3) = select(a2, i3) */
01103     ds[0]       = Z3_mk_eq(ctx, i1, i3);
01104     ds[1]       = Z3_mk_eq(ctx, i2, i3);
01105     ds[2]       = Z3_mk_eq(ctx, sel1, sel2);
01106     consequent  = Z3_mk_or(ctx, 3, ds);
01107 
01108     /* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) */
01109     thm         = Z3_mk_implies(ctx, antecedent, consequent);
01110     printf("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))\n");
01111     printf("%s\n", Z3_ast_to_string(ctx, thm));
01112     prove(ctx, thm, Z3_TRUE);
01113 
01114     Z3_del_context(ctx);
01115 }

void array_example2 (  ) 

Show that distinct(a_0, ... , a_n) is unsatisfiable when a_i's are arrays from boolean to boolean and n > 4.

This example also shows how to use the distinct construct.

Definition at line 1124 of file test_capi.c.

01125 {
01126     Z3_context ctx;
01127     Z3_type_ast bool_type, array_type;
01128     Z3_ast      a[5];
01129     Z3_ast      d;
01130     unsigned      i, n;
01131 
01132     printf("\narray_example2\n");
01133 
01134     for (n = 2; n <= 5; n++) {
01135         printf("n = %d\n", n);
01136         ctx = mk_context();
01137         
01138         bool_type   = Z3_mk_bool_type(ctx);
01139         array_type  = Z3_mk_array_type(ctx, bool_type, bool_type);
01140         
01141         /* create arrays */
01142         for (i = 0; i < n; i++) {
01143             Z3_symbol s = Z3_mk_int_symbol(ctx, i);
01144             a[i]          = Z3_mk_const(ctx, s, array_type);
01145         }
01146         
01147         /* assert distinct(a[0], ..., a[n]) */
01148         d = Z3_mk_distinct(ctx, n, a);
01149         printf("%s\n", Z3_ast_to_string(ctx, d));
01150         Z3_assert_cnstr(ctx, d);
01151 
01152         /* context is satisfiable if n < 5 */
01153         check2(ctx, n < 5 ? Z3_L_TRUE : Z3_L_FALSE);
01154         
01155         Z3_del_context(ctx);
01156     }
01157 }

void array_example3 (  ) 

Simple array type construction/deconstruction example.

Definition at line 1162 of file test_capi.c.

01163 {
01164     Z3_context ctx;
01165     Z3_type_ast bool_type, int_type, array_type;
01166     Z3_type_ast domain, range;
01167     printf("\narray_example3\n");
01168 
01169     ctx      = mk_context();
01170 
01171     bool_type  = Z3_mk_bool_type(ctx);
01172     int_type   = Z3_mk_int_type(ctx); 
01173     array_type = Z3_mk_array_type(ctx, int_type, bool_type);
01174 
01175     if (Z3_get_type_kind(ctx, array_type) != Z3_ARRAY_TYPE) {
01176         exitf("type must be an array type");
01177     }
01178     
01179     domain = Z3_get_array_type_domain(ctx, array_type);
01180     range  = Z3_get_array_type_range(ctx, array_type);
01181 
01182     printf("domain: ");
01183     display_type(ctx, stdout, domain);
01184     printf("\n");
01185     printf("range:  ");
01186     display_type(ctx, stdout, range);
01187     printf("\n");
01188 
01189     if (!Z3_is_eq(ctx, Z3_type_ast_to_ast(ctx, int_type),  Z3_type_ast_to_ast(ctx, domain)) ||
01190         !Z3_is_eq(ctx, Z3_type_ast_to_ast(ctx, bool_type), Z3_type_ast_to_ast(ctx, range))) {
01191         exitf("invalid array type");
01192     }
01193 
01194     Z3_del_context(ctx);
01195 }

void assert_comm_axiom ( Z3_context  ctx,
Z3_const_decl_ast  f 
)

Assert the axiom: function f is commutative.

This example uses the SMT-LIB parser to simplify the axiom construction.

Definition at line 326 of file test_capi.c.

Referenced by parser_example3().

00327 {
00328     Z3_type_ast t;
00329     Z3_symbol f_name, t_name;
00330     Z3_ast q;
00331 
00332     t = Z3_get_range(ctx, f);
00333 
00334     if (Z3_get_domain_size(ctx, f) != 2 ||
00335         Z3_get_domain(ctx, f, 0) != t ||
00336         Z3_get_domain(ctx, f, 1) != t) {
00337         exitf("function must be binary, and argument types must be equal to return type");
00338     } 
00339     
00340     /* Inside the parser, function f will be referenced using the symbol 'f'. */
00341     f_name = Z3_mk_string_symbol(ctx, "f");
00342     
00343     /* Inside the parser, type t will be referenced using the symbol 'T'. */
00344     t_name = Z3_mk_string_symbol(ctx, "T");
00345 
00346     Z3_parse_smtlib_string(ctx, 
00347                            "(benchmark comm :formula (forall (x T) (y T) (= (f x y) (f y x))))",
00348                            1, &t_name, &t,
00349                            1, &f_name, &f);
00350     q = Z3_get_smtlib_formula(ctx, 0);
00351     printf("assert axiom:\n%s\n", Z3_ast_to_string(ctx, q));
00352     Z3_assert_cnstr(ctx, q);
00353 }

void assert_inj_axiom ( Z3_context  ctx,
Z3_const_decl_ast  f,
unsigned  i 
)

Assert the axiom: function f is injective in the i-th argument.

The following axiom is asserted into the logical context:

   forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i

Where, finv is a fresh function declaration.

Definition at line 255 of file test_capi.c.

Referenced by quantifier_example1().

00256 {
00257     unsigned sz, j;
00258     Z3_type_ast finv_domain, finv_range;
00259     Z3_const_decl_ast finv;
00260     Z3_type_ast * types; /* types of the quantified variables */
00261     Z3_symbol *   names; /* names of the quantified variables */
00262     Z3_ast * xs;         /* arguments for the application f(x_0, ..., x_i, ..., x_{n-1}) */
00263     Z3_ast   x_i, fxs, finv_fxs, eq;
00264     Z3_pattern_ast p;
00265     Z3_ast   q;
00266     sz = Z3_get_domain_size(ctx, f);
00267 
00268     if (i >= sz) {
00269         exitf("failed to create inj axiom");
00270     }
00271     
00272     /* declare the i-th inverse of f: finv */
00273     finv_domain = Z3_get_range(ctx, f);
00274     finv_range  = Z3_get_domain(ctx, f, i);
00275     finv        = Z3_mk_fresh_func_decl(ctx, "inv", 1, &finv_domain, finv_range);
00276 
00277     /* allocate temporary arrays */
00278     types       = (Z3_type_ast *) malloc(sizeof(Z3_type_ast) * sz);
00279     names       = (Z3_symbol *) malloc(sizeof(Z3_symbol) * sz);
00280     xs          = (Z3_ast *) malloc(sizeof(Z3_ast) * sz);
00281     
00282     /* fill types, names and xs */
00283     for (j = 0; j < sz; j++) { types[j] = Z3_get_domain(ctx, f, j); };
00284     for (j = 0; j < sz; j++) { names[j] = Z3_mk_int_symbol(ctx, j); };
00285     for (j = 0; j < sz; j++) { xs[j]    = Z3_mk_bound(ctx, j, types[j]); };
00286 
00287     x_i = xs[i];
00288 
00289     /* create f(x_0, ..., x_i, ..., x_{n-1}) */ 
00290     fxs         = Z3_mk_app(ctx, f, sz, xs);
00291 
00292     /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */
00293     finv_fxs    = mk_unary_app(ctx, finv, fxs);
00294 
00295     /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */
00296     eq          = Z3_mk_eq(ctx, finv_fxs, x_i);
00297 
00298     /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */
00299     p           = Z3_mk_pattern(ctx, 1, &fxs);
00300     printf("pattern: %s\n", Z3_ast_to_string(ctx, Z3_pattern_ast_to_ast(ctx, p)));
00301     printf("\n");
00302 
00303     /* create & assert quantifier */
00304     q           = Z3_mk_forall(ctx, 
00305                                  0, /* using default weight */
00306                                  1, /* number of patterns */
00307                                  &p, /* address of the "array" of patterns */
00308                                  sz, /* number of quantified variables */
00309                                  types, 
00310                                  names,
00311                                  eq);
00312     printf("assert axiom:\n%s\n", Z3_ast_to_string(ctx, q));
00313     Z3_assert_cnstr(ctx, q);
00314 
00315     /* free temporary arrays */
00316     free(types);
00317     free(names);
00318     free(xs);
00319 }

void bitvector_example1 (  ) 

Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers.

Definition at line 1313 of file test_capi.c.

01314 {
01315     Z3_context         ctx;
01316     Z3_type_ast        bv_type;
01317     Z3_ast             x, zero, ten, x_minus_ten, c1, c2, thm;
01318 
01319     printf("\nbitvector_example1\n");
01320     
01321     ctx       = mk_context();
01322     
01323     bv_type   = Z3_mk_bv_type(ctx, 32);
01324     
01325     x           = mk_var(ctx, "x", bv_type);
01326     zero        = Z3_mk_numeral(ctx, "0", bv_type);
01327     ten         = Z3_mk_numeral(ctx, "10", bv_type);
01328     x_minus_ten = Z3_mk_bvsub(ctx, x, ten);
01329     /* bvsle is signed less than or equal to */
01330     c1          = Z3_mk_bvsle(ctx, x, ten);
01331     c2          = Z3_mk_bvsle(ctx, x_minus_ten, zero);
01332     thm         = Z3_mk_iff(ctx, c1, c2);
01333     printf("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers\n");
01334     prove(ctx, thm, Z3_FALSE);
01335     
01336     Z3_del_context(ctx);
01337 }

void bitvector_example2 (  ) 

Find x and y such that: x ^ y - 103 == x * y.

Definition at line 1342 of file test_capi.c.

01343 {
01344     Z3_context ctx = mk_context();
01345  
01346     /* construct x ^ y - 103 == x * y */
01347     Z3_type_ast bv_type = Z3_mk_bv_type(ctx, 32);
01348     Z3_ast x = mk_var(ctx, "x", bv_type);
01349     Z3_ast y = mk_var(ctx, "y", bv_type);
01350     Z3_ast x_xor_y = Z3_mk_bvxor(ctx, x, y);
01351     Z3_ast c103 = Z3_mk_numeral(ctx, "103", bv_type);
01352     Z3_ast lhs = Z3_mk_bvsub(ctx, x_xor_y, c103);
01353     Z3_ast rhs = Z3_mk_bvmul(ctx, x, y);
01354     Z3_ast ctr = Z3_mk_eq(ctx, lhs, rhs);
01355 
01356     printf("\nbitvector_example2\n");
01357     printf("find values of x and y, such that x ^ y - 103 == x * y\n");
01358     
01359     /* add the constraint <tt>x ^ y - 103 == x * y<\tt> to the logical context */
01360     Z3_assert_cnstr(ctx, ctr);
01361     
01362     /* find a model (i.e., values for x an y that satisfy the constraint */
01363     check(ctx, Z3_L_TRUE);
01364     
01365     Z3_del_context(ctx);
01366 }

void check ( Z3_context  ctx,
Z3_lbool  expected_result 
)

Check whether the logical context is satisfiable, and compare the result with the expected result. If the context is satisfiable, then display the model.

Definition at line 158 of file test_capi.c.

Referenced by bitvector_example2(), find_model_example1(), find_model_example2(), parser_example1(), and parser_example2().

00159 {
00160     Z3_model m      = 0;
00161     Z3_lbool result = Z3_check_and_get_model(ctx, &m);
00162     switch (result) {
00163     case Z3_L_FALSE:
00164         printf("unsat\n");
00165         break;
00166     case Z3_L_UNDEF:
00167         printf("unknown\n");
00168         printf("potential model:\n%s\n", Z3_model_to_string(ctx, m));
00169         break;
00170     case Z3_L_TRUE:
00171         printf("sat\n%s\n", Z3_model_to_string(ctx, m));
00172         break;
00173     }
00174     if (m) {
00175         Z3_del_model(m);
00176     }
00177     if (result != expected_result) {
00178         exitf("unexpected result");
00179     }
00180 }

void check2 ( Z3_context  ctx,
Z3_lbool  expected_result 
)

Similar to check, but uses display_model instead of Z3_model_to_string.

Definition at line 603 of file test_capi.c.

Referenced by array_example2(), push_pop_example1(), and quantifier_example1().

00604 {
00605     Z3_model m      = 0;
00606     Z3_lbool result = Z3_check_and_get_model(ctx, &m);
00607     switch (result) {
00608     case Z3_L_FALSE:
00609         printf("unsat\n");
00610         break;
00611     case Z3_L_UNDEF:
00612         printf("unknown\n");
00613         printf("potential model:\n");
00614         display_model(ctx, stdout, m);
00615         break;
00616     case Z3_L_TRUE:
00617         printf("sat\n");
00618         display_model(ctx, stdout, m);
00619         break;
00620     }
00621     if (m) {
00622         Z3_del_model(m);
00623     }
00624     if (result != expected_result) {
00625         exitf("unexpected result");
00626     }
00627 }

void demorgan (  ) 

Demonstration of how Z3 can be used to prove validity of De Morgan's Duality Law: {e not(x and y) <-> (not x) or ( not y) }

Definition at line 666 of file test_capi.c.

00667 {
00668     Z3_config cfg;
00669     Z3_context ctx;
00670     Z3_type_ast bool_type;
00671     Z3_symbol symbol_x, symbol_y;
00672     Z3_ast x, y, not_x, not_y, x_and_y, ls, rs, conjecture, negated_conjecture;
00673     Z3_ast args[2];
00674 
00675     printf("\nDeMorgan\n");
00676     
00677     cfg                = Z3_mk_config();
00678     ctx                = Z3_mk_context(cfg);
00679     Z3_del_config(cfg);
00680 #ifdef TRACING
00681     Z3_trace_to_stderr(ctx);
00682 #endif
00683     bool_type          = Z3_mk_bool_type(ctx);
00684     symbol_x           = Z3_mk_int_symbol(ctx, 0);
00685     symbol_y           = Z3_mk_int_symbol(ctx, 1);
00686     x                  = Z3_mk_const(ctx, symbol_x, bool_type);
00687     y                  = Z3_mk_const(ctx, symbol_y, bool_type);
00688     
00689     /* De Morgan - with a negation around */
00690     /* !(!(x && y) <-> (!x || !y)) */
00691     not_x              = Z3_mk_not(ctx, x);
00692     not_y              = Z3_mk_not(ctx, y);
00693     args[0]            = x;
00694     args[1]            = y;
00695     x_and_y            = Z3_mk_and(ctx, 2, args);
00696     ls                 = Z3_mk_not(ctx, x_and_y);
00697     args[0]            = not_x;
00698     args[1]            = not_y;
00699     rs                 = Z3_mk_or(ctx, 2, args);
00700     conjecture         = Z3_mk_iff(ctx, ls, rs);
00701     negated_conjecture = Z3_mk_not(ctx, conjecture);
00702     
00703     Z3_assert_cnstr(ctx, negated_conjecture);
00704     switch (Z3_check(ctx)) {
00705     case Z3_L_FALSE:
00706         /* The negated conjecture was unsatisfiable, hence the conjecture is valid */
00707         printf("DeMorgan is valid\n");
00708         break;
00709     case Z3_L_UNDEF:
00710         /* Check returned undef */
00711         printf("Undef\n");
00712         break;
00713     case Z3_L_TRUE:
00714         /* The negated conjecture was satisfiable, hence the conjecture is not valid */
00715         printf("DeMorgan is not valid\n");
00716         break;
00717     }
00718     Z3_del_context(ctx);
00719 }

void display_function_interpretations ( Z3_context  c,
FILE *  out,
Z3_model  m 
)

Custom function interpretations pretty printer.

Definition at line 532 of file test_capi.c.

Referenced by display_model().

00533 {
00534     unsigned num_functions, i;
00535 
00536     fprintf(out, "function interpretations:\n");
00537 
00538     num_functions = Z3_get_model_num_funcs(c, m);
00539     for (i = 0; i < num_functions; i++) {
00540         if (!Z3_is_model_func_internal(c, m, i)) {
00541             Z3_const_decl_ast fdecl;
00542             Z3_symbol name;
00543             Z3_value func_else;
00544             unsigned num_entries, j;
00545 
00546             fdecl = Z3_get_model_func_decl(c, m, i);
00547             name = Z3_get_decl_name(c, fdecl);
00548             display_symbol(c, out, name);
00549             fprintf(out, " = {");
00550             num_entries = Z3_get_model_func_num_entries(c, m, i);
00551             for (j = 0; j < num_entries; j++) {
00552                 unsigned num_args, k;
00553                 if (j > 0) {
00554                     fprintf(out, ", ");
00555                 }
00556                 num_args = Z3_get_model_func_entry_num_args(c, m, i, j);
00557                 fprintf(out, "(");
00558                 for (k = 0; k < num_args; k++) {
00559                     if (k > 0) {
00560                         fprintf(out, ", ");
00561                     }
00562                     display_value(c, out, Z3_get_model_func_entry_arg(c, m, i, j, k));
00563                 }
00564                 fprintf(out, "|->");
00565                 display_value(c, out, Z3_get_model_func_entry_value(c, m, i, j));
00566                 fprintf(out, ")");
00567             }
00568             if (num_entries > 0) {
00569                 fprintf(out, ", ");
00570             }
00571             fprintf(out, "(else|->");
00572             func_else = Z3_get_model_func_else(c, m, i);
00573             display_value(c, out, func_else);
00574             fprintf(out, ")}\n");
00575         }
00576     }
00577 }

void display_model ( Z3_context  c,
FILE *  out,
Z3_model  m 
)

Custom model pretty printer.

Definition at line 582 of file test_capi.c.

Referenced by check2().

00583 {
00584     unsigned num_constants;
00585     unsigned i;
00586 
00587     num_constants = Z3_get_model_num_constants(c, m);
00588     for (i = 0; i < num_constants; i++) {
00589         Z3_symbol name;
00590         Z3_const_decl_ast cnst = Z3_get_model_constant(c, m, i);
00591         name = Z3_get_decl_name(c, cnst);
00592         display_symbol(c, out, name);
00593         fprintf(out, " = ");
00594         display_value(c, out, Z3_get_value(c, m, cnst));
00595         fprintf(out, "\n");
00596     }
00597     display_function_interpretations(c, out, m);
00598 }

void display_symbol ( Z3_context  c,
FILE *  out,
Z3_symbol  s 
)

Display a symbol in the given output stream.

Definition at line 405 of file test_capi.c.

Referenced by display_function_interpretations(), display_model(), display_type(), and print_term().

00406 {
00407     switch (Z3_get_symbol_kind(c, s)) {
00408     case Z3_INT_SYMBOL:
00409         fprintf(out, "#%d", Z3_get_symbol_int(c, s));
00410         break;
00411     case Z3_STRING_SYMBOL:
00412         fprintf(out, Z3_get_symbol_string(c, s));
00413         break;
00414     default:
00415         unreachable();
00416     }
00417 }

void display_type ( Z3_context  c,
FILE *  out,
Z3_type_ast  ty 
)

Display the given type.

Definition at line 422 of file test_capi.c.

Referenced by array_example3(), display_value(), and tuple_example1().

00423 {
00424     switch (Z3_get_type_kind(c, ty)) {
00425     case Z3_UNINTERPRETED_TYPE:
00426         display_symbol(c, out, Z3_get_type_name(c, ty));
00427         break;
00428     case Z3_BOOL_TYPE:
00429         fprintf(out, "bool");
00430         break;
00431     case Z3_INT_TYPE:
00432         fprintf(out, "int");
00433         break;
00434     case Z3_REAL_TYPE:
00435         fprintf(out, "real");
00436         break;
00437     case Z3_BV_TYPE:
00438         fprintf(out, "bv%d", Z3_get_bv_type_size(c, ty));
00439         break;
00440     case Z3_ARRAY_TYPE: 
00441         fprintf(out, "[");
00442         display_type(c, out, Z3_get_array_type_domain(c, ty));
00443         fprintf(out, "->");
00444         display_type(c, out, Z3_get_array_type_range(c, ty));
00445         fprintf(out, "]");
00446         break;
00447     case Z3_TUPLE_TYPE: {
00448         unsigned num_fields = Z3_get_tuple_type_num_fields(c, ty);
00449         unsigned i;
00450         fprintf(out, "(");
00451         for (i = 0; i < num_fields; i++) {
00452             Z3_const_decl_ast field = Z3_get_tuple_type_field_decl(c, ty, i);
00453             if (i > 0) {
00454                 fprintf(out, ", ");
00455             }
00456             display_type(c, out, Z3_get_range(c, field));
00457         }
00458         fprintf(out, ")");
00459         break;
00460     }
00461     default:
00462         fprintf(out, "unknown[");
00463         display_symbol(c, out, Z3_get_type_name(c, ty));
00464         fprintf(out, "]");
00465         break;
00466     }
00467 }

void display_value ( Z3_context  c,
FILE *  out,
Z3_value  v 
)

Custom value pretty printer.

This function demonstrates how to use the API to navigate values found in Z3 models.

Definition at line 475 of file test_capi.c.

Referenced by display_function_interpretations(), display_model(), and eval_example1().

00476 {
00477     switch (Z3_get_value_kind(c, v)) {
00478     case Z3_BOOL_VALUE:
00479         fprintf(out, Z3_get_bool_value_bool(c, v) ? "true" : "false");
00480         break;
00481     case Z3_NUMERAL_VALUE: {
00482         Z3_type_ast t;
00483         fprintf(out, Z3_get_numeral_value_string(c, v));
00484         t = Z3_get_value_type(c, v);
00485         fprintf(out, ":");
00486         display_type(c, out, t);
00487         break;
00488     }
00489     case Z3_TUPLE_VALUE: {
00490         unsigned i;
00491         unsigned num_fields = Z3_get_tuple_value_num_fields(c, v);
00492         fprintf(out, "[");
00493         for (i = 0; i < num_fields; i++) {
00494             if (i > 0) {
00495                 fprintf(out, ", ");
00496             }
00497             display_value(c, out, Z3_get_tuple_value_field(c, v, i));
00498         }
00499         fprintf(out, "]");
00500         break;
00501     }
00502     case Z3_ARRAY_VALUE: {
00503         unsigned i;
00504         unsigned array_size = Z3_get_array_value_size(c, v);
00505         fprintf(out, "{");
00506         for (i = 0; i < array_size; i++) {
00507             if (i > 0) {
00508                 fprintf(out, ", ");
00509             }
00510             fprintf(out, "(");
00511             display_value(c, out, Z3_get_array_value_entry_index(c, v, i));
00512             fprintf(out, "|->");
00513             display_value(c, out, Z3_get_array_value_entry_value(c, v, i));
00514             fprintf(out, ")");
00515         }
00516         if (array_size > 0) {
00517             fprintf(out, ", ");
00518         }
00519         fprintf(out, "(else|->");
00520         display_value(c, out, Z3_get_array_value_else(c, v));
00521         fprintf(out, ")}");
00522         break;
00523     }
00524     default:
00525         fprintf(out, "#unknown");
00526     }
00527 }

void display_version (  ) 

Display Z3 version in the standard output.

Definition at line 632 of file test_capi.c.

00633 {
00634     unsigned major, minor, build, revision;
00635     Z3_get_version(&major, &minor, &build, &revision);
00636     printf("Z3 %d.%d.%d.%d\n", major, minor, build, revision);
00637 }

void error_code_example1 (  ) 

Demonstrates how error codes can be read insted of registering an error handler.

Definition at line 1446 of file test_capi.c.

01447 {
01448     Z3_config cfg;
01449     Z3_context ctx;
01450     Z3_ast x;
01451     Z3_model m;
01452     Z3_value v;
01453     Z3_const_decl_ast x_decl;
01454     const char * str;
01455 
01456     printf("\nerror_code_example1\n");
01457     
01458     /* Do not register an error handler, as we want to use Z3_get_error_code manually */
01459     cfg = Z3_mk_config();
01460     ctx = mk_context_custom(cfg, NULL);
01461     Z3_del_config(cfg);
01462 
01463     x          = mk_bool_var(ctx, "x");
01464     x_decl     = Z3_get_const_ast_decl(ctx, Z3_to_const_ast(ctx, x));
01465     Z3_assert_cnstr(ctx, x);
01466     
01467     if (Z3_check_and_get_model(ctx, &m) != Z3_L_TRUE) {
01468         exitf("unexpected result");
01469     }
01470 
01471     v = Z3_get_value(ctx, m, x_decl);
01472     if (Z3_get_error_code(ctx) == Z3_OK) {
01473         printf("last call succeeded.\n");
01474     }
01475     /* The following call will fail since the value of x is a boolean */
01476     str = Z3_get_numeral_value_string(ctx, v);
01477     if (Z3_get_error_code(ctx) != Z3_OK) {
01478         printf("last call failed.\n");
01479     }
01480     Z3_del_model(m);
01481     Z3_del_context(ctx);
01482 }

void error_code_example2 (  ) 

Demonstrates how error handlers can be used.

Definition at line 1487 of file test_capi.c.

01488 {
01489     Z3_config cfg;
01490     Z3_context ctx = NULL;
01491     int r;
01492 
01493     printf("\nerror_code_example2\n");
01494     
01495     /* low tech try&catch */
01496     r = setjmp(g_catch_buffer);
01497     if (r == 0) {
01498         Z3_ast x, y, app;
01499         
01500         cfg = Z3_mk_config();
01501         ctx = mk_context_custom(cfg, throw_z3_error);
01502         Z3_del_config(cfg);
01503         
01504         x   = mk_int_var(ctx, "x");
01505         y   = mk_bool_var(ctx, "y");
01506         printf("before Z3_mk_iff\n"); 
01507         /* the next call will produce an error */
01508         app = Z3_mk_iff(ctx, x, y);
01509         unreachable();
01510         Z3_del_context(ctx);
01511     }
01512     else {
01513         printf("Z3 error: %s.\n", Z3_get_error_msg(r));
01514         if (cfg != NULL) {
01515             Z3_del_context(ctx);
01516         }
01517     }
01518 }

void error_handler ( Z3_error_code  e  ) 

Simpler error handler.

Definition at line 37 of file test_capi.c.

Referenced by mk_context(), parser_example3(), and quantifier_example1().

00038 {
00039   exitf("incorrect use of Z3");
00040 }

void eval_example1 (  ) 

Demonstrate how to use Z3_eval.

Definition at line 1371 of file test_capi.c.

01372 {
01373     Z3_context ctx;
01374     Z3_ast x, y, two;
01375     Z3_ast c1, c2;
01376     Z3_model m;
01377 
01378     printf("\neval_example1\n");
01379     
01380     ctx        = mk_context();
01381     x          = mk_int_var(ctx, "x");
01382     y          = mk_int_var(ctx, "y");
01383     two        = mk_int(ctx, 2);
01384     
01385     /* assert x < y */
01386     c1         = Z3_mk_lt(ctx, x, y);
01387     Z3_assert_cnstr(ctx, c1);
01388 
01389     /* assert x > 2 */
01390     c2         = Z3_mk_gt(ctx, x, two);
01391     Z3_assert_cnstr(ctx, c2);
01392 
01393     /* find model for the constraints above */
01394     if (Z3_check_and_get_model(ctx, &m) == Z3_L_TRUE) {
01395         Z3_ast   x_plus_y;
01396         Z3_ast   args[2] = {x, y};
01397         Z3_value v;
01398         printf("MODEL:\n%s", Z3_model_to_string(ctx, m));
01399         x_plus_y = Z3_mk_add(ctx, 2, args);
01400         printf("\nevaluating x+y\n");
01401         if (Z3_eval(ctx, m, x_plus_y, &v)) {
01402             printf("result = ");
01403             display_value(ctx, stdout, v);
01404             printf("\n");
01405         }
01406         else {
01407             exitf("failed to evaluate: x+y");
01408         }
01409         Z3_del_model(m);
01410     }
01411     else {
01412         exitf("the constraints are satisfiable");
01413     }
01414 
01415     Z3_del_context(ctx);
01416 }

void exitf ( const char *  message  ) 

exit gracefully in case of error.

Definition at line 20 of file test_capi.c.

Referenced by array_example3(), assert_comm_axiom(),