Bit-vector expressions
Inheritance: Expr
Esempio n. 1
0
    public void Run()
    {
        Dictionary<string, string> cfg = new Dictionary<string, string>() {
            { "AUTO_CONFIG", "true" } };

        using (Context ctx = new Context(cfg))
        {
            BitVecExpr x = ctx.MkBVConst("x", 32);
            BitVecExpr[] powers = new BitVecExpr[32];
            for (uint i = 0; i < 32; i++)
                powers[i] = ctx.MkBVSHL(ctx.MkBV(1, 32), ctx.MkBV(i, 32));

            BoolExpr step_zero = ctx.MkEq(ctx.MkBVAND(x, ctx.MkBVSub(x, ctx.MkBV(1, 32))), ctx.MkBV(0, 32));

            BoolExpr fast = ctx.MkAnd(ctx.MkNot(ctx.MkEq(x, ctx.MkBV(0, 32))),
                                      step_zero);

            BoolExpr slow = ctx.MkFalse();
            foreach (BitVecExpr p in powers)
                slow = ctx.MkOr(slow, ctx.MkEq(x, p));

        TestDriver.CheckString(fast, "(and (not (= x #x00000000)) (= (bvand x (bvsub x #x00000001)) #x00000000))");

            Solver s = ctx.MkSolver();
            s.Assert(ctx.MkNot(ctx.MkEq(fast, slow)));
            TestDriver.CheckUNSAT(s.Check());

            s = ctx.MkSolver();
            s.Assert(ctx.MkNot(step_zero));
            TestDriver.CheckSAT(s.Check());
        }
    }
Esempio n. 2
0
        /// <summary>
        /// Arithmetic shift right
        /// </summary>
        /// <remarks>
        /// It is like logical shift right except that the most significant
        /// bits of the result always copy the most significant bit of the
        /// second argument.
        /// 
        /// NB. The semantics of shift operations varies between environments. This 
        /// definition does not necessarily capture directly the semantics of the 
        /// programming language or assembly architecture you are modeling.
        /// 
        /// The arguments must have a bit-vector sort.
        /// </remarks>
        public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2)
        {
            Contract.Requires(t1 != null);
            Contract.Requires(t2 != null);
            Contract.Ensures(Contract.Result<BitVecExpr>() != null);

            CheckContextMatch(t1);
            CheckContextMatch(t2);
            return new BitVecExpr(this, Native.Z3_mk_bvashr(nCtx, t1.NativeObject, t2.NativeObject));
        }
Esempio n. 3
0
        /// <summary>
        /// Create a predicate that checks that the bit-wise addition does not underflow.
        /// </summary>
        /// <remarks>
        /// The arguments must be of bit-vector sort.
        /// </remarks>
        public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2)
        {
            Contract.Requires(t1 != null);
            Contract.Requires(t2 != null);
            Contract.Ensures(Contract.Result<BoolExpr>() != null);

            CheckContextMatch(t1);
            CheckContextMatch(t2);
            return new BoolExpr(this, Native.Z3_mk_bvadd_no_underflow(nCtx, t1.NativeObject, t2.NativeObject));
        }
Esempio n. 4
0
        /// <summary>
        /// Create an integer from the bit-vector argument <paramref name="t"/>.
        /// </summary>
        /// <remarks>
        /// If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. 
        /// So the result is non-negative and in the range <c>[0..2^N-1]</c>, where 
        /// N are the number of bits in <paramref name="t"/>.
        /// If \c is_signed is true, \c t1 is treated as a signed bit-vector.
        ///
        /// NB. This function is essentially treated as uninterpreted. 
        /// So you cannot expect Z3 to precisely reflect the semantics of this function
        /// when solving constraints with this function.
        /// 
        /// The argument must be of bit-vector sort.
        /// </remarks>
        public IntExpr MkBV2Int(BitVecExpr t, bool signed)
        {
            Contract.Requires(t != null);
            Contract.Ensures(Contract.Result<IntExpr>() != null);

            CheckContextMatch(t);
            return new IntExpr(this, Native.Z3_mk_bv2int(nCtx, t.NativeObject, (signed) ? 1 : 0));
        }
