/// <summary> /// Generates a slightly randomized expression. /// </summary> static BoolExpr MkRandomExpr(Context ctx, System.Random rng) { int limit = 1073741823; Sort i = ctx.IntSort; Sort b = ctx.BoolSort; Symbol sr1 = ctx.MkSymbol(rng.Next(0, limit)); Symbol sr2 = ctx.MkSymbol(rng.Next(0, limit)); Symbol sr3 = ctx.MkSymbol(rng.Next(0, limit)); FuncDecl r1 = ctx.MkFuncDecl(sr1, i, b); FuncDecl r2 = ctx.MkFuncDecl(sr2, i, b); FuncDecl r3 = ctx.MkFuncDecl(sr3, i, b); Symbol s = ctx.MkSymbol(rng.Next(0, limit)); Expr x = ctx.MkConst(s, i); BoolExpr r1x = (BoolExpr)ctx.MkApp(r1, x); BoolExpr r2x = (BoolExpr)ctx.MkApp(r2, x); BoolExpr r3x = (BoolExpr)ctx.MkApp(r3, x); Expr[] vars = { x }; BoolExpr rl1 = ctx.MkForall(vars, ctx.MkImplies(r1x, r2x)); BoolExpr rl2 = ctx.MkForall(vars, ctx.MkImplies(r2x, r1x)); BoolExpr rl3 = (BoolExpr)ctx.MkApp(r1, ctx.MkInt(3)); BoolExpr q = (BoolExpr)ctx.MkApp(r3, ctx.MkInt(2)); BoolExpr a1 = ctx.MkNot(q); BoolExpr q1 = ctx.MkExists(vars, ctx.MkAnd(r3x, r2x)); BoolExpr q2 = ctx.MkExists(vars, ctx.MkAnd(r3x, r1x)); BoolExpr[] all = { a1, q1, q2 }; return ctx.MkAnd(all); }
public static void ProveExample2(Context ctx) { Console.WriteLine("ProveExample2"); /* declare function g */ Sort I = ctx.IntSort; FuncDecl g = ctx.MkFuncDecl("g", I, I); /* create x, y, and z */ IntExpr x = ctx.MkIntConst("x"); IntExpr y = ctx.MkIntConst("y"); IntExpr z = ctx.MkIntConst("z"); /* create gx, gy, gz */ Expr gx = ctx.MkApp(g, x); Expr gy = ctx.MkApp(g, y); Expr gz = ctx.MkApp(g, z); /* create zero */ IntExpr zero = ctx.MkInt(0); /* assert not(g(g(x) - g(y)) = g(z)) */ ArithExpr gx_gy = ctx.MkSub((IntExpr)gx, (IntExpr)gy); Expr ggx_gy = ctx.MkApp(g, gx_gy); BoolExpr eq = ctx.MkEq(ggx_gy, gz); BoolExpr c1 = ctx.MkNot(eq); /* assert x + z <= y */ ArithExpr x_plus_z = ctx.MkAdd(x, z); BoolExpr c2 = ctx.MkLe(x_plus_z, y); /* assert y <= x */ BoolExpr c3 = ctx.MkLe(y, x); /* prove z < 0 */ BoolExpr f = ctx.MkLt(z, zero); Console.WriteLine("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); Prove(ctx, f, c1, c2, c3); /* disprove z < -1 */ IntExpr minus_one = ctx.MkInt(-1); f = ctx.MkLt(z, minus_one); Console.WriteLine("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); Disprove(ctx, f, c1, c2, c3); }
//Constructor public Z3Context() { //Initialize Config and Context _config = new Config(); _config.SetParamValue("MODEL", "true"); // corresponds to /m switch _config.SetParamValue("MACRO_FINDER", "true"); _context = new Context(_config); //Setup custom conversion method BoolToInt (boolean -> integer)---------------------------------------------------------------- FuncDecl boolToInt = _context.MkFuncDecl("BoolToInt", _context.MkBoolSort(), _context.MkIntSort()); Term i = _context.MkConst("i", _context.MkBoolSort()); Term fDef = _context.MkIte(_context.MkEq(i, _context.MkTrue()), _context.MkIntNumeral(1), _context.MkIntNumeral(0)); // x == true => 1, x == false => 0 Term fStatement = _context.MkForall(0, new Term[] { i }, null, _context.MkEq(_context.MkApp(boolToInt, i), fDef)); _context.AssertCnstr(fStatement); // _functions.Add("BoolToInt", new Z3Function(boolToInt)); //----------------------------------------------------------------------------------------------------------------------------- }
internal EnumSort(Context ctx, Symbol name, Symbol[] enumNames) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(name != null); Contract.Requires(enumNames != null); int n = enumNames.Length; IntPtr[] n_constdecls = new IntPtr[n]; IntPtr[] n_testers = new IntPtr[n]; NativeObject = Native.Z3_mk_enumeration_sort(ctx.nCtx, name.NativeObject, (uint)n, Symbol.ArrayToNative(enumNames), n_constdecls, n_testers); _constdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); _testerdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); _consts = new Expr[n]; for (uint i = 0; i < n; i++) _consts[i] = ctx.MkApp(_constdecls[i]); }
/// <summary> /// Some basic tests. /// </summary> static void BasicTests(Context ctx) { Console.WriteLine("BasicTests"); Symbol qi = ctx.MkSymbol(1); Symbol fname = ctx.MkSymbol("f"); Symbol x = ctx.MkSymbol("x"); Symbol y = ctx.MkSymbol("y"); Sort bs = ctx.MkBoolSort(); Sort[] domain = { bs, bs }; FuncDecl f = ctx.MkFuncDecl(fname, domain, bs); Expr fapp = ctx.MkApp(f, ctx.MkConst(x, bs), ctx.MkConst(y, bs)); Expr[] fargs2 = { ctx.MkFreshConst("cp", bs) }; Sort[] domain2 = { bs }; Expr fapp2 = ctx.MkApp(ctx.MkFreshFuncDecl("fp", domain2, bs), fargs2); BoolExpr trivial_eq = ctx.MkEq(fapp, fapp); BoolExpr nontrivial_eq = ctx.MkEq(fapp, fapp2); Goal g = ctx.MkGoal(true); g.Assert(trivial_eq); g.Assert(nontrivial_eq); Console.WriteLine("Goal: " + g); Solver solver = ctx.MkSolver(); foreach (BoolExpr a in g.Formulas) solver.Assert(a); if (solver.Check() != Status.SATISFIABLE) throw new TestFailedException(); ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) throw new TestFailedException(); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) throw new TestFailedException(); g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) throw new TestFailedException(); Goal g2 = ctx.MkGoal(true, true); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) throw new TestFailedException(); g2 = ctx.MkGoal(true, true); g2.Assert(ctx.MkFalse()); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) throw new TestFailedException(); Goal g3 = ctx.MkGoal(true, true); Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); BoolExpr constr = ctx.MkEq(xc, yc); g3.Assert(constr); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) throw new TestFailedException(); ModelConverterTest(ctx); // Real num/den test. RatNum rn = ctx.MkReal(42, 43); Expr inum = rn.Numerator; Expr iden = rn.Denominator; Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); if (inum.ToString() != "42" || iden.ToString() != "43") throw new TestFailedException(); if (rn.ToDecimalString(3) != "0.976?") throw new TestFailedException(); BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); BigIntCheck(ctx, ctx.MkReal("-234234333")); BigIntCheck(ctx, ctx.MkReal("234234333/2")); string bn = "1234567890987654321"; if (ctx.MkInt(bn).BigInteger.ToString() != bn) throw new TestFailedException(); if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) throw new TestFailedException(); if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) throw new TestFailedException(); // Error handling test. try { IntExpr i = ctx.MkInt("1/2"); throw new TestFailedException(); // unreachable } catch (Z3Exception) { } }
/// <summary> /// Prove that <tt>f(x, y) = f(w, v) implies y = v</tt> when /// <code>f</code> is injective in the second argument. <seealso cref="inj_axiom"/> /// </summary> public static void QuantifierExample4(Context ctx) { Console.WriteLine("QuantifierExample4"); /* If quantified formulas are asserted in a logical context, then the model produced by Z3 should be viewed as a potential model. */ /* declare function f */ Sort I = ctx.IntSort; FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); /* f is injective in the second argument. */ BoolExpr inj = InjAxiomAbs(ctx, f, 1); /* create x, y, v, w, fxy, fwv */ Expr x = ctx.MkIntConst("x"); Expr y = ctx.MkIntConst("y"); Expr v = ctx.MkIntConst("v"); Expr w = ctx.MkIntConst("w"); Expr fxy = ctx.MkApp(f, x, y); Expr fwv = ctx.MkApp(f, w, v); /* f(x, y) = f(w, v) */ BoolExpr p1 = ctx.MkEq(fxy, fwv); /* prove f(x, y) = f(w, v) implies y = v */ BoolExpr p2 = ctx.MkEq(y, v); Prove(ctx, p2, false, inj, p1); /* disprove f(x, y) = f(w, v) implies x = w */ BoolExpr p3 = ctx.MkEq(x, w); Disprove(ctx, p3, false, inj, p1); }
static void QuantifierExample2(Context ctx) { Console.WriteLine("QuantifierExample2"); Expr q1, q2; FuncDecl f = ctx.MkFuncDecl("f", ctx.IntSort, ctx.IntSort); FuncDecl g = ctx.MkFuncDecl("g", ctx.IntSort, ctx.IntSort); // Quantifier with Exprs as the bound variables. { Expr x = ctx.MkConst("x", ctx.IntSort); Expr y = ctx.MkConst("y", ctx.IntSort); Expr f_x = ctx.MkApp(f, x); Expr f_y = ctx.MkApp(f, y); Expr g_y = ctx.MkApp(g, y); Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, g_y }) }; Expr[] no_pats = new Expr[] { f_y }; Expr[] bound = new Expr[2] { x, y }; Expr body = ctx.MkAnd(ctx.MkEq(f_x, f_y), ctx.MkEq(f_y, g_y)); q1 = ctx.MkForall(bound, body, 1, null, no_pats, ctx.MkSymbol("q"), ctx.MkSymbol("sk")); Console.WriteLine("{0}", q1); } // Quantifier with de-Brujin indices. { Expr x = ctx.MkBound(1, ctx.IntSort); Expr y = ctx.MkBound(0, ctx.IntSort); Expr f_x = ctx.MkApp(f, x); Expr f_y = ctx.MkApp(f, y); Expr g_y = ctx.MkApp(g, y); Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, g_y }) }; Expr[] no_pats = new Expr[] { f_y }; Symbol[] names = new Symbol[] { ctx.MkSymbol("x"), ctx.MkSymbol("y") }; Sort[] sorts = new Sort[] { ctx.IntSort, ctx.IntSort }; Expr body = ctx.MkAnd(ctx.MkEq(f_x, f_y), ctx.MkEq(f_y, g_y)); q2 = ctx.MkForall(sorts, names, body, 1, null, // pats, no_pats, ctx.MkSymbol("q"), ctx.MkSymbol("sk") ); Console.WriteLine("{0}", q2); } Console.WriteLine("{0}", (q1.Equals(q2))); }
/// <summary> /// A simple array example. /// </summary> /// <param name="ctx"></param> static void ArrayExample1(Context ctx) { Console.WriteLine("ArrayExample1"); Goal g = ctx.MkGoal(true); ArraySort asort = ctx.MkArraySort(ctx.IntSort, ctx.MkBitVecSort(32)); ArrayExpr aex = (ArrayExpr)ctx.MkConst(ctx.MkSymbol("MyArray"), asort); Expr sel = ctx.MkSelect(aex, ctx.MkInt(0)); g.Assert(ctx.MkEq(sel, ctx.MkBV(42, 32))); Symbol xs = ctx.MkSymbol("x"); IntExpr xc = (IntExpr)ctx.MkConst(xs, ctx.IntSort); Symbol fname = ctx.MkSymbol("f"); Sort[] domain = { ctx.IntSort }; FuncDecl fd = ctx.MkFuncDecl(fname, domain, ctx.IntSort); Expr[] fargs = { ctx.MkConst(xs, ctx.IntSort) }; IntExpr fapp = (IntExpr)ctx.MkApp(fd, fargs); g.Assert(ctx.MkEq(ctx.MkAdd(xc, fapp), ctx.MkInt(123))); Solver s = ctx.MkSolver(); foreach (BoolExpr a in g.Formulas) s.Assert(a); Console.WriteLine("Solver: " + s); Status q = s.Check(); Console.WriteLine("Status: " + q); if (q != Status.SATISFIABLE) throw new TestFailedException(); Console.WriteLine("Model = " + s.Model); Console.WriteLine("Interpretation of MyArray:\n" + s.Model.FuncInterp(aex.FuncDecl)); Console.WriteLine("Interpretation of x:\n" + s.Model.ConstInterp(xc)); Console.WriteLine("Interpretation of f:\n" + s.Model.FuncInterp(fd)); Console.WriteLine("Interpretation of MyArray as Term:\n" + s.Model.FuncInterp(aex.FuncDecl)); }
/// <summary> /// Demonstrate how to use #Eval on tuples. /// </summary> public static void EvalExample2(Context ctx) { Console.WriteLine("EvalExample2"); Sort int_type = ctx.IntSort; TupleSort tuple = ctx.MkTupleSort( ctx.MkSymbol("mk_tuple"), // name of tuple constructor new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names of projection operators new Sort[] { int_type, int_type } // types of projection operators ); FuncDecl first = tuple.FieldDecls[0]; // declarations are for projections FuncDecl second = tuple.FieldDecls[1]; Expr tup1 = ctx.MkConst("t1", tuple); Expr tup2 = ctx.MkConst("t2", tuple); Solver solver = ctx.MkSolver(); /* assert tup1 != tup2 */ solver.Assert(ctx.MkNot(ctx.MkEq(tup1, tup2))); /* assert first tup1 = first tup2 */ solver.Assert(ctx.MkEq(ctx.MkApp(first, tup1), ctx.MkApp(first, tup2))); /* find model for the constraints above */ Model model = null; if (Status.SATISFIABLE == solver.Check()) { model = solver.Model; Console.WriteLine("{0}", model); Console.WriteLine("evaluating tup1 {0}", (model.Evaluate(tup1))); Console.WriteLine("evaluating tup2 {0}", (model.Evaluate(tup2))); Console.WriteLine("evaluating second(tup2) {0}", (model.Evaluate(ctx.MkApp(second, tup2)))); } else { Console.WriteLine("BUG, the constraints are satisfiable."); } }
/// <summary> /// Create a forest of trees. /// </summary> /// <remarks> /// forest ::= nil | cons(tree, forest) /// tree ::= nil | cons(forest, forest) /// </remarks> public static void ForestExample(Context ctx) { Console.WriteLine("ForestExample"); Sort tree, forest; FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; Expr nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; // // Declare the names of the accessors for cons. // Then declare the sorts of the accessors. // For this example, all sorts refer to the new types 'forest' and 'tree' // being declared, so we pass in null for both sorts1 and sorts2. // On the other hand, the sort_refs arrays contain the indices of the // two new sorts being declared. The first element in sort1_refs // points to 'tree', which has index 1, the second element in sort1_refs array // points to 'forest', which has index 0. // Symbol[] head_tail1 = new Symbol[] { ctx.MkSymbol("head"), ctx.MkSymbol("tail") }; Sort[] sorts1 = new Sort[] { null, null }; uint[] sort1_refs = new uint[] { 1, 0 }; // the first item points to a tree, the second to a forest Symbol[] head_tail2 = new Symbol[] { ctx.MkSymbol("car"), ctx.MkSymbol("cdr") }; Sort[] sorts2 = new Sort[] { null, null }; uint[] sort2_refs = new uint[] { 0, 0 }; // both items point to the forest datatype. Constructor nil1_con, cons1_con, nil2_con, cons2_con; Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; Symbol[] sort_names = { ctx.MkSymbol("forest"), ctx.MkSymbol("tree") }; /* build a forest */ nil1_con = ctx.MkConstructor(ctx.MkSymbol("nil"), ctx.MkSymbol("is_nil"), null, null, null); cons1_con = ctx.MkConstructor(ctx.MkSymbol("cons1"), ctx.MkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); constructors1[0] = nil1_con; constructors1[1] = cons1_con; /* build a tree */ nil2_con = ctx.MkConstructor(ctx.MkSymbol("nil2"), ctx.MkSymbol("is_nil2"), null, null, null); cons2_con = ctx.MkConstructor(ctx.MkSymbol("cons2"), ctx.MkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); constructors2[0] = nil2_con; constructors2[1] = cons2_con; Constructor[][] clists = new Constructor[][] { constructors1, constructors2 }; Sort[] sorts = ctx.MkDatatypeSorts(sort_names, clists); forest = sorts[0]; tree = sorts[1]; // // Now that the datatype has been created. // Query the constructors for the constructor // functions, testers, and field accessors. // nil1_decl = nil1_con.ConstructorDecl; is_nil1_decl = nil1_con.TesterDecl; cons1_decl = cons1_con.ConstructorDecl; is_cons1_decl = cons1_con.TesterDecl; FuncDecl[] cons1_accessors = cons1_con.AccessorDecls; car1_decl = cons1_accessors[0]; cdr1_decl = cons1_accessors[1]; nil2_decl = nil2_con.ConstructorDecl; is_nil2_decl = nil2_con.TesterDecl; cons2_decl = cons2_con.ConstructorDecl; is_cons2_decl = cons2_con.TesterDecl; FuncDecl[] cons2_accessors = cons2_con.AccessorDecls; car2_decl = cons2_accessors[0]; cdr2_decl = cons2_accessors[1]; nil1 = ctx.MkConst(nil1_decl); nil2 = ctx.MkConst(nil2_decl); f1 = ctx.MkApp(cons1_decl, nil2, nil1); t1 = ctx.MkApp(cons2_decl, nil1, nil1); t2 = ctx.MkApp(cons2_decl, f1, nil1); t3 = ctx.MkApp(cons2_decl, f1, f1); t4 = ctx.MkApp(cons2_decl, nil1, f1); f2 = ctx.MkApp(cons1_decl, t1, nil1); f3 = ctx.MkApp(cons1_decl, t1, f1); /* nil != cons(nil,nil) */ Prove(ctx, ctx.MkNot(ctx.MkEq(nil1, f1))); Prove(ctx, ctx.MkNot(ctx.MkEq(nil2, t1))); /* cons(x,u) = cons(x, v) => u = v */ u = ctx.MkConst("u", forest); v = ctx.MkConst("v", forest); x = ctx.MkConst("x", tree); y = ctx.MkConst("y", tree); l1 = ctx.MkApp(cons1_decl, x, u); l2 = ctx.MkApp(cons1_decl, y, v); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); /* is_nil(u) or is_cons(u) */ Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(is_nil1_decl, u), (BoolExpr)ctx.MkApp(is_cons1_decl, u))); /* occurs check u != cons(x,u) */ Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); }
/// <summary> /// Create a binary tree datatype. /// </summary> public static void TreeExample(Context ctx) { Console.WriteLine("TreeExample"); Sort cell; FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; Expr nil, l1, l2, x, y, u, v; BoolExpr fml, fml1; string[] head_tail = new string[] { "car", "cdr" }; Sort[] sorts = new Sort[] { null, null }; uint[] sort_refs = new uint[] { 0, 0 }; Constructor nil_con, cons_con; nil_con = ctx.MkConstructor("nil", "is_nil", null, null, null); cons_con = ctx.MkConstructor("cons", "is_cons", head_tail, sorts, sort_refs); Constructor[] constructors = new Constructor[] { nil_con, cons_con }; cell = ctx.MkDatatypeSort("cell", constructors); nil_decl = nil_con.ConstructorDecl; is_nil_decl = nil_con.TesterDecl; cons_decl = cons_con.ConstructorDecl; is_cons_decl = cons_con.TesterDecl; FuncDecl[] cons_accessors = cons_con.AccessorDecls; car_decl = cons_accessors[0]; cdr_decl = cons_accessors[1]; nil = ctx.MkConst(nil_decl); l1 = ctx.MkApp(cons_decl, nil, nil); l2 = ctx.MkApp(cons_decl, l1, nil); /* nil != cons(nil, nil) */ Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1))); /* cons(x,u) = cons(x, v) => u = v */ u = ctx.MkConst("u", cell); v = ctx.MkConst("v", cell); x = ctx.MkConst("x", cell); y = ctx.MkConst("y", cell); l1 = ctx.MkApp(cons_decl, x, u); l2 = ctx.MkApp(cons_decl, y, v); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); /* is_nil(u) or is_cons(u) */ Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(is_nil_decl, u), (BoolExpr)ctx.MkApp(is_cons_decl, u))); /* occurs check u != cons(x,u) */ Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ fml1 = ctx.MkEq(u, ctx.MkApp(cons_decl, ctx.MkApp(car_decl, u), ctx.MkApp(cdr_decl, u))); fml = ctx.MkImplies((BoolExpr)ctx.MkApp(is_cons_decl, u), fml1); Console.WriteLine("Formula {0}", fml); Prove(ctx, fml); Disprove(ctx, fml1); }
/// <summary> /// Create a list datatype. /// </summary> public static void ListExample(Context ctx) { Console.WriteLine("ListExample"); Sort int_ty; ListSort int_list; Expr nil, l1, l2, x, y, u, v; BoolExpr fml, fml1; int_ty = ctx.MkIntSort(); int_list = ctx.MkListSort(ctx.MkSymbol("int_list"), int_ty); nil = ctx.MkConst(int_list.NilDecl); l1 = ctx.MkApp(int_list.ConsDecl, ctx.MkInt(1), nil); l2 = ctx.MkApp(int_list.ConsDecl, ctx.MkInt(2), nil); /* nil != cons(1, nil) */ Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1))); /* cons(2,nil) != cons(1, nil) */ Prove(ctx, ctx.MkNot(ctx.MkEq(l1, l2))); /* cons(x,nil) = cons(y, nil) => x = y */ x = ctx.MkConst("x", int_ty); y = ctx.MkConst("y", int_ty); l1 = ctx.MkApp(int_list.ConsDecl, x, nil); l2 = ctx.MkApp(int_list.ConsDecl, y, nil); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); /* cons(x,u) = cons(x, v) => u = v */ u = ctx.MkConst("u", int_list); v = ctx.MkConst("v", int_list); l1 = ctx.MkApp(int_list.ConsDecl, x, u); l2 = ctx.MkApp(int_list.ConsDecl, y, v); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); /* is_nil(u) or is_cons(u) */ Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(int_list.IsNilDecl, u), (BoolExpr)ctx.MkApp(int_list.IsConsDecl, u))); /* occurs check u != cons(x,u) */ Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ fml1 = ctx.MkEq(u, ctx.MkApp(int_list.ConsDecl, ctx.MkApp(int_list.HeadDecl, u), ctx.MkApp(int_list.TailDecl, u))); fml = ctx.MkImplies((BoolExpr)ctx.MkApp(int_list.IsConsDecl, u), fml1); Console.WriteLine("Formula {0}", fml); Prove(ctx, fml); Disprove(ctx, fml1); }
/// <summary> /// Create an enumeration data type. /// </summary> public static void EnumExample(Context ctx) { Console.WriteLine("EnumExample"); Symbol name = ctx.MkSymbol("fruit"); EnumSort fruit = ctx.MkEnumSort(ctx.MkSymbol("fruit"), new Symbol[] { ctx.MkSymbol("apple"), ctx.MkSymbol("banana"), ctx.MkSymbol("orange") }); Console.WriteLine("{0}", (fruit.Consts[0])); Console.WriteLine("{0}", (fruit.Consts[1])); Console.WriteLine("{0}", (fruit.Consts[2])); Console.WriteLine("{0}", (fruit.TesterDecls[0])); Console.WriteLine("{0}", (fruit.TesterDecls[1])); Console.WriteLine("{0}", (fruit.TesterDecls[2])); Expr apple = fruit.Consts[0]; Expr banana = fruit.Consts[1]; Expr orange = fruit.Consts[2]; /* Apples are different from oranges */ Prove(ctx, ctx.MkNot(ctx.MkEq(apple, orange))); /* Apples pass the apple test */ Prove(ctx, (BoolExpr)ctx.MkApp(fruit.TesterDecls[0], apple)); /* Oranges fail the apple test */ Disprove(ctx, (BoolExpr)ctx.MkApp(fruit.TesterDecls[0], orange)); Prove(ctx, (BoolExpr)ctx.MkNot((BoolExpr)ctx.MkApp(fruit.TesterDecls[0], orange))); Expr fruity = ctx.MkConst("fruity", fruit); /* If something is fruity, then it is an apple, banana, or orange */ Prove(ctx, ctx.MkOr(new BoolExpr[] { ctx.MkEq(fruity, apple), ctx.MkEq(fruity, banana), ctx.MkEq(fruity, orange) })); }
/// <summary> /// Prove that <tt>f(x, y) = f(w, v) implies y = v</tt> when /// <code>f</code> is injective in the second argument. <seealso cref="inj_axiom"/> /// </summary> public static void QuantifierExample3() { Console.WriteLine("QuantifierExample3"); Dictionary<string, string> cfg = new Dictionary<string, string>() { { "MBQI", "false" }, { "PROOF_MODE", "2" }, { "AUTO_CONFIG", "false" } }; /* If quantified formulas are asserted in a logical context, then the model produced by Z3 should be viewed as a potential model. */ using (Context ctx = new Context(cfg)) { /* declare function f */ Sort I = ctx.IntSort; FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); /* f is injective in the second argument. */ BoolExpr inj = InjAxiom(ctx, f, 1); /* create x, y, v, w, fxy, fwv */ Expr x = ctx.MkIntConst("x"); Expr y = ctx.MkIntConst("y"); Expr v = ctx.MkIntConst("v"); Expr w = ctx.MkIntConst("w"); Expr fxy = ctx.MkApp(f, x, y); Expr fwv = ctx.MkApp(f, w, v); /* f(x, y) = f(w, v) */ BoolExpr p1 = ctx.MkEq(fxy, fwv); /* prove f(x, y) = f(w, v) implies y = v */ BoolExpr p2 = ctx.MkEq(y, v); Prove(ctx, p2, inj, p1); /* disprove f(x, y) = f(w, v) implies x = w */ BoolExpr p3 = ctx.MkEq(x, w); Disprove(ctx, p3, inj, p1); } }
// CMW: get_implied_equalities is deprecated. ///*! // \brief Extract implied equalities. //*/ public void get_implied_equalities_example() { if (this.z3 != null) { this.z3.Dispose(); } Config p = new Config(); p.SetParam("ARITH_EQ_BOUNDS","true"); this.z3 = new Context(p); Sort int_sort = z3.MkIntSort(); Expr a = mk_int_var("a"); Expr b = mk_int_var("b"); Expr c = mk_int_var("c"); Expr d = mk_int_var("d"); FuncDecl f = z3.MkFuncDecl("f", int_sort, int_sort); Expr fa = z3.MkApp(f,a); Expr fb = z3.MkApp(f,b); Expr fc = z3.MkApp(f,c); Expr[] Exprs = new Expr[]{ a, b, c, d, fa, fb, fc }; uint[] class_ids; solver.Assert(z3.MkEq(a, b)); solver.Assert(z3.MkEq(b, c)); solver.Assert(z3.MkLe((ArithExpr)fc, (ArithExpr)a)); solver.Assert(z3.MkLe((ArithExpr)b, (ArithExpr)fb)); int num_Exprs = Exprs.Length; z3.GetImpliedEqualities(Exprs, out class_ids); for (int i = 0; i < num_Exprs; ++i) { Console.WriteLine("Class {0} |-> {1}", Exprs[i], class_ids[i]); } }