示例#1
0
 public virtual Expr UFC(FunctionCall func, params Expr[] args)
 {
     return(UB.UFC(func, args));
 }
示例#2
0
        public void RemoveNoConstraintsBasedOnVarsAndFunctions()
        {
            IConstraintManager CM      = new ConstraintManager();
            IExprBuilder       builder = GetBuilder();

            // Dummy Boogie variable
            var bv8Type      = Microsoft.Boogie.Type.GetBvType(8);
            var bv8TypeIdent = new TypedIdent(Token.NoToken, "bv8", bv8Type);
            var dummyVarBv   = new GlobalVariable(Token.NoToken, bv8TypeIdent);

            // dummyVar needs a programLocation, otherwise SymbolicVariable constructor raises an exception
            var progLoc = new ProgramLocation(dummyVarBv);

            dummyVarBv.SetMetadata <ProgramLocation>((int)Symbooglix.Annotation.AnnotationIndex.PROGRAM_LOCATION, progLoc);

            var s0 = new SymbolicVariable("s0", dummyVarBv).Expr;
            var s1 = new SymbolicVariable("s1", dummyVarBv).Expr;
            var s2 = new SymbolicVariable("s2", dummyVarBv).Expr;

            // Construct some constraints
            Expr c0 = builder.Eq(builder.BVAND(s0, s1), builder.ConstantBV(0, 8));
            Expr c1 = builder.Eq(s2, builder.ConstantBV(1, 8));

            var FCB        = new FunctionCallBuilder();
            var foobarFunc = FCB.CreateUninterpretedFunctionCall("foobar", bv8Type, new List <Microsoft.Boogie.Type>()
            {
                bv8Type
            });
            // foobar(0bv8) == 0bv8
            Expr c2 = builder.Eq(builder.UFC(foobarFunc, builder.ConstantBV(0, 8)), builder.ConstantBV(0, 8));

            CM.AddConstraint(c0, progLoc);
            CM.AddConstraint(c1, progLoc);
            CM.AddConstraint(c2, progLoc);

            var mockSolver      = new MockSolver();
            var indepenceSolver = new Symbooglix.Solver.ConstraintIndependenceSolver(mockSolver);

            // The query expression uses the "foobar" function so we need to keep constraints on that function
            Expr queryExpr = builder.And(builder.Eq(builder.BVAND(s1, s2), builder.ConstantBV(0, 8)),
                                         builder.NotEq(builder.UFC(foobarFunc, s1), s1)
                                         );

            indepenceSolver.ComputeSatisfiability(new Solver.Query(CM, new Constraint(queryExpr)));

            // Check no constraints were removed
            Assert.AreEqual(3, mockSolver.Constraints.Count);
            Assert.AreSame(queryExpr, mockSolver.QueryExpr);

            bool c0Found = false;
            bool c1Found = false;
            bool c2Found = false;

            foreach (var constraint in mockSolver.Constraints)
            {
                if (c0 == constraint.Condition)
                {
                    c0Found = true;
                }

                if (c1 == constraint.Condition)
                {
                    c1Found = true;
                }

                if (c2 == constraint.Condition)
                {
                    c2Found = true;
                }
            }

            Assert.IsTrue(c0Found);
            Assert.IsTrue(c1Found);
            Assert.IsTrue(c2Found);
        }
