Exemple #1
0
 internal DatatypeSort(Context ctx, Symbol name, Constructor[] constructors)
     : base(ctx, Native.Z3_mk_datatype(ctx.nCtx, name.NativeObject, (uint)constructors.Length, ArrayToNative(constructors)))
 {
     Contract.Requires(ctx != null);
     Contract.Requires(name != null);
     Contract.Requires(constructors != null);
 }
        internal ConstructorList(Context ctx, Constructor[] constructors)
            : base(ctx)
        {
            Contract.Requires(ctx != null);
            Contract.Requires(constructors != null);

            NativeObject = Native.Z3_mk_constructor_list(Context.nCtx, (uint)constructors.Length, Constructor.ArrayToNative(constructors));
        }
Exemple #3
0
        /// <summary>
        ///  Create mutually recursive data-types.
        /// </summary>
        /// <param name="names"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public DatatypeSort[] MkDatatypeSorts(string[] names, Constructor[][] c)
        {
            Contract.Requires(names != null);
            Contract.Requires(c != null);
            Contract.Requires(names.Length == c.Length);
            Contract.Requires(Contract.ForAll(0, c.Length, j => c[j] != null));
            Contract.Requires(Contract.ForAll(names, name => name != null));
            Contract.Ensures(Contract.Result<DatatypeSort[]>() != null);

            return MkDatatypeSorts(MkSymbols(names), c);
        }
Exemple #4
0
        /// <summary>
        /// Create mutually recursive datatypes.
        /// </summary>
        /// <param name="names">names of datatype sorts</param>
        /// <param name="c">list of constructors, one list per sort.</param>
        public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c)
        {
            Contract.Requires(names != null);
            Contract.Requires(c != null);
            Contract.Requires(names.Length == c.Length);
            Contract.Requires(Contract.ForAll(0, c.Length, j => c[j] != null));
            Contract.Requires(Contract.ForAll(names, name => name != null));
            Contract.Ensures(Contract.Result<DatatypeSort[]>() != null);

            CheckContextMatch(names);
            uint n = (uint)names.Length;
            ConstructorList[] cla = new ConstructorList[n];
            IntPtr[] n_constr = new IntPtr[n];
            for (uint i = 0; i < n; i++)
            {
                Constructor[] constructor = c[i];
                Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays");
                CheckContextMatch(constructor);
                cla[i] = new ConstructorList(this, constructor);
                n_constr[i] = cla[i].NativeObject;
            }
            IntPtr[] n_res = new IntPtr[n];
            Native.Z3_mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr);
            DatatypeSort[] res = new DatatypeSort[n];
            for (uint i = 0; i < n; i++)
                res[i] = new DatatypeSort(this, n_res[i]);
            return res;
        }
Exemple #5
0
        /// <summary>
        /// Create a new datatype sort.
        /// </summary>
        public DatatypeSort MkDatatypeSort(string name, Constructor[] constructors)
        {
            Contract.Requires(constructors != null);
            Contract.Requires(Contract.ForAll(constructors, c => c != null));
            Contract.Ensures(Contract.Result<DatatypeSort>() != null);

            CheckContextMatch(constructors);
            return new DatatypeSort(this, MkSymbol(name), constructors);
        }
Exemple #6
0
        /// <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)));
        }
Exemple #7
0
        /// <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);
        }
        internal ConstructorList(Context ctx, Constructor[] constructors)
            : base(ctx)
        {
            Contract.Requires(ctx != null);
            Contract.Requires(constructors != null);

            NativeObject = Native.Z3_mk_constructor_list(Context.nCtx, (uint)constructors.Length, Constructor.ArrayToNative(constructors));
        }