public virtual Expr UFC(FunctionCall func, params Expr[] args) { return(UB.UFC(func, args)); }
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); }
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"); }