public MkDatatypeSorts ( |
||
names | names of datatype sorts | |
c | Microsoft.Z3.Constructor | list of constructors, one list per sort. |
리턴 | Microsoft.Z3.DatatypeSort[] |
public void Run() { Dictionary<string, string> cfg = new Dictionary<string, string>() { { "AUTO_CONFIG", "true" }, { "MODEL", "true" } }; using (Context ctx = new Context(cfg)) { Constructor c_leaf = ctx.MkConstructor("leaf", "is_leaf", new string[] { "val" }, new Sort[] { ctx.IntSort }); Constructor c_node = ctx.MkConstructor("node", "is_node", new string[] { "left", "right" }, new Sort[] { null, null }, new uint[] { 1, 1 }); Constructor[] constr_1 = new Constructor[] { c_leaf, c_node }; Constructor c_nil = ctx.MkConstructor("nil", "is_nil"); Constructor c_cons = ctx.MkConstructor("cons", "is_cons", new string[] { "car", "cdr" }, new Sort[] { null, null }, new uint[] { 0, 1 }); Constructor[] constr_2 = new Constructor[] { c_nil, c_cons }; DatatypeSort[] ts = ctx.MkDatatypeSorts(new string[] { "Tree", "TreeList" }, new Constructor[][] { constr_1, constr_2 }); DatatypeSort Tree = ts[0]; DatatypeSort TreeList = ts[1]; FuncDecl leaf = Tree.Constructors[0]; FuncDecl node = Tree.Constructors[1]; FuncDecl val = Tree.Accessors[0][0]; FuncDecl nil = TreeList.Constructors[0]; FuncDecl cons = TreeList.Constructors[1]; Expr t1 = leaf[ctx.MkInt(10)]; Expr tl1 = cons[t1, nil.Apply()]; Expr t2 = node[tl1, nil.Apply()]; Console.WriteLine(t2); Console.WriteLine(val.Apply(t1).Simplify()); t1 = ctx.MkConst("t1", TreeList); t2 = ctx.MkConst("t2", TreeList); Expr t3 = ctx.MkConst("t3", TreeList); Solver s = ctx.MkSolver(); s.Assert(ctx.MkDistinct(t1, t2, t3)); Console.WriteLine(s.Check()); Console.WriteLine(s.Model); } }
/// <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))); }