Esempio n. 5
0
        /// <summary>
        /// Bit-vector zero extension.
        /// </summary>
        /// <remarks>    
        /// Extend the given bit-vector with zeros to the (unsigned) equivalent
        /// bitvector of size <c>m+i</c>, where \c m is the size of the
        /// given bit-vector.
        /// The argument <paramref name="t"/> must have a bit-vector sort.
        /// </remarks>
        public BitVecExpr MkZeroExt(uint i, BitVecExpr t)
        {
            Contract.Requires(t != null);
            Contract.Ensures(Contract.Result<BitVecExpr>() != null);

            CheckContextMatch(t);
            return new BitVecExpr(this, Native.Z3_mk_zero_ext(nCtx, i, t.NativeObject));
        }
Esempio n. 6
0
        /// <summary>
        /// Bit-vector extraction.
        /// </summary>
        /// <remarks>    
        /// Extract the bits <paramref name="high"/> down to <paramref name="low"/> from a bitvector of
        /// size <c>m</c> to yield a new bitvector of size <c>n</c>, where 
        /// <c>n = high - low + 1</c>.
        /// The argument <paramref name="t"/> must have a bit-vector sort.
        /// </remarks>
        public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t)
        {
            Contract.Requires(t != null);
            Contract.Ensures(Contract.Result<BitVecExpr>() != null);

            CheckContextMatch(t);
            return new BitVecExpr(this, Native.Z3_mk_extract(nCtx, high, low, t.NativeObject));
        }
Esempio n. 7
0
        /// <summary>
        /// Create a predicate that checks that the bit-wise subtraction does not underflow.
        /// </summary>
        /// <remarks>
        /// The arguments must be of bit-vector sort.
        /// </remarks>
        public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned)
        {
            Contract.Requires(t1 != null);
            Contract.Requires(t2 != null);
            Contract.Ensures(Contract.Result<BoolExpr>() != null);

            CheckContextMatch(t1);
            CheckContextMatch(t2);
            return new BoolExpr(this, Native.Z3_mk_bvsub_no_underflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0));
        }
Esempio n. 8
0
        /// <summary>
        /// Take disjunction of bits in a vector, return vector of length 1.
        /// </summary>
        /// <remarks>The argument must have a bit-vector sort.</remarks>
        public BitVecExpr MkBVRedOR(BitVecExpr t)
        {
            Contract.Requires(t != null);
            Contract.Ensures(Contract.Result<BitVecExpr>() != null);

            CheckContextMatch(t);
            return new BitVecExpr(this, Native.Z3_mk_bvredor(nCtx, t.NativeObject));
        }
Esempio n. 9
0
        /// <summary>
        /// Create a predicate that checks that the bit-wise negation does not overflow.
        /// </summary>
        /// <remarks>
        /// The arguments must be of bit-vector sort.
        /// </remarks>
        public BoolExpr MkBVNegNoOverflow(BitVecExpr t)
        {
            Contract.Requires(t != null);
            Contract.Ensures(Contract.Result<BoolExpr>() != null);

            CheckContextMatch(t);
            return new BoolExpr(this, Native.Z3_mk_bvneg_no_overflow(nCtx, t.NativeObject));
        }
