Home Docs Download Mail FAQ Awards Status MSR

Z3 An Efficient SMT Solver

TestManaged Class Reference
[Managed (.NET) API examples]

Class encapsulating Z3 tests. More...


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.


Detailed Description

Class encapsulating Z3 tests.

Definition at line 13 of file test_managed.cs.


Member Function Documentation

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]

Create a bit-vector type.

Definition at line 45 of file test_managed.cs.

Referenced by mk_bv_var().

00046     {
00047         return z3.MkBvSort(num_bytes);
00048     }

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().

00039     {
00040         return z3.MkIntSort();
00041     }

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().

00053     {
00054         return z3.MkConst(name, ty);
00055     }

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.

See also:
assert_inj_axiom.

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.

See also:
assert_inj_axiom.

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     }

Last modified Thu Nov 12 16:35:57 2009