| Home | • | Docs | • | Download | • | • | FAQ | • | Awards | • | Status | • | MSR |
|---|
An Efficient SMT Solver
Public Member Functions | |
| void | mk_context () |
| Create a logical context with model construction enabled. | |
| Sort | mk_int_type () |
| Create an integer type. | |
| Sort | mk_bv_type (uint num_bytes) |
| Create a bit-vector type. | |
| Term | mk_var (string name, Sort ty) |
| Create a variable using the given name and type. | |
| Term | mk_bool_var (string name) |
| Create a boolean variable using the given name. | |
| Term | mk_int_var (string name) |
| Create an integer variable using the given name. | |
| Term | mk_bv_var (string name, uint num_bytes) |
| Create a bit-vector variable using the given name. | |
| void | check (LBool expected_result, out Model model) |
| 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 | check2 (LBool expected_result) |
| Similar to check, but uses display_model instead of Z3's native display method. | |
| void | prove (Term f) |
| Prove that the constraints already asserted into the logical context implies the given formula. The result of the proof is displayed. | |
| void | prove2 (Term f, 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 (FuncDecl f, int i) |
| Assert the axiom: function f is injective in the i-th argument. | |
| void | assert_inj_axiom_abs (FuncDecl f, int i) |
| Assert the axiom: function f is injective in the i-th argument. | |
| void | simple_example () |
| "Hello world" example: create a Z3 logical context, and delete it. | |
| 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 | quantifier_example1_abs () |
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 | tuple_example () |
| Tuples. | |
| 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 | injective_example () |
| Injective functions. | |
| 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 () |
| Create an ite-term (if-then-else terms). | |
| void | enum_example () |
| Create an enumeration data type. | |
| void | list_example () |
| Create a list datatype. | |
| void | tree_example () |
| Create a binary tree datatype. | |
| void | forest_example () |
| Create a forest of trees. | |
| void | eval_example1 () |
| Demonstrate how to use Eval. | |
| void | eval_example2 () |
| Demonstrate how to use Eval on tuples. | |
| void | check_small (Term[] to_minimize) |
| Demonstrate how to use Push and Pop to control the size of models. | |
| void | find_small_model_example () |
| Reduced-size model generation example. | |
| void | simplifier_example () |
| Simplifier example. | |
| void | unsat_core_and_proof_example () |
| Extract unsatisfiable core example. | |
| void | get_implied_equalities_example () |
| Extract implied equalities. | |
Definition at line 13 of file test_managed.cs.
| void array_example1 | ( | ) | [inline] |
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 830 of file test_managed.cs.
00831 { 00832 00833 Console.WriteLine("array_example1"); 00834 00835 mk_context(); 00836 00837 Sort int_type = mk_int_type(); 00838 Sort array_type = z3.MkArraySort(int_type, int_type); 00839 00840 Term a1 = mk_var("a1", array_type); 00841 Term a2 = mk_var("a2", array_type); 00842 Term i1 = mk_var("i1", int_type); 00843 Term i2 = mk_var("i2", int_type); 00844 Term i3 = mk_var("i3", int_type); 00845 Term v1 = mk_var("v1", int_type); 00846 Term v2 = mk_var("v2", int_type); 00847 00848 Term st1 = z3.MkArrayStore(a1, i1, v1); 00849 Term st2 = z3.MkArrayStore(a2, i2, v2); 00850 00851 Term sel1 = z3.MkArraySelect(a1, i3); 00852 Term sel2 = z3.MkArraySelect(a2, i3); 00853 00854 /* create antecedent */ 00855 Term antecedent = z3.MkEq(st1, st2); 00856 00857 /* create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3) */ 00858 Term consequent = z3.MkOr(new Term[] { z3.MkEq(i1, i3), z3.MkEq(i2, i3), z3.MkEq(sel1, sel2) }); 00859 00860 /* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) */ 00861 Term thm = z3.MkImplies(antecedent, consequent); 00862 Console.WriteLine("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))"); 00863 Console.WriteLine("{0}", z3.ToString(thm)); 00864 prove(thm); 00865 }
| void array_example2 | ( | ) | [inline] |
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 873 of file test_managed.cs.
00874 { 00875 Console.WriteLine("array_example2"); 00876 00877 for (int n = 2; n <= 5; n++) 00878 { 00879 Console.WriteLine("n = {0}", n); 00880 mk_context(); 00881 00882 if (n == 3) 00883 { 00884 z3.OpenLog("array3.z3"); 00885 } 00886 Sort bool_type = z3.MkBoolSort(); 00887 Sort array_type = z3.MkArraySort(bool_type, bool_type); 00888 Term[] a = new Term[n]; 00889 00890 /* create arrays */ 00891 for (int i = 0; i < n; i++) 00892 { 00893 a[i] = z3.MkConst(String.Format("array_{0}", i), array_type); 00894 } 00895 00896 /* assert distinct(a[0], ..., a[n]) */ 00897 Term d = z3.MkDistinct(a); 00898 Console.WriteLine("{0}", z3.ToString(d)); 00899 z3.AssertCnstr(d); 00900 00901 /* context is satisfiable if n < 5 */ 00902 Model model = null; 00903 check(n < 5 ? LBool.True : LBool.False, out model); 00904 if (n < 5) 00905 { 00906 for (int i = 0; i < n; i++) 00907 { 00908 Console.WriteLine("{0} = {1}", 00909 z3.ToString(a[i]), 00910 z3.ToString(model.Eval(a[i]))); 00911 } 00912 } 00913 if (model != null) 00914 { 00915 model.Dispose(); 00916 } 00917 } 00918 }
| void assert_inj_axiom | ( | FuncDecl | f, | |
| int | i | |||
| ) | [inline] |
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 312 of file test_managed.cs.
Referenced by quantifier_example1().
00313 { 00314 Sort[] domain = z3.GetDomain(f); 00315 uint sz = (uint)domain.Length; 00316 00317 if (i >= sz) 00318 { 00319 Console.WriteLine("failed to create inj axiom"); 00320 return; 00321 } 00322 00323 /* declare the i-th inverse of f: finv */ 00324 Sort finv_domain = z3.GetRange(f); 00325 Sort finv_range = domain[i]; 00326 FuncDecl finv = z3.MkFuncDecl("f_fresh", finv_domain, finv_range); 00327 00328 /* allocate temporary arrays */ 00329 Term[] xs = new Term[sz]; 00330 Symbol[] names = new Symbol[sz]; 00331 Sort[] types = new Sort[sz]; 00332 00333 /* fill types, names and xs */ 00334 00335 for (uint j = 0; j < sz; j++) 00336 { 00337 types[j] = domain[j]; 00338 names[j] = z3.MkSymbol(String.Format("x_{0}", j)); 00339 xs[j] = z3.MkBound(j, types[j]); 00340 } 00341 Term x_i = xs[i]; 00342 00343 /* create f(x_0, ..., x_i, ..., x_{n-1}) */ 00344 Term fxs = z3.MkApp(f, xs); 00345 00346 /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ 00347 Term finv_fxs = mk_unary_app(finv, fxs); 00348 00349 /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ 00350 Term eq = z3.MkEq(finv_fxs, x_i); 00351 00352 /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ 00353 Pattern p = z3.MkPattern(new Term[] { fxs }); 00354 Console.WriteLine("pattern {0}", z3.ToString(p)); 00355 00356 /* create & assert quantifier */ 00357 Term q = z3.MkForall( 00358 0, /* using default weight */ 00359 new Pattern[] { p }, /* patterns */ 00360 types, /* types of quantified variables */ 00361 names, /* names of quantified variables */ 00362 eq); 00363 00364 Console.WriteLine("assert axiom {0}", z3.ToString(q)); 00365 z3.AssertCnstr(q); 00366 00367 }
| void assert_inj_axiom_abs | ( | FuncDecl | f, | |
| int | i | |||
| ) | [inline] |
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 379 of file test_managed.cs.
Referenced by quantifier_example1_abs().
00380 { 00381 Sort[] domain = z3.GetDomain(f); 00382 uint sz = (uint)domain.Length; 00383 00384 if (i >= sz) 00385 { 00386 Console.WriteLine("failed to create inj axiom"); 00387 return; 00388 } 00389 00390 /* declare the i-th inverse of f: finv */ 00391 Sort finv_domain = z3.GetRange(f); 00392 Sort finv_range = domain[i]; 00393 FuncDecl finv = z3.MkFuncDecl("f_fresh", finv_domain, finv_range); 00394 00395 /* allocate temporary arrays */ 00396 Term[] xs = new Term[sz]; 00397 00398 /* fill types, names and xs */ 00399 00400 for (uint j = 0; j < sz; j++) 00401 { 00402 xs[j] = z3.MkConst(String.Format("x_{0}", j), domain[j]); 00403 } 00404 Term x_i = xs[i]; 00405 00406 /* create f(x_0, ..., x_i, ..., x_{n-1}) */ 00407 Term fxs = z3.MkApp(f, xs); 00408 00409 /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ 00410 Term finv_fxs = mk_unary_app(finv, fxs); 00411 00412 /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ 00413 Term eq = z3.MkEq(finv_fxs, x_i); 00414 00415 /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ 00416 Pattern p = z3.MkPattern(new Term[] { fxs }); 00417 Console.WriteLine("pattern {0}", z3.ToString(p)); 00418 00419 /* create & assert quantifier */ 00420 Term q = z3.MkForall( 00421 0, /* using default weight */ 00422 xs, /* the list of bound variables */ 00423 new Pattern[] { p }, /* patterns */ 00424 eq); 00425 00426 Console.WriteLine("assert axiom {0}", z3.ToString(q)); 00427 z3.AssertCnstr(q); 00428 00429 }
| void bitvector_example1 | ( | ) | [inline] |
Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers.
Definition at line 952 of file test_managed.cs.
00953 { 00954 Console.WriteLine("\nbitvector_example1"); 00955 00956 mk_context(); 00957 00958 Sort bv_type = z3.MkBvSort(32); 00959 Term x = mk_var("x", bv_type); 00960 Term zero = z3.MkNumeral("0", bv_type); 00961 Term ten = z3.MkNumeral("10", bv_type); 00962 Term x_minus_ten = z3.MkBvSub(x, ten); 00963 /* bvsle is signed less than or equal to */ 00964 Term c1 = z3.MkBvSle(x, ten); 00965 Term c2 = z3.MkBvSle(x_minus_ten, zero); 00966 Term thm = z3.MkIff(c1, c2); 00967 Console.WriteLine("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers"); 00968 prove(thm); 00969 }
| void bitvector_example2 | ( | ) | [inline] |
Find x and y such that: x ^ y - 103 == x * y.
Definition at line 974 of file test_managed.cs.
00975 { 00976 mk_context(); 00977 00978 /* construct x ^ y - 103 == x * y */ 00979 Sort bv_type = z3.MkBvSort(32); 00980 Term x = mk_var("x", bv_type); 00981 Term y = mk_var("y", bv_type); 00982 Term x_xor_y = z3.MkBvXor(x, y); 00983 Term c103 = z3.MkNumeral("103", bv_type); 00984 Term lhs = z3.MkBvSub(x_xor_y, c103); 00985 Term rhs = z3.MkBvMul(x, y); 00986 Term ctr = z3.MkEq(lhs, rhs); 00987 00988 Console.WriteLine("\nbitvector_example2"); 00989 Console.WriteLine("find values of x and y, such that x ^ y - 103 == x * y"); 00990 00991 /* add the constraint <tt>x ^ y - 103 == x * y<\tt> to the logical context */ 00992 z3.AssertCnstr(ctr); 00993 00994 /* find a model (i.e., values for x an y that satisfy the constraint */ 00995 check2(LBool.True); 00996 }
| void check | ( | LBool | expected_result, | |
| out Model | model | |||
| ) | [inline] |
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 119 of file test_managed.cs.
Referenced by array_example2(), find_model_example1(), find_model_example2(), and push_pop_example1().
00120 { 00121 LBool result = z3.CheckAndGetModel(out model); 00122 switch (result) 00123 { 00124 case LBool.False: 00125 Console.WriteLine("unsat"); 00126 break; 00127 case LBool.Undef: 00128 Console.WriteLine("unknown"); 00129 break; 00130 case LBool.True: 00131 Console.WriteLine("sat"); 00132 model.Display(Console.Out); 00133 break; 00134 } 00135 if (result != expected_result) 00136 { 00137 Console.WriteLine("BUG: unexpected result"); 00138 } 00139 }
| void check2 | ( | LBool | expected_result | ) | [inline] |
Similar to check, but uses display_model instead of Z3's native display method.
Definition at line 144 of file test_managed.cs.
Referenced by bitvector_example2(), parser_example1(), parser_example2(), prove_example1(), and push_pop_example1().
00145 { 00146 Model model = null; 00147 LBool result = z3.CheckAndGetModel(out model); 00148 switch (result) 00149 { 00150 case LBool.False: 00151 Console.WriteLine("unsat"); 00152 break; 00153 case LBool.Undef: 00154 Console.WriteLine("unknown"); 00155 break; 00156 case LBool.True: 00157 Console.WriteLine("sat"); 00158 display_model(Console.Out, model); 00159 break; 00160 } 00161 if (result != expected_result) 00162 { 00163 Console.WriteLine("BUG: unexpected result"); 00164 } 00165 if (model != null) 00166 { 00167 model.Dispose(); 00168 } 00169 }
| void check_small | ( | Term[] | to_minimize | ) | [inline] |
Demonstrate how to use Push and Pop to control the size of models.
Note: this test is specialized to 32-bit bitvectors.
Definition at line 1547 of file test_managed.cs.
01548 { 01549 01550 Sort bv32 = mk_bv_type(32); 01551 01552 int num_terms = to_minimize.Length; 01553 UInt32[] upper = new UInt32[num_terms]; 01554 UInt32[] lower = new UInt32[num_terms]; 01555 Term[] values = new Term[num_terms]; 01556 for (int i = 0; i < upper.Length; ++i) 01557 { 01558 upper[i] = UInt32.MaxValue; 01559 lower[i] = 0; 01560 } 01561 bool some_work = true; 01562 int last_index = -1; 01563 UInt32 last_upper = 0; 01564 while (some_work) 01565 { 01566 z3.Push(); 01567 01568 bool check_is_sat = true; 01569 while (check_is_sat && some_work) 01570 { 01571 // Assert all feasible bounds. 01572 for (int i = 0; i < num_terms; ++i) 01573 { 01574 z3.AssertCnstr(z3.MkBvUle(to_minimize[i], mk_bv32(upper[i]))); 01575 } 01576 Model model = null; 01577 check_is_sat = LBool.True == z3.CheckAndGetModel(out model); 01578 if (!check_is_sat) 01579 { 01580 if (last_index != -1) 01581 { 01582 lower[last_index] = last_upper + 1; 01583 } 01584 if (model != null) 01585 { 01586 model.Dispose(); 01587 } 01588 break; 01589 } 01590 model.Display(Console.Out); 01591 01592 // narrow the bounds based on the current model. 01593 for (int i = 0; i < num_terms; ++i) 01594 { 01595 Term v = model.Eval(to_minimize[i]); 01596 UInt64 ui = z3.GetNumeralUInt64(v); 01597 if (ui < upper[i]) 01598 { 01599 upper[i] = (UInt32)ui; 01600 } 01601 Console.WriteLine("{0} {1} {2}", i, lower[i], upper[i]); 01602 } 01603 model.Dispose(); 01604 // find a new bound to add 01605 some_work = false; 01606 last_index = 0; 01607 for (int i = 0; i < num_terms; ++i) 01608 { 01609 if (lower[i] < upper[i]) 01610 { 01611 last_upper = (upper[i] + lower[i]) / 2; 01612 last_index = i; 01613 z3.AssertCnstr(z3.MkBvUle(to_minimize[i], mk_bv32(last_upper))); 01614 some_work = true; 01615 break; 01616 } 01617 } 01618 } 01619 z3.Pop(); 01620 } 01621 }
| void enum_example | ( | ) | [inline] |
Create an enumeration data type.
Definition at line 1176 of file test_managed.cs.
01177 { 01178 mk_context(); 01179 Symbol name = z3.MkSymbol("fruit"); 01180 01181 FuncDecl[] enum_consts = new FuncDecl[3]; 01182 FuncDecl[] enum_testers = new FuncDecl[3]; 01183 01184 Console.WriteLine("\nenum_example"); 01185 01186 01187 Sort fruit = z3.MkEnumerationSort("fruit", new string[] { "apple", "banana", "orange" }, enum_consts, enum_testers); 01188 01189 Console.WriteLine("{0}", (enum_consts[0])); 01190 Console.WriteLine("{0}", (enum_consts[1])); 01191 Console.WriteLine("{0}", (enum_consts[2])); 01192 01193 Console.WriteLine("{0}", (enum_testers[0])); 01194 Console.WriteLine("{0}", (enum_testers[1])); 01195 Console.WriteLine("{0}", (enum_testers[2])); 01196 01197 Term apple = z3.MkConst(enum_consts[0]); 01198 Term banana = z3.MkConst(enum_consts[1]); 01199 Term orange = z3.MkConst(enum_consts[2]); 01200 01201 /* Apples are different from oranges */ 01202 prove2(z3.MkNot(z3.MkEq(apple, orange)), true); 01203 01204 /* Apples pass the apple test */ 01205 prove2(z3.MkApp(enum_testers[0], apple), true); 01206 01207 /* Oranges fail the apple test */ 01208 prove2(z3.MkApp(enum_testers[0], orange), false); 01209 prove2(z3.MkNot(z3.MkApp(enum_testers[0], orange)), true); 01210 01211 Term fruity = mk_var("fruity", fruit); 01212 01213 /* If something is fruity, then it is an apple, banana, or orange */ 01214 01215 prove2(z3.MkOr(new Term[] { z3.MkEq(fruity, apple), z3.MkEq(fruity, banana), z3.MkEq(fruity, orange) }), true); 01216 }
| void eval_example1 | ( | ) | [inline] |
Demonstrate how to use Eval.
Definition at line 1460 of file test_managed.cs.
01461 { 01462 Console.WriteLine("\neval_example1"); 01463 mk_context(); 01464 Term x = mk_int_var("x"); 01465 Term y = mk_int_var("y"); 01466 Term two = mk_int(2); 01467 01468 /* assert x < y */ 01469 z3.AssertCnstr(z3.MkLt(x, y)); 01470 01471 /* assert x > 2 */ 01472 z3.AssertCnstr(z3.MkGt(x, two)); 01473 01474 /* find model for the constraints above */ 01475 Model model = null; 01476 if (LBool.True == z3.CheckAndGetModel(out model)) 01477 { 01478 model.Display(Console.Out); 01479 Console.WriteLine("\nevaluating x+y"); 01480 Term v = model.Eval(z3.MkAdd(x, y)); 01481 if (v != null) 01482 { 01483 Console.WriteLine("result = {0}", z3.ToString(v)); 01484 } 01485 else 01486 { 01487 Console.WriteLine("Failed to evaluate: x+y"); 01488 } 01489 model.Dispose(); 01490 } 01491 else 01492 { 01493 Console.WriteLine("BUG, the constraints are satisfiable."); 01494 } 01495 }
| void eval_example2 | ( | ) | [inline] |
Demonstrate how to use Eval on tuples.
Definition at line 1500 of file test_managed.cs.
01501 { 01502 Console.WriteLine("\neval_example2"); 01503 mk_context(); 01504 Sort int_type = mk_int_type(); 01505 FuncDecl[] decls = new FuncDecl[2]; 01506 FuncDecl mk_tuple = null; 01507 Sort tuple = z3.MkTupleSort 01508 ( 01509 z3.MkSymbol("mk_tuple"), // name of tuple constructor 01510 new Symbol[] { z3.MkSymbol("first"), z3.MkSymbol("second") }, // names of projection operators 01511 new Sort[] { int_type, int_type }, // types of projection operators 01512 out mk_tuple, 01513 decls // return declarations. 01514 ); 01515 FuncDecl first = decls[0]; // declarations are for projections 01516 FuncDecl second = decls[1]; 01517 Term tup1 = z3.MkConst("t1", tuple); 01518 Term tup2 = z3.MkConst("t2", tuple); 01519 /* assert tup1 != tup2 */ 01520 z3.AssertCnstr(z3.MkNot(z3.MkEq(tup1, tup2))); 01521 /* assert first tup1 = first tup2 */ 01522 z3.AssertCnstr(z3.MkEq(z3.MkApp(first, tup1), z3.MkApp(first, tup2))); 01523 01524 /* find model for the constraints above */ 01525 Model model = null; 01526 if (LBool.True == z3.CheckAndGetModel(out model)) 01527 { 01528 model.Display(Console.Out); 01529 Console.WriteLine("evaluating tup1 {0}", z3.ToString(model.Eval(tup1))); 01530 Console.WriteLine("evaluating tup2 {0}", z3.ToString(model.Eval(tup2))); 01531 Console.WriteLine("evaluating second(tup2) {0}", 01532 z3.ToString(model.Eval(z3.MkApp(second, tup2)))); 01533 model.Dispose(); 01534 } 01535 else 01536 { 01537 Console.WriteLine("BUG, the constraints are satisfiable."); 01538 } 01539 }
| void find_model_example1 | ( | ) | [inline] |
Find a model for x xor y.
Definition at line 485 of file test_managed.cs.
00486 { 00487 Console.WriteLine("find_model_example1"); 00488 00489 mk_context(); 00490 00491 Term x = mk_bool_var("x"); 00492 Term y = mk_bool_var("y"); 00493 Term x_xor_y = z3.MkXor(x, y); 00494 00495 z3.AssertCnstr(x_xor_y); 00496 00497 Console.WriteLine("model for: x xor y"); 00498 Model model = null; 00499 check(LBool.True, out model); 00500 Console.WriteLine("x = {0}, y = {1}", 00501 z3.ToString(model.Eval(x)), 00502 z3.ToString(model.Eval(y))); 00503 model.Dispose(); 00504 }
| void find_model_example2 | ( | ) | [inline] |
Find a model for x < y + 1, x > 2. Then, assert not(x = y), and find another model.
Definition at line 510 of file test_managed.cs.
00511 { 00512 Console.WriteLine("find_model_example2"); 00513 00514 mk_context(); 00515 Term x = mk_int_var("x"); 00516 Term y = mk_int_var("y"); 00517 Term one = mk_int(1); 00518 Term two = mk_int(2); 00519 00520 Term y_plus_one = z3.MkAdd(y, one); 00521 00522 Term c1 = z3.MkLt(x, y_plus_one); 00523 Term c2 = z3.MkGt(x, two); 00524 00525 z3.AssertCnstr(c1); 00526 z3.AssertCnstr(c2); 00527 00528 Console.WriteLine("model for: x < y + 1, x > 2"); 00529 Model model = null; 00530 check(LBool.True, out model); 00531 Console.WriteLine("x = {0}, y = {1}", 00532 z3.ToString(model.Eval(x)), 00533 z3.ToString(model.Eval(y))); 00534 model.Dispose(); 00535 model = null; 00536 00537 /* assert not(x = y) */ 00538 Term x_eq_y = z3.MkEq(x, y); 00539 Term c3 = z3.MkNot(x_eq_y); 00540 z3.AssertCnstr(c3); 00541 00542 Console.WriteLine("model for: x < y + 1, x > 2, not(x = y)"); 00543 check(LBool.True, out model); 00544 Console.WriteLine("x = {0}, y = {1}", 00545 z3.ToString(model.Eval(x)), 00546 z3.ToString(model.Eval(y))); 00547 model.Dispose(); 00548 }
| void find_small_model_example | ( | ) | [inline] |
Reduced-size model generation example.
Definition at line 1626 of file test_managed.cs.
01627 { 01628 mk_context(); 01629 Term x = mk_bv_var("x", 32); 01630 Term y = mk_bv_var("y", 32); 01631 Term z = mk_bv_var("z", 32); 01632 Sort bv32 = mk_bv_type(32); 01633 z3.AssertCnstr(z3.MkBvUle(x, z3.MkBvAdd(y, z))); 01634 check_small(new Term[] { x, y, z }); 01635 }
| void forest_example | ( | ) | [inline] |
Create a forest of trees.
forest ::= nil | cons(tree, forest) tree ::= nil | cons(forest, forest)
Definition at line 1351 of file test_managed.cs.
01352 { 01353 mk_context(); 01354 Sort tree, forest; 01355 FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; 01356 FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; 01357 Term nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; 01358 01359 // 01360 // Declare the names of the accessors for cons. 01361 // Then declare the sorts of the accessors. 01362 // For this example, all sorts refer to the new types 'forest' and 'tree' 01363 // being declared, so we pass in null for both sorts1 and sorts2. 01364 // On the other hand, the sort_refs arrays contain the indices of the 01365 // two new sorts being declared. The first element in sort1_refs 01366 // points to 'tree', which has index 1, the second element in sort1_refs array 01367 // points to 'forest', which has index 0. 01368 // 01369 string[] head_tail1 = new string[] { "head", "tail" }; 01370 Sort[] sorts1 = new Sort[] { null, null }; 01371 uint[] sort1_refs = new uint[] { 1, 0 }; // the first item points to a tree, the second to a forest 01372 01373 string[] head_tail2 = new string[] { "car", "cdr" }; 01374 Sort[] sorts2 = new Sort[] { null, null }; 01375 uint[] sort2_refs = new uint[] { 0, 0 }; // both items point to the forest datatype. 01376 Constructor nil1_con, cons1_con, nil2_con, cons2_con; 01377 Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; 01378 string[] sort_names = { "forest", "tree" }; 01379 01380 Console.WriteLine("\nforest_example"); 01381 01382 /* build a forest */ 01383 nil1_con = z3.MkConstructor("nil", "is_nil", null, null, null); 01384 cons1_con = z3.MkConstructor("cons1", "is_cons1", head_tail1, sorts1, sort1_refs); 01385 constructors1[0] = nil1_con; 01386 constructors1[1] = cons1_con; 01387 01388 /* build a tree */ 01389 nil2_con = z3.MkConstructor("nil2", "is_nil2", null, null, null); 01390 cons2_con = z3.MkConstructor("cons2", "is_cons2", head_tail2, sorts2, sort2_refs); 01391 constructors2[0] = nil2_con; 01392 constructors2[1] = cons2_con; 01393 01394 01395 Constructor[][] clists = new Constructor[][] { constructors1, constructors2 }; 01396 01397 Sort[] sorts = z3.MkDataTypes(sort_names, clists); 01398 forest = sorts[0]; 01399 tree = sorts[1]; 01400 01401 // 01402 // Now that the datatype has been created. 01403 // Query the constructors for the constructor 01404 // functions, testers, and field accessors. 01405 // 01406 nil1_decl = z3.GetConstructor(nil1_con); 01407 is_nil1_decl = z3.GetTester(nil1_con); 01408 cons1_decl = z3.GetConstructor(cons1_con); 01409 is_cons1_decl = z3.GetTester(cons1_con); 01410 FuncDecl[] cons1_accessors = z3.GetAccessors(cons1_con); 01411 car1_decl = cons1_accessors[0]; 01412 cdr1_decl = cons1_accessors[1]; 01413 01414 nil2_decl = z3.GetConstructor(nil2_con); 01415 is_nil2_decl = z3.GetTester(nil2_con); 01416 cons2_decl = z3.GetConstructor(cons2_con); 01417 is_cons2_decl = z3.GetTester(cons2_con); 01418 FuncDecl[] cons2_accessors = z3.GetAccessors(cons2_con); 01419 car2_decl = cons2_accessors[0]; 01420 cdr2_decl = cons2_accessors[1]; 01421 01422 01423 nil1 = z3.MkConst(nil1_decl); 01424 nil2 = z3.MkConst(nil2_decl); 01425 f1 = mk_binary_app(cons1_decl, nil2, nil1); 01426 t1 = mk_binary_app(cons2_decl, nil1, nil1); 01427 t2 = mk_binary_app(cons2_decl, f1, nil1); 01428 t3 = mk_binary_app(cons2_decl, f1, f1); 01429 t4 = mk_binary_app(cons2_decl, nil1, f1); 01430 f2 = mk_binary_app(cons1_decl, t1, nil1); 01431 f3 = mk_binary_app(cons1_decl, t1, f1); 01432 01433 01434 /* nil != cons(nil,nil) */ 01435 prove2(z3.MkNot(z3.MkEq(nil1, f1)), true); 01436 prove2(z3.MkNot(z3.MkEq(nil2, t1)), true); 01437 01438 01439 /* cons(x,u) = cons(x, v) => u = v */ 01440 u = mk_var("u", forest); 01441 v = mk_var("v", forest); 01442 x = mk_var("x", tree); 01443 y = mk_var("y", tree); 01444 l1 = mk_binary_app(cons1_decl, x, u); 01445 l2 = mk_binary_app(cons1_decl, y, v); 01446 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); 01447 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); 01448 01449 /* is_nil(u) or is_cons(u) */ 01450 prove2(z3.MkOr(z3.MkApp(is_nil1_decl, u), z3.MkApp(is_cons1_decl, u)), true); 01451 01452 /* occurs check u != cons(x,u) */ 01453 prove2(z3.MkNot(z3.MkEq(u, l1)), true); 01454 }
| void get_implied_equalities_example | ( | ) | [inline] |
Extract implied equalities.
Definition at line 1711 of file test_managed.cs.
01711 { 01712 if (this.z3 != null) 01713 { 01714 this.z3.Dispose(); 01715 } 01716 Config p = new Config(); 01717 p.SetParamValue("ARITH_PROPAGATE_EXPENSIVE_EQS","true"); 01718 p.SetParamValue("ARITH_EQ_BOUNDS","true"); 01719 this.z3 = new Context(p); 01720 p.Dispose(); 01721 01722 Sort int_sort = z3.MkIntSort(); 01723 Term a = mk_int_var("a"); 01724 Term b = mk_int_var("b"); 01725 Term c = mk_int_var("c"); 01726 Term d = mk_int_var("d"); 01727 FuncDecl f = z3.MkFuncDecl("f", int_sort, int_sort); 01728 Term fa = z3.MkApp(f,a); 01729 Term fb = z3.MkApp(f,b); 01730 Term fc = z3.MkApp(f,c); 01731 Term[] terms = new Term[]{ a, b, c, d, fa, fb, fc }; 01732 uint[] class_ids; 01733 01734 z3.AssertCnstr(z3.MkEq(a, b)); 01735 z3.AssertCnstr(z3.MkEq(b, c)); 01736 z3.AssertCnstr(z3.MkLe(fc, a)); 01737 z3.AssertCnstr(z3.MkLe(b, fb)); 01738 int num_terms = terms.Length; 01739 01740 z3.GetImpliedEqualities(terms, out class_ids); 01741 for (int i = 0; i < num_terms; ++i) { 01742 Console.WriteLine("Class {0} |-> {1}", terms[i], class_ids[i]); 01743 } 01744 }
| void injective_example | ( | ) | [inline] |
Injective functions.
Check that the projection of a tuple returns the corresponding element.
Definition at line 1003 of file test_managed.cs.
01004 { 01005 mk_context(); 01006 Sort int_type = mk_int_type(); 01007 FuncDecl f = z3.MkInjectiveFunction("f_inj", new Sort[] { int_type }, int_type); 01008 Term x = z3.MkConst("x", int_type); 01009 Term y = z3.MkConst("y", int_type); 01010 Term fx = z3.MkApp(f, x); 01011 Term f_y = z3.MkApp(f, y); 01012 Term c = z3.MkImplies(z3.MkEq(fx, f_y), z3.MkEq(x, y)); 01013 Console.WriteLine("Injective example: {0}", z3.ToString(c)); 01014 prove(c); 01015 }
| void ite_example | ( | ) | [inline] |
Create an ite-term (if-then-else terms).
Definition at line 1160 of file test_managed.cs.
01161 { 01162 Console.WriteLine("\nite_example"); 01163 mk_context(); 01164 01165 Term f = z3.MkFalse(); 01166 Term one = mk_int(1); 01167 Term zero = mk_int(0); 01168 Term ite = z3.MkIte(f, one, zero); 01169 01170 Console.WriteLine("term: {0}", ite); 01171 }
| void list_example | ( | ) | [inline] |
Create a list datatype.
Definition at line 1222 of file test_managed.cs.
01223 { 01224 mk_context(); 01225 01226 Sort int_ty, int_list; 01227 FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl; 01228 Term nil, l1, l2, x, y, u, v, fml, fml1; 01229 01230 Console.WriteLine("\nlist_example"); 01231 01232 int_ty = z3.MkIntSort(); 01233 01234 int_list = z3.MkListSort("int_list", int_ty, 01235 out nil_decl, out is_nil_decl, out cons_decl, out is_cons_decl, out head_decl, out tail_decl); 01236 01237 nil = z3.MkConst(nil_decl); 01238 l1 = mk_binary_app(cons_decl, mk_int(1), nil); 01239 l2 = mk_binary_app(cons_decl, mk_int(2), nil); 01240 01241 /* nil != cons(1, nil) */ 01242 prove2(z3.MkNot(z3.MkEq(nil, l1)), true); 01243 01244 /* cons(2,nil) != cons(1, nil) */ 01245 prove2(z3.MkNot(z3.MkEq(l1, l2)), true); 01246 01247 /* cons(x,nil) = cons(y, nil) => x = y */ 01248 x = mk_var("x", int_ty); 01249 y = mk_var("y", int_ty); 01250 l1 = mk_binary_app(cons_decl, x, nil); 01251 l2 = mk_binary_app(cons_decl, y, nil); 01252 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); 01253 01254 /* cons(x,u) = cons(x, v) => u = v */ 01255 u = mk_var("u", int_list); 01256 v = mk_var("v", int_list); 01257 l1 = mk_binary_app(cons_decl, x, u); 01258 l2 = mk_binary_app(cons_decl, y, v); 01259 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); 01260 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); 01261 01262 /* is_nil(u) or is_cons(u) */ 01263 prove2(z3.MkOr(z3.MkApp(is_nil_decl, u), z3.MkApp(is_cons_decl, u)), true); 01264 01265 /* occurs check u != cons(x,u) */ 01266 prove2(z3.MkNot(z3.MkEq(u, l1)), true); 01267 01268 /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ 01269 fml1 = z3.MkEq(u, mk_binary_app(cons_decl, mk_unary_app(head_decl, u), mk_unary_app(tail_decl, u))); 01270 fml = z3.MkImplies(z3.MkApp(is_cons_decl, u), fml1); 01271 Console.WriteLine("Formula {0}", fml); 01272 01273 prove2(fml, true); 01274 01275 prove2(fml1, false); 01276 }
| Term mk_bool_var | ( | string | name | ) | [inline] |
Create a boolean variable using the given name.
Definition at line 59 of file test_managed.cs.
Referenced by find_model_example1().
00060 { 00061 return mk_var(name, z3.MkBoolSort()); 00062 }
| Sort mk_bv_type | ( | uint | num_bytes | ) | [inline] |
| Term mk_bv_var | ( | string | name, | |
| uint | num_bytes | |||
| ) | [inline] |
Create a bit-vector variable using the given name.
Definition at line 73 of file test_managed.cs.
00074 { 00075 return mk_var(name, mk_bv_type(num_bytes)); 00076 }
| void mk_context | ( | ) | [inline] |
Create a logical context with model construction enabled.
Definition at line 23 of file test_managed.cs.
Referenced by array_example1(), array_example2(), bitvector_example1(), bitvector_example2(), enum_example(), find_model_example1(), find_model_example2(), injective_example(), ite_example(), parser_example1(), parser_example2(), parser_example3(), parser_example4(), prove_example1(), prove_example2(), push_pop_example1(), and tuple_example().
00024 { 00025 if (this.z3 != null) 00026 { 00027 this.z3.Dispose(); 00028 } 00029 Config p = new Config(); 00030 p.SetParamValue("MODEL", "true"); 00031 this.z3 = new Context(p); 00032 p.Dispose(); 00033 }
| Sort mk_int_type | ( | ) | [inline] |
Create an integer type.
Definition at line 38 of file test_managed.cs.
Referenced by array_example1(), injective_example(), mk_int_var(), prove_example2(), push_pop_example1(), quantifier_example1(), quantifier_example1_abs(), and tuple_example().
| Term mk_int_var | ( | string | name | ) | [inline] |
Create an integer variable using the given name.
Definition at line 66 of file test_managed.cs.
Referenced by find_model_example2(), prove_example2(), quantifier_example1(), and quantifier_example1_abs().
00067 { 00068 return mk_var(name, mk_int_type()); 00069 }
| Term mk_var | ( | string | name, | |
| Sort | ty | |||
| ) | [inline] |
Create a variable using the given name and type.
Definition at line 52 of file test_managed.cs.
Referenced by array_example1(), bitvector_example1(), bitvector_example2(), enum_example(), mk_bool_var(), mk_bv_var(), and mk_int_var().
| void parser_example1 | ( | ) | [inline] |
Demonstrates how to use the SMTLIB parser.
Definition at line 1020 of file test_managed.cs.
01021 { 01022 mk_context(); 01023 01024 Console.WriteLine("\nparser_example1"); 01025 01026 Term[] formulas, assumptions; 01027 FuncDecl[] decls; 01028 Sort[] sorts; 01029 string err; 01030 z3.ParseSmtlibString("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))", 01031 null, null, out assumptions, out formulas, out decls, out sorts, out err); 01032 foreach (var f in formulas) 01033 { 01034 Console.WriteLine("formula {0}", f); 01035 z3.AssertCnstr(f); 01036 } 01037 check2(LBool.True); 01038 }
| void parser_example2 | ( | ) | [inline] |
Demonstrates how to initialize the parser symbol table.
Definition at line 1043 of file test_managed.cs.
01044 { 01045 mk_context(); 01046 Console.WriteLine("\nparser_example2"); 01047 01048 /* 01049 Z3_enable_arithmetic doesn't need to be invoked in this example 01050 because it will be implicitly invoked by mk_int_var. 01051 */ 01052 01053 FuncDecl a = z3.MkConstDecl("a", z3.MkIntSort()); 01054 FuncDecl b = z3.MkConstDecl("b", z3.MkIntSort()); 01055 FuncDecl[] decls = new FuncDecl[] { a, b }; 01056 Term[] formulas, assumptions; 01057 FuncDecl[] new_decls; 01058 Sort[] sorts; 01059 string err; 01060 01061 z3.ParseSmtlibString( 01062 "(benchmark tst :formula (> a b))", 01063 null, 01064 decls, 01065 out assumptions, out formulas, out new_decls, out sorts, out err); 01066 Term f = formulas[0]; 01067 Console.WriteLine("formula: {0}", f); 01068 z3.AssertCnstr(f); 01069 check2(LBool.True); 01070 }
| void parser_example3 | ( | ) | [inline] |
Demonstrates how to initialize the parser symbol table.
Definition at line 1075 of file test_managed.cs.
01076 { 01077 Console.WriteLine("\nparser_example3"); 01078 01079 mk_context(); 01080 01081 /* declare function g */ 01082 Sort int_type = z3.MkIntSort(); 01083 FuncDecl g = z3.MkFuncDecl("g", new Sort[] { int_type, int_type }, int_type); 01084 Term[] formulas, assumptions; 01085 FuncDecl[] new_decls; 01086 Sort[] sorts; 01087 string err; 01088 01089 assert_comm_axiom(g); 01090 01091 z3.ParseSmtlibString 01092 ( 01093 "(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y)))))", 01094 null, 01095 new FuncDecl[] { g }, 01096 out assumptions, out formulas, out new_decls, out sorts, out err); 01097 Term thm = formulas[0]; 01098 Console.WriteLine("formula: {0}", thm); 01099 prove(thm); 01100 }
| void parser_example4 | ( | ) | [inline] |
Display the declarations, assumptions and formulas in a SMT-LIB string.
Definition at line 1105 of file test_managed.cs.
01106 { 01107 mk_context(); 01108 01109 Console.WriteLine("\nparser_example4"); 01110 01111 Term[] formulas, assumptions; 01112 FuncDecl[] decls; 01113 Sort[] sorts; 01114 string err; 01115 z3.ParseSmtlibString 01116 ("(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))", 01117 null, null, 01118 out assumptions, out formulas, out decls, out sorts, out err); 01119 foreach (var decl in decls) 01120 { 01121 Console.WriteLine("Declaration: {0}", decl); 01122 } 01123 foreach (var f in assumptions) 01124 { 01125 Console.WriteLine("Assumption: {0}", f); 01126 } 01127 foreach (var f in formulas) 01128 { 01129 Console.WriteLine("Formula: {0}", f); 01130 } 01131 }
| void parser_example5 | ( | ) | [inline] |
Demonstrates how to handle parser errors using Z3 error handling support.
Definition at line 1136 of file test_managed.cs.
01137 { 01138 Console.WriteLine("\nparser_example5"); 01139 01140 Term[] formulas, assumptions; 01141 FuncDecl[] decls; 01142 Sort[] sorts; 01143 string err = ""; 01144 try 01145 { 01146 z3.ParseSmtlibString( 01147 /* the following string has a parsing error: missing parenthesis */ 01148 "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))", 01149 null, null, out assumptions, out formulas, out decls, out sorts, out err); 01150 } 01151 catch (Z3Error e) 01152 { 01153 Console.WriteLine("Z3 error: {0} {1}", e, err); 01154 } 01155 }
| void prove | ( | Term | f | ) | [inline] |
Prove that the constraints already asserted into the logical context implies the given formula. The result of the proof is displayed.
Z3 is a satisfiability checker. So, one can prove f by showing that (not f) is unsatisfiable.
Definition at line 182 of file test_managed.cs.
Referenced by array_example1(), bitvector_example1(), injective_example(), parser_example3(), prove_example1(), prove_example2(), quantifier_example1(), quantifier_example1_abs(), and tuple_example().
00183 { 00184 /* save the current state of the context */ 00185 z3.Push(); 00186 00187 Term not_f = z3.MkNot(f); 00188 z3.AssertCnstr(not_f); 00189 00190 Model model = null; 00191 switch (z3.CheckAndGetModel(out model)) 00192 { 00193 case LBool.False: 00194 /* proved */ 00195 Console.WriteLine("valid"); 00196 break; 00197 case LBool.Undef: 00198 /* Z3 failed to prove/disprove f. */ 00199 Console.WriteLine("unknown"); 00200 break; 00201 case LBool.True: 00202 /* disproved */ 00203 Console.WriteLine("invalid"); 00204 model.Display(Console.Out); 00205 break; 00206 } 00207 if (model != null) 00208 { 00209 model.Dispose(); 00210 } 00211 00212 /* restore context */ 00213 z3.Pop(1); 00214 }
| void prove2 | ( | Term | f, | |
| bool | is_valid | |||
| ) | [inline] |
Prove that the constraints already asserted into the logical context implies the given formula. The result of the proof is displayed.
Z3 is a satisfiability checker. So, one can prove f by showing that (not f) is unsatisfiable.
Definition at line 225 of file test_managed.cs.
Referenced by enum_example().
00226 { 00227 /* save the current state of the context */ 00228 z3.Push(); 00229 00230 Term not_f = z3.MkNot(f); 00231 z3.AssertCnstr(not_f); 00232 00233 Model model = null; 00234 LBool result = z3.CheckAndGetModel(out model); 00235 switch (result) 00236 { 00237 case LBool.False: 00238 /* proved */ 00239 Console.WriteLine("valid"); 00240 if (!is_valid) 00241 { 00242 exitf("Did not expecte valid"); 00243 } 00244 break; 00245 case LBool.Undef: 00246 /* Z3 failed to prove/disprove f. */ 00247 Console.WriteLine("unknown"); 00248 if (is_valid) 00249 { 00250 exitf("Expected valid"); 00251 } 00252 break; 00253 case LBool.True: 00254 /* disproved */ 00255 Console.WriteLine("invalid"); 00256 model.Display(Console.Out); 00257 if (is_valid) 00258 { 00259 exitf("Expected valid"); 00260 } 00261 break; 00262 } 00263 if (model != null) 00264 { 00265 model.Dispose(); 00266 } 00267 00268 /* restore context */ 00269 z3.Pop(1); 00270 00271 }
| void prove_example1 | ( | ) | [inline] |
Prove x = y implies g(x) = g(y), and disprove x = y implies g(g(x)) = g(y).
This function demonstrates how to create uninterpreted types and functions.
Definition at line 557 of file test_managed.cs.
00558 { 00559 Console.WriteLine("prove_example1"); 00560 00561 mk_context(); 00562 00563 /* create uninterpreted type. */ 00564 Sort U = z3.MkSort("U"); 00565 00566 /* declare function g */ 00567 FuncDecl g = z3.MkFuncDecl("g", U, U); 00568 00569 /* create x and y */ 00570 Term x = z3.MkConst("x", U); 00571 Term y = z3.MkConst("y", U); 00572 /* create g(x), g(y) */ 00573 Term gx = mk_unary_app(g, x); 00574 Term gy = mk_unary_app(g, y); 00575 00576 /* assert x = y */ 00577 Term eq = z3.MkEq(x, y); 00578 z3.AssertCnstr(eq); 00579 00580 /* prove g(x) = g(y) */ 00581 Term f = z3.MkEq(gx, gy); 00582 Console.WriteLine("prove: x = y implies g(x) = g(y)"); 00583 prove(f); 00584 00585 /* create g(g(x)) */ 00586 Term ggx = mk_unary_app(g, gx); 00587 00588 /* disprove g(g(x)) = g(y) */ 00589 f = z3.MkEq(ggx, gy); 00590 Console.WriteLine("disprove: x = y implies g(g(x)) = g(y)"); 00591 prove(f); 00592 00593 00594 /* Print the model using the custom model printer */ 00595 z3.AssertCnstr(z3.MkNot(f)); 00596 check2(LBool.True); 00597 }
| void prove_example2 | ( | ) | [inline] |
Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . Then, show that z < -1 is not implied.
This example demonstrates how to combine uninterpreted functions and arithmetic.
Definition at line 605 of file test_managed.cs.
00606 { 00607 Console.WriteLine("prove_example2"); 00608 00609 mk_context(); 00610 00611 /* declare function g */ 00612 Sort int_type = mk_int_type(); 00613 00614 FuncDecl g = z3.MkFuncDecl("g", int_type, int_type); 00615 00616 /* create x, y, and z */ 00617 Term x = mk_int_var("x"); 00618 Term y = mk_int_var("y"); 00619 Term z = mk_int_var("z"); 00620 00621 /* create gx, gy, gz */ 00622 Term gx = mk_unary_app(g, x); 00623 Term gy = mk_unary_app(g, y); 00624 Term gz = mk_unary_app(g, z); 00625 00626 /* create zero */ 00627 Term zero = mk_int(0); 00628 00629 /* assert not(g(g(x) - g(y)) = g(z)) */ 00630 Term gx_gy = z3.MkSub(gx, gy); 00631 Term ggx_gy = mk_unary_app(g, gx_gy); 00632 Term eq = z3.MkEq(ggx_gy, gz); 00633 Term c1 = z3.MkNot(eq); 00634 z3.AssertCnstr(c1); 00635 00636 /* assert x + z <= y */ 00637 Term x_plus_z = z3.MkAdd(x, z); 00638 Term c2 = z3.MkLe(x_plus_z, y); 00639 z3.AssertCnstr(c2); 00640 00641 /* assert y <= x */ 00642 Term c3 = z3.MkLe(y, x); 00643 z3.AssertCnstr(c3); 00644 00645 /* prove z < 0 */ 00646 Term f = z3.MkLt(z, zero); 00647 Console.WriteLine("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); 00648 prove(f); 00649 00650 /* disprove z < -1 */ 00651 Term minus_one = mk_int(-1); 00652 f = z3.MkLt(z, minus_one); 00653 Console.WriteLine("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); 00654 prove(f); 00655 }
| void push_pop_example1 | ( | ) | [inline] |
Show how push & pop can be used to create "backtracking" points.
This example also demonstrates how big numbers can be created in Z3.
Definition at line 662 of file test_managed.cs.
00663 { 00664 Console.WriteLine("push_pop_example1"); 00665 00666 mk_context(); 00667 00668 /* create a big number */ 00669 Sort int_type = mk_int_type(); 00670 Term big_number = z3.MkNumeral("1000000000000000000000000000000000000000000000000000000", int_type); 00671 00672 /* create number 3 */ 00673 Term three = z3.MkNumeral("3", int_type); 00674 00675 /* create x */ 00676 Term x = z3.MkConst("x", int_type); 00677 00678 00679 /* assert x >= "big number" */ 00680 Term c1 = z3.MkGe(x, big_number); 00681 Console.WriteLine("assert: x >= 'big number'"); 00682 z3.AssertCnstr(c1); 00683 00684 /* create a backtracking point */ 00685 Console.WriteLine("push"); 00686 z3.Push(); 00687 00688 /* assert x <= 3 */ 00689 Term c2 = z3.MkLe(x, three); 00690 Console.WriteLine("assert: x <= 3"); 00691 z3.AssertCnstr(c2); 00692 00693 /* context is inconsistent at this point */ 00694 Model model = null; 00695 check(LBool.False, out model); 00696 00697 /* backtrack: the constraint x <= 3 will be removed, since it was 00698 asserted after the last z3.Push. */ 00699 Console.WriteLine("pop"); 00700 z3.Pop(1); 00701 00702 /* the context is consistent again. */ 00703 check2(LBool.True); 00704 00705 /* new constraints can be asserted... */ 00706 00707 /* create y */ 00708 Term y = z3.MkConst("y", int_type); 00709 00710 /* assert y > x */ 00711 Term c3 = z3.MkGt(y, x); 00712 Console.WriteLine("assert: y > x"); 00713 z3.AssertCnstr(c3); 00714 00715 /* the context is still consistent. */ 00716 check(LBool.True, out model); 00717 model.Dispose(); 00718 }
| void quantifier_example1 | ( | ) | [inline] |
Prove that f(x, y) = f(w, v) implies y = v when f is injective in the second argument.
Definition at line 726 of file test_managed.cs.
00727 { 00728 Console.WriteLine("quantifier_example1"); 00729 00730 Config p = new Config(); 00731 // p.SetParamValue("MODEL", "true"); 00732 /* If quantified formulas are asserted in a logical context, then 00733 the model produced by Z3 should be viewed as a potential model. 00734 00735 */ 00736 if (this.z3 != null) 00737 { 00738 this.z3.Dispose(); 00739 } 00740 this.z3 = new Context(p); 00741 p.Dispose(); 00742 00743 /* declare function f */ 00744 Sort int_type = mk_int_type(); 00745 FuncDecl f = z3.MkFuncDecl("f", new Sort[] { int_type, int_type }, int_type); 00746 00747 /* assert that f is injective in the second argument. */ 00748 assert_inj_axiom(f, 1); 00749 00750 /* create x, y, v, w, fxy, fwv */ 00751 Term x = mk_int_var("x"); 00752 Term y = mk_int_var("y"); 00753 Term v = mk_int_var("v"); 00754 Term w = mk_int_var("w"); 00755 Term fxy = mk_binary_app(f, x, y); 00756 Term fwv = mk_binary_app(f, w, v); 00757 00758 /* assert f(x, y) = f(w, v) */ 00759 Term p1 = z3.MkEq(fxy, fwv); 00760 z3.AssertCnstr(p1); 00761 00762 /* prove f(x, y) = f(w, v) implies y = v */ 00763 Term p2 = z3.MkEq(y, v); 00764 Console.WriteLine("prove: f(x, y) = f(w, v) implies y = v"); 00765 prove(p2); 00766 00767 /* disprove f(x, y) = f(w, v) implies x = w */ 00768 Term p3 = z3.MkEq(x, w); 00769 Console.WriteLine("disprove: f(x, y) = f(w, v) implies x = w"); 00770 prove(p3); 00771 }
| void quantifier_example1_abs | ( | ) | [inline] |
Prove that f(x, y) = f(w, v) implies y = v when f is injective in the second argument.
Definition at line 778 of file test_managed.cs.
00779 { 00780 Console.WriteLine("quantifier_example1_abs"); 00781 00782 Config p = new Config(); 00783 // p.SetParamValue("MODEL", "true"); 00784 /* If quantified formulas are asserted in a logical context, then 00785 the model produced by Z3 should be viewed as a potential model. 00786 00787 */ 00788 if (this.z3 != null) 00789 { 00790 this.z3.Dispose(); 00791 } 00792 this.z3 = new Context(p); 00793 p.Dispose(); 00794 00795 /* declare function f */ 00796 Sort int_type = mk_int_type(); 00797 FuncDecl f = z3.MkFuncDecl("f", new Sort[] { int_type, int_type }, int_type); 00798 00799 /* assert that f is injective in the second argument. */ 00800 assert_inj_axiom_abs(f, 1); 00801 00802 /* create x, y, v, w, fxy, fwv */ 00803 Term x = mk_int_var("x"); 00804 Term y = mk_int_var("y"); 00805 Term v = mk_int_var("v"); 00806 Term w = mk_int_var("w"); 00807 Term fxy = mk_binary_app(f, x, y); 00808 Term fwv = mk_binary_app(f, w, v); 00809 00810 /* assert f(x, y) = f(w, v) */ 00811 Term p1 = z3.MkEq(fxy, fwv); 00812 z3.AssertCnstr(p1); 00813 00814 /* prove f(x, y) = f(w, v) implies y = v */ 00815 Term p2 = z3.MkEq(y, v); 00816 Console.WriteLine("prove: f(x, y) = f(w, v) implies y = v"); 00817 prove(p2); 00818 00819 /* disprove f(x, y) = f(w, v) implies x = w */ 00820 Term p3 = z3.MkEq(x, w); 00821 Console.WriteLine("disprove: f(x, y) = f(w, v) implies x = w"); 00822 prove(p3); 00823 }
| void simple_example | ( | ) | [inline] |
"Hello world" example: create a Z3 logical context, and delete it.
Definition at line 469 of file test_managed.cs.
00470 { 00471 Console.WriteLine("simple_example"); 00472 Config p = new Config(); 00473 Context z3 = new Context(p); 00474 00475 /* do something with the context */ 00476 00477 /* be kind to dispose manually and not wait for the GC. */ 00478 z3.Dispose(); 00479 p.Dispose(); 00480 }
| void simplifier_example | ( | ) | [inline] |
Simplifier example.
Definition at line 1640 of file test_managed.cs.
01641 { 01642 mk_context(); 01643 Term x = mk_int_var("x"); 01644 Term y = mk_int_var("y"); 01645 Term z = mk_int_var("z"); 01646 Term u = mk_int_var("u"); 01647 01648 Term t1 = z3.MkAdd(x, z3.MkSub(y, z3.MkAdd(x, z))); 01649 Term t2 = z3.Simplify(t1); 01650 Console.WriteLine("{0} -> {1}", z3.ToString(t1), z3.ToString(t2)); 01651 }
| void tree_example | ( | ) | [inline] |
Create a binary tree datatype.
Definition at line 1283 of file test_managed.cs.
01284 { 01285 mk_context(); 01286 Sort cell; 01287 FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; 01288 Term nil, l1, l2, x, y, u, v, fml, fml1; 01289 string[] head_tail = new string[] { "car", "cdr" }; 01290 Sort[] sorts = new Sort[] { null, null }; 01291 uint[] sort_refs = new uint[] { 0, 0 }; 01292 Constructor nil_con, cons_con; 01293 01294 Console.WriteLine("\ntree_example"); 01295 01296 nil_con = z3.MkConstructor("nil", "is_nil", null, null, null); 01297 cons_con = z3.MkConstructor("cons", "is_cons", head_tail, sorts, sort_refs); 01298 Constructor[] constructors = new Constructor[] { nil_con, cons_con }; 01299 01300 cell = z3.MkDataType("cell", constructors); 01301 01302 nil_decl = z3.GetConstructor(nil_con); 01303 is_nil_decl = z3.GetTester(nil_con); 01304 cons_decl = z3.GetConstructor(cons_con); 01305 is_cons_decl = z3.GetTester(cons_con); 01306 FuncDecl[] cons_accessors = z3.GetAccessors(cons_con); 01307 car_decl = cons_accessors[0]; 01308 cdr_decl = cons_accessors[1]; 01309 01310 nil = z3.MkConst(nil_decl); 01311 l1 = mk_binary_app(cons_decl, nil, nil); 01312 l2 = mk_binary_app(cons_decl, l1, nil); 01313 01314 /* nil != cons(nil, nil) */ 01315 prove2(z3.MkNot(z3.MkEq(nil, l1)), true); 01316 01317 /* cons(x,u) = cons(x, v) => u = v */ 01318 u = mk_var("u", cell); 01319 v = mk_var("v", cell); 01320 x = mk_var("x", cell); 01321 y = mk_var("y", cell); 01322 l1 = mk_binary_app(cons_decl, x, u); 01323 l2 = mk_binary_app(cons_decl, y, v); 01324 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); 01325 prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); 01326 01327 /* is_nil(u) or is_cons(u) */ 01328 prove2(z3.MkOr(z3.MkApp(is_nil_decl, u), z3.MkApp(is_cons_decl, u)), true); 01329 01330 /* occurs check u != cons(x,u) */ 01331 prove2(z3.MkNot(z3.MkEq(u, l1)), true); 01332 01333 /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ 01334 fml1 = z3.MkEq(u, mk_binary_app(cons_decl, mk_unary_app(car_decl, u), mk_unary_app(cdr_decl, u))); 01335 fml = z3.MkImplies(z3.MkApp(is_cons_decl, u), fml1); 01336 Console.WriteLine("Formula {0}", fml); 01337 prove2(fml, true); 01338 01339 prove2(fml1, false); 01340 01341 }
| void tuple_example | ( | ) | [inline] |
Tuples.
Check that the projection of a tuple returns the corresponding element.
Definition at line 924 of file test_managed.cs.
00925 { 00926 mk_context(); 00927 Sort int_type = mk_int_type(); 00928 FuncDecl[] decls = new FuncDecl[2]; 00929 FuncDecl mk_tuple = null; 00930 Sort tuple = z3.MkTupleSort 00931 ( 00932 z3.MkSymbol("mk_tuple"), // name of tuple constructor 00933 new Symbol[] { z3.MkSymbol("first"), z3.MkSymbol("second") }, // names of projection operators 00934 new Sort[] { int_type, int_type }, // types of projection operators 00935 out mk_tuple, 00936 decls // return declarations. 00937 ); 00938 FuncDecl first = decls[0]; // declarations are for projections 00939 FuncDecl second = decls[1]; 00940 Term x = z3.MkConst("x", int_type); 00941 Term y = z3.MkConst("y", int_type); 00942 Term n1 = z3.MkApp(mk_tuple, x, y); 00943 Term n2 = z3.MkApp(first, n1); 00944 Term n3 = z3.MkEq(x, n2); 00945 Console.WriteLine("Tuple example: {0}", z3.ToString(n3)); 00946 prove(n3); 00947 }
| void unsat_core_and_proof_example | ( | ) | [inline] |
Extract unsatisfiable core example.
Definition at line 1656 of file test_managed.cs.
01657 { 01658 if (this.z3 != null) 01659 { 01660 this.z3.Dispose(); 01661 } 01662 Config p = new Config(); 01663 // p.SetParamValue("MODEL","true"); 01664 p.SetParamValue("PROOF_MODE", "2"); 01665 this.z3 = new Context(p); 01666 p.Dispose(); 01667 01668 Term pa = mk_bool_var("PredA"); 01669 Term pb = mk_bool_var("PredB"); 01670 Term pc = mk_bool_var("PredC"); 01671 Term pd = mk_bool_var("PredD"); 01672 Term p1 = mk_bool_var("P1"); 01673 Term p2 = mk_bool_var("P2"); 01674 Term p3 = mk_bool_var("P3"); 01675 Term p4 = mk_bool_var("P4"); 01676 Term[] assumptions = new Term[] { z3.MkNot(p1), z3.MkNot(p2), z3.MkNot(p3), z3.MkNot(p4) }; 01677 Term f1 = z3.MkAnd(new Term[] { pa, pb, pc }); 01678 Term f2 = z3.MkAnd(new Term[] { pa, z3.MkNot(pb), pc }); 01679 Term f3 = z3.MkOr(z3.MkNot(pa), z3.MkNot(pc)); 01680 Term f4 = pd; 01681 01682 z3.AssertCnstr(z3.MkOr(f1, p1)); 01683 z3.AssertCnstr(z3.MkOr(f2, p2)); 01684 z3.AssertCnstr(z3.MkOr(f3, p3)); 01685 z3.AssertCnstr(z3.MkOr(f4, p4)); 01686 Term[] core = null; 01687 Term proof; 01688 Model m = null; 01689 LBool result; 01690 01691 result = z3.CheckAssumptions(out m, assumptions, out proof, out core); 01692 01693 if (result == LBool.False) 01694 { 01695 Console.WriteLine("unsat"); 01696 Console.WriteLine("proof: {0}", proof); 01697 foreach (Term c in core) 01698 { 01699 Console.WriteLine("{0}", c); 01700 } 01701 } 01702 if (m != null) 01703 { 01704 m.Dispose(); 01705 } 01706 }