Esempio n. 10
0
 /// <summary>
 /// Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort.
 /// </summary>
 /// <remarks>
 /// Produces a term that represents the conversion of the bit-vector term t into a
 /// floating-point term of sort s. The bit-vector t is taken to be in signed 
 /// 2's complement format (when signed==true, otherwise unsigned). If necessary, the 
 /// result will be rounded according to rounding mode rm.
 /// </remarks>
 /// <param name="rm">RoundingMode term.</param>
 /// <param name="t">term of bit-vector sort.</param>
 /// <param name="s">FloatingPoint sort.</param>
 /// <param name="signed">flag indicating whether t is interpreted as signed or unsigned bit-vector.</param>
 public FPExpr MkFPToFP(FPRMExpr rm, BitVecExpr t, FPSort s, bool signed)
 {
     Contract.Ensures(Contract.Result<FPExpr>() != null);
     if (signed)
         return new FPExpr(this, Native.Z3_mk_fpa_to_fp_signed(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
     else
         return new FPExpr(this, Native.Z3_mk_fpa_to_fp_unsigned(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
 }
Esempio n. 11
0
 /// <summary>
 /// Conversion of a single IEEE 754-2008 bit-vector into a floating-point number.
 /// </summary>
 /// <remarks>
 /// Produces a term that represents the conversion of a bit-vector term bv to a 
 /// floating-point term of sort s. The bit-vector size of bv (m) must be equal 
 /// to ebits+sbits of s. The format of the bit-vector is as defined by the 
 /// IEEE 754-2008 interchange format.
 /// </remarks>
 /// <param name="bv">bit-vector value (of size m).</param>
 /// <param name="s">FloatingPoint sort (ebits+sbits == m)</param>
 public FPExpr MkFPToFP(BitVecExpr bv, FPSort s)
 {
     Contract.Ensures(Contract.Result<FPExpr>() != null);
     return new FPExpr(this, Native.Z3_mk_fpa_to_fp_bv(this.nCtx, bv.NativeObject, s.NativeObject));
 }
Esempio n. 12
0
 /// <summary>
 /// Create an expression of FloatingPoint sort from three bit-vector expressions.
 /// </summary>
 /// <remarks>
 /// This is the operator named `fp' in the SMT FP theory definition. 
 /// Note that sgn is required to be a bit-vector of size 1. Significand and exponent 
 /// are required to be greater than 1 and 2 respectively. The FloatingPoint sort 
 /// of the resulting expression is automatically determined from the bit-vector sizes
 /// of the arguments.
 /// </remarks>
 /// <param name="sgn">bit-vector term (of size 1) representing the sign.</param>
 /// <param name="sig">bit-vector term representing the significand.</param>
 /// <param name="exp">bit-vector term representing the exponent.</param>
 public FPExpr MkFP(BitVecExpr sgn, BitVecExpr sig, BitVecExpr exp)
 {
     Contract.Ensures(Contract.Result<FPExpr>() != null);
     return new FPExpr(this, Native.Z3_mk_fpa_fp(this.nCtx, sgn.NativeObject, sig.NativeObject, exp.NativeObject));
 }
Esempio n. 13
0
        /// <summary>
        /// Demonstrate how to use <code>Push</code>and <code>Pop</code>to
        /// control the size of models.
        /// </summary>
        /// <remarks>Note: this test is specialized to 32-bit bitvectors.</remarks>
        public static void CheckSmall(Context ctx, Solver solver, BitVecExpr[] to_minimize)
        {
            Sort bv32 = ctx.MkBitVecSort(32);

            int num_Exprs = to_minimize.Length;
            UInt32[] upper = new UInt32[num_Exprs];
            UInt32[] lower = new UInt32[num_Exprs];
            BitVecExpr[] values = new BitVecExpr[num_Exprs];
            for (int i = 0; i < upper.Length; ++i)
            {
                upper[i] = UInt32.MaxValue;
                lower[i] = 0;
            }
            bool some_work = true;
            int last_index = -1;
            UInt32 last_upper = 0;
            while (some_work)
            {
                solver.Push();

                bool check_is_sat = true;
                while (check_is_sat && some_work)
                {
                    // Assert all feasible bounds.
                    for (int i = 0; i < num_Exprs; ++i)
                    {
                        solver.Assert(ctx.MkBVULE(to_minimize[i], ctx.MkBV(upper[i], 32)));
                    }

                    check_is_sat = Status.SATISFIABLE == solver.Check();
                    if (!check_is_sat)
                    {
                        if (last_index != -1)
                        {
                            lower[last_index] = last_upper + 1;
                        }
                        break;
                    }
                    Console.WriteLine("{0}", solver.Model);

                    // narrow the bounds based on the current model.
                    for (int i = 0; i < num_Exprs; ++i)
                    {
                        Expr v = solver.Model.Evaluate(to_minimize[i]);
                        UInt64 ui = ((BitVecNum)v).UInt64;
                        if (ui < upper[i])
                        {
                            upper[i] = (UInt32)ui;
                        }
                        Console.WriteLine("{0} {1} {2}", i, lower[i], upper[i]);
                    }

                    // find a new bound to add
                    some_work = false;
                    last_index = 0;
                    for (int i = 0; i < num_Exprs; ++i)
                    {
                        if (lower[i] < upper[i])
                        {
                            last_upper = (upper[i] + lower[i]) / 2;
                            last_index = i;
                            solver.Assert(ctx.MkBVULE(to_minimize[i], ctx.MkBV(last_upper, 32)));
                            some_work = true;
                            break;
                        }
                    }
                }
                solver.Pop();
            }
        }
Esempio n. 14
0
 /// <summary>
 /// Translates an ASTVector into a BitVecExpr[]
 /// </summary>    
 public BitVecExpr[] ToBitVecExprArray()
 {
     uint n = Size;
     BitVecExpr[] res = new BitVecExpr[n];
     for (uint i = 0; i < n; i++)
         res[i] = (BitVecExpr)Expr.Create(this.Context, this[i].NativeObject);
     return res;
 }