示例#3
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            // Need to duplicate arguments first (doing post order traversal)
            var newArgs = new List <Expr>();

            foreach (var oldExpr in node.Args)
            {
                var newExpr = (Expr)this.Visit(oldExpr);
                newArgs.Add(newExpr);
            }

            // Now can finally duplicate this node now we've done our children

            if (node.Fun is FunctionCall)
            {
                var    FC        = (FunctionCall)node.Fun;
                string bvbuiltin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "bvbuiltin");
                if (bvbuiltin != null)
                {
                    return(HandleBvBuiltIns(FC, bvbuiltin, newArgs));
                }
                else
                {
                    string builtin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "builtin");
                    if (builtin != null)
                    {
                        return(HandleBuiltIns(FC, builtin, newArgs));
                    }
                }
                // Not a builtin so treat as uninterpreted function call
                return(Builder.UFC(FC, newArgs.ToArray()));
            }
            else if (node.Fun is UnaryOperator)
            {
                var U = (UnaryOperator)node.Fun;
                Debug.Assert(newArgs.Count == 1);
                switch (U.Op)
                {
                case UnaryOperator.Opcode.Neg:
                    return(Builder.Neg(newArgs[0]));

                case UnaryOperator.Opcode.Not:
                    return(Builder.Not(newArgs[0]));

                default:
                    throw new NotImplementedException("Unary operator not supported");
                }
            }
            else if (node.Fun is BinaryOperator)
            {
                var B = (BinaryOperator)node.Fun;
                Debug.Assert(newArgs.Count == 2);
                switch (B.Op)
                {
                // Integer or Real number operators
                case BinaryOperator.Opcode.Add:
                    return(Builder.Add(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Sub:
                    return(Builder.Sub(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Mul:
                    return(Builder.Mul(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Div:
                    return(Builder.Div(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Mod:
                    return(Builder.Mod(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.RealDiv:
                    return(Builder.RealDiv(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Pow:
                    return(Builder.Pow(newArgs[0], newArgs[1]));

                // Comparision operators
                case BinaryOperator.Opcode.Eq:
                    return(Builder.Eq(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Neq:
                    return(Builder.NotEq(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Gt:
                    return(Builder.Gt(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Ge:
                    return(Builder.Ge(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Lt:
                    return(Builder.Lt(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Le:
                    return(Builder.Le(newArgs[0], newArgs[1]));

                // Bool operators
                case BinaryOperator.Opcode.And:
                    return(Builder.And(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Or:
                    return(Builder.Or(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Imp:
                    return(Builder.Imp(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Iff:
                    return(Builder.Iff(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Subtype:
                    throw new NotImplementedException("SubType binary operator support not implemented");

                default:
                    throw new NotSupportedException("Binary operator" + B.Op.ToString() + "not supported!");
                }
            }
            else if (node.Fun is MapStore)
            {
                Debug.Assert(newArgs.Count >= 3);
                // FIXME: We're probably making too many lists/arrays here
                var map     = newArgs[0];
                var value   = newArgs[newArgs.Count - 1]; // Last argument is value to store
                var indices = new List <Expr>();
                for (int index = 1; index < newArgs.Count - 1; ++index)
                {
                    indices.Add(newArgs[index]);
                }
                Debug.Assert(indices.Count + 2 == newArgs.Count);
                return(Builder.MapStore(map, value, indices.ToArray()));
            }
            else if (node.Fun is MapSelect)
            {
                // FIXME: We're probably making too many lists/arrays here
                Debug.Assert(newArgs.Count >= 2);
                var map     = newArgs[0];
                var indices = new List <Expr>();
                for (int index = 1; index < newArgs.Count; ++index)
                {
                    indices.Add(newArgs[index]);
                }
                Debug.Assert(indices.Count + 1 == newArgs.Count);
                return(Builder.MapSelect(map, indices.ToArray()));
            }
            else if (node.Fun is IfThenElse)
            {
                Debug.Assert(newArgs.Count == 3);
                return(Builder.IfThenElse(newArgs[0], newArgs[1], newArgs[2]));
            }
            else if (node.Fun is TypeCoercion)
            {
                // FIXME: Add support for this in the builder
                // I don't want to put this into the IExprBuilder until I know
                // exactly how this operator works and how it should be type checked
                var immutableTC = new NAryExpr(Token.NoToken, node.Fun, newArgs, /*immutable=*/ true);
                immutableTC.Type = node.Type;
                return(immutableTC);
            }
            else if (node.Fun is ArithmeticCoercion)
            {
                Debug.Assert(newArgs.Count == 1);
                var ac = node.Fun as ArithmeticCoercion;
                return(Builder.ArithmeticCoercion(ac.Coercion, newArgs[0]));
            }

            throw new NotSupportedException("Unsupported NAryExpr");
        }