| Home | • | Docs | • | Download | • | • | FAQ | • | Awards | • | Status | • | MSR |
|---|
An Efficient SMT Solver
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 () |
| 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(),