public void Run() { Dictionary<string, string> cfg = new Dictionary<string, string>() { }; using (Context ctx = new Context(cfg)) { FuncDecl f = ctx.MkFuncDecl("f", ctx.IntSort, ctx.IntSort); FuncDecl g = ctx.MkFuncDecl("g", ctx.IntSort, ctx.IntSort); IntExpr a = ctx.MkIntConst("a"); IntExpr b = ctx.MkIntConst("b"); IntExpr c = ctx.MkIntConst("c"); IntExpr x = ctx.MkIntConst("x"); Solver s = ctx.MkSolver(); Params p = ctx.MkParams(); p.Add("AUTO_CONFIG", false); p.Add("MBQI", false); s.Parameters = p; s.Assert(ctx.MkForall(new Expr[] { x }, ctx.MkEq(f[g[x]], x), 1, new Pattern[] { ctx.MkPattern(f[g[x]]) })); s.Assert(ctx.MkEq(a, g[b])); s.Assert(ctx.MkEq(b, c)); s.Assert(ctx.MkDistinct(f[a], c)); Console.WriteLine(s); Console.WriteLine(s.Check()); } }
public void Run() { Dictionary<string, string> cfg = new Dictionary<string, string>() { { "AUTO_CONFIG", "true" } }; using (Context ctx = new Context(cfg)) { Sort A = ctx.MkUninterpretedSort("A"); Sort B = ctx.MkUninterpretedSort("B"); FuncDecl f = ctx.MkFuncDecl("f", A, B); Expr a1 = ctx.MkConst("a1", A); Expr a2 = ctx.MkConst("a2", A); Expr b = ctx.MkConst("b", B); Expr x = ctx.MkConst("x", A); Expr y = ctx.MkConst("y", A); Solver s = ctx.MkSolver(); s.Assert(ctx.MkNot(ctx.MkEq(a1, a2))); s.Assert(ctx.MkEq(f[a1], b)); s.Assert(ctx.MkEq(f[a2], b)); s.Assert(ctx.MkForall(new Expr[] { x, y }, ctx.MkImplies(ctx.MkEq(f[x], f[y]), ctx.MkEq(x, y)), 1, new Pattern[] { ctx.MkPattern(f[x], f[y]) })); Console.WriteLine(s); Console.WriteLine(s.Check()); } }
/// <summary> /// Create axiom: function f is injective in the i-th argument. /// </summary> /// <remarks> /// The following axiom is produced: /// <c> /// forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i /// </c> /// Where, <code>finv</code>is a fresh function declaration. /// </summary> public static BoolExpr InjAxiom(Context ctx, FuncDecl f, int i) { Sort[] domain = f.Domain; uint sz = f.DomainSize; if (i >= sz) { Console.WriteLine("failed to create inj axiom"); return null; } /* declare the i-th inverse of f: finv */ Sort finv_domain = f.Range; Sort finv_range = domain[i]; FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); /* allocate temporary arrays */ Expr[] xs = new Expr[sz]; Symbol[] names = new Symbol[sz]; Sort[] types = new Sort[sz]; /* fill types, names and xs */ for (uint j = 0; j < sz; j++) { types[j] = domain[j]; names[j] = ctx.MkSymbol(String.Format("x_{0}", j)); xs[j] = ctx.MkBound(j, types[j]); } Expr x_i = xs[i]; /* create f(x_0, ..., x_i, ..., x_{n-1}) */ Expr fxs = f[xs]; /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ Expr finv_fxs = finv[fxs]; /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ Expr eq = ctx.MkEq(finv_fxs, x_i); /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ Pattern p = ctx.MkPattern(new Expr[] { fxs }); /* create & assert quantifier */ BoolExpr q = ctx.MkForall( types, /* types of quantified variables */ names, /* names of quantified variables */ eq, 1, new Pattern[] { p } /* patterns */); return q; }
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))); }