private static bool TryGetVariableHandle(BoundVariable boundvar, FlowState state, out VariableHandle varHandle) { if (boundvar.Name != null) // direct variable name { if (boundvar.VariableKind == VariableKind.LocalVariable || boundvar.VariableKind == VariableKind.Parameter || boundvar.VariableKind == VariableKind.LocalTemporalVariable) { varHandle = state.GetLocalHandle(new VariableName(boundvar.Name)); return(true); } } // varHandle = default(VariableHandle); return(false); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (node.Decl == null || !(node.Decl is LocalVariable || node.Decl is Formal || node.Decl is GlobalVariable)) { return(node); } else { BoundVariable boundVar; if (!Substitutions.TryGetValue(node.Decl, out boundVar)) { boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, node.Name, node.Type)); Substitutions[node.Decl] = boundVar; } return(new IdentifierExpr(node.tok, boundVar)); } }
/////////////////////////////////////////////////////////////////////// public void addBoundVariable(BoundVariable v) { if (parentScope != null) { parentScope.addBoundVariable(v); } else { if (boundVariableMap.ContainsKey(v.name)) { Debug.Assert(ReferenceEquals(boundVariableMap[v.name], v)); } else { boundVariableMap[v.name] = v; } } }
// FIXME: Taken from SimpleExprBuilderTestBase. This needs to be refactored protected Tuple <Variable, IdentifierExpr> GetVarAndIdExpr(string name, Microsoft.Boogie.Type type, bool isBound = false) { var typeIdent = new TypedIdent(Token.NoToken, name, type); Variable v = null; if (isBound) { v = new BoundVariable(Token.NoToken, typeIdent); } else { v = new GlobalVariable(Token.NoToken, typeIdent); } var id = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true); return(new Tuple <Variable, IdentifierExpr>(v, id)); }
public void SimpleExists() { var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.Bool)); var id = new IdentifierExpr(Token.NoToken, boundVar); var exists = new ExistsExpr(Token.NoToken, new List <Variable>() { boundVar }, id); var id2 = new IdentifierExpr(Token.NoToken, boundVar); var exists2 = new ExistsExpr(Token.NoToken, new List <Variable>() { boundVar }, id2); Assert.AreNotSame(exists, exists2); // These are different references Assert.IsTrue(exists.Equals(exists2)); // These are "structurally equal" Assert.AreEqual(exists.GetHashCode(), exists2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }
public virtual Expression visit(QuantifiedExpression e) { BoundVariable newV = visitBoundVariable(e.variable); Expression newE = e.expression.visit(this); var newT = (from trs in e.triggers select trs.visit(this)).ToArray(); e.type.visit(this); Expression result; if (!ReferenceEquals(e.variable, newV) || !ReferenceEquals(e.expression, newE) || (e.triggers.Count != newT.Count() || Enumerable.Range(0, e.triggers.Count).Any(i => !ReferenceEquals(e.triggers[i], newT[i])))) { result = new BasicQuantifiedExpression(procedure, e.quantifier, newV, newE, newT, e.attributes); } else { result = e; } return(result); }
public void SimpleLambda() { var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.Bool)); var id = new IdentifierExpr(Token.NoToken, boundVar); // This is basically an Identity Map var lambdaExpr = new LambdaExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable>() { boundVar }, null, id); var id2 = new IdentifierExpr(Token.NoToken, boundVar); var lambdaExpr2 = new LambdaExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable>() { boundVar }, null, id2); Assert.AreNotSame(lambdaExpr, lambdaExpr2); // These are different references Assert.IsTrue(lambdaExpr.Equals(lambdaExpr2)); // These are "structurally equal" Assert.AreEqual(lambdaExpr.GetHashCode(), lambdaExpr2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }
public void AddBoundVariable(string name, BindingGetDlg getDelegate, BindingSetDlg setDelegate) { BoundVariable variable; if (variables.ContainsKey(name)) { variable = variables[name]; } else { variable = new BoundVariable { Name = name, }; variables.Add(name, variable); shared.Cpu.AddVariable(variable, name, false); } if (getDelegate != null) variable.Get = getDelegate; if (setDelegate != null) variable.Set = setDelegate; }
public Expr DisjointnessExprForPermissions(string domainName, IEnumerable<Expr> permissionsExprs) { Expr expr = Expr.True; if (permissionsExprs.Count() > 1) { int count = 0; List<Expr> subsetExprs = new List<Expr>(); LinearDomain domain = linearDomains[domainName]; BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, $"partition_{domainName}", domain.mapTypeInt)); foreach (Expr e in permissionsExprs) { subsetExprs.Add(SubsetExpr(domain, e, partition, count)); count++; } expr = new ExistsExpr(Token.NoToken, new List<Variable> {partition}, Expr.And(subsetExprs)); } expr.Resolve(new ResolutionContext(null)); expr.Typecheck(new TypecheckingContext(null)); return expr; }
/////////////////////////////////////////////////////////// public BasicQuantifiedExpression( Scope scope, Quantifier quantifier, BoundVariable variable, // DataType typeBound, Expression expression, IEnumerable <IEnumerable <Expression> > triggers, string attributes ) { Debug.Assert(scope != null); this.scope = scope; scope.addBoundVariable(variable); this.quantifier = quantifier; this.variable = variable; // this.typeBound = typeBound; this.expression = expression; this.triggers = (from trs in triggers select new ExpressionList(trs)).ToArray(); if (attributes != null) { this.attributes = (string)(attributes.Clone()); } }
static void InitMemory(Program program) { // find curraddr var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar) .FirstOrDefault(); if (alloc == null) { return; } // create alloc_init var allocinit = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, alloc.Name + "_init", alloc.TypedIdent.Type), false); // malloc ensures ret > alloc_init program.TopLevelDeclarations.OfType <Procedure>() .Where(p => MallocNames.Contains(p.Name)) .Iter(p => p.Ensures.Add(new Ensures(false, Expr.Gt(Expr.Ident(p.OutParams[0]), Expr.Ident(allocinit))))); // forall x : int :: { M[x] } M[x] >= 0 && M[x] < alloc_init var initM = new Func <Variable, Expr>(M => { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", btype.Int)); var mx = BoogieAstFactory.MkMapAccessExpr(M, Expr.Ident(x)); return(new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { x }, null, new Trigger(Token.NoToken, true, new List <Expr> { mx }), Expr.And(Expr.Ge(mx, Expr.Literal(0)), Expr.Lt(mx, Expr.Ident(allocinit))))); }); var cmds = new List <Cmd>( program.TopLevelDeclarations.OfType <GlobalVariable>() .Where(g => g.Name.StartsWith("$M")) .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt) .Select(g => initM(g)) .Select(e => new AssumeCmd(Token.NoToken, e))); // alloc_init > 0 && alloc > alloc_init cmds.Insert(0, new AssumeCmd(Token.NoToken, Expr.And(Expr.Gt(Expr.Ident(allocinit), Expr.Literal(0)), Expr.Gt(Expr.Ident(alloc), Expr.Ident(allocinit))))); var blk = new Block(Token.NoToken, "start", cmds, new ReturnCmd(Token.NoToken)); // create init proc var initproc = new Procedure(Token.NoToken, "SmackExtraInit", new List <TypeVariable>(), new List <Variable>(), new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>()); initproc.AddAttribute(AvUtil.AvnAnnotations.InitialializationProcAttr); var initimpl = new Implementation(Token.NoToken, initproc.Name, new List <TypeVariable>(), new List <Variable>(), new List <Variable>(), new List <Variable>(), new List <Block> { blk }); program.AddTopLevelDeclaration(initproc); program.AddTopLevelDeclaration(initimpl); program.AddTopLevelDeclaration(allocinit); }
public static void AddStaticMethod(this Environment environment, string name, System.Type type, MethodInfo method) { var boundVariable = new BoundVariable(name, null, method); environment.AddVariable(boundVariable); }
public static void AddStaticProperty(this Environment environment, string name, System.Type type, PropertyInfo property) { var boundVariable = new BoundVariable(name, null, property); environment.AddVariable(boundVariable); }
public static void AddBoundMethod(this Environment environment, string name, object target, MethodInfo method) { var boundVariable = new BoundVariable(name, target, method); environment.AddVariable(boundVariable); }
public static void AddBoundProperty(this Environment environment, string name, object target, PropertyInfo property) { var boundVariable = new BoundVariable(name, target, property); environment.AddVariable(boundVariable); }
//assertions for remote jumps and return instructions public List <AssertCmd> RemoteTransferAssertions() { List <AssertCmd> assertions = new List <AssertCmd>(); if (this.bound_stacksize_option && Options.instantiateQuantifiers) //can only instantiate quantifiers on bounded { Expr instantiation = Expr.True; int addr_offset = 8; while (addr_offset <= (this.bound_stacksize_offset)) { Expr addr = new NAryExpr(Token.NoToken, new FunctionCall(this.minus_64), new List <Expr>() { new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)), new LiteralExpr(Token.NoToken, BigNum.FromInt(addr_offset), 64) }); Expr addr_not_writable = Expr.Not(new NAryExpr(Token.NoToken, new FunctionCall(writable), new List <Expr>() { new IdentifierExpr(Token.NoToken, mem_bitmap), addr })); //instantiation = Expr.And(instantiation, addr_not_writable); Expr precondition = Expr.And(Expr.Eq(new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP), 3, 0), new LiteralExpr(Token.NoToken, BigNum.FromInt(0), 3)), Expr.Eq(new IdentifierExpr(Token.NoToken, RSP), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)))); assertions.Add(new AssertCmd(Token.NoToken, Expr.Imp(precondition, addr_not_writable), new QKeyValue(Token.NoToken, "return_instrumentation", new List <object> { addr }, null))); addr_offset += 8; } } else { //forall i. i < old(rsp) && i[3:0] == 0bv3 ==> ¬writable(mem,i) BoundVariable i = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "i", this.mem.TypedIdent.Type.AsMap.Arguments[0])); Expr in_local_frame = new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, i), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)) }); if (this.bound_stacksize_option) { Expr smallest_allowed_address = new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)), new LiteralExpr(Token.NoToken, BigNum.FromInt(this.bound_stacksize_offset), 64) }); in_local_frame = Expr.And(in_local_frame, new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, i), smallest_allowed_address })); } NAryExpr in_stack = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr>() { new IdentifierExpr(Token.NoToken, i) }); Expr aligned = Expr.Eq(new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, i), 3, 0), new LiteralExpr(Token.NoToken, BigNum.FromInt(0), 3)); Expr not_writable = Expr.Not(new NAryExpr(Token.NoToken, new FunctionCall(writable), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_bitmap), new IdentifierExpr(Token.NoToken, i) })); Expr assert_mem_false_expr = new ForallExpr(Token.NoToken, new List <Variable>() { i }, Expr.Imp(Expr.And(Expr.And(in_local_frame, in_stack), aligned), not_writable)); assertions.Add(new AssertCmd(Token.NoToken, assert_mem_false_expr)); } //rsp == old(rsp) assertions.Add(new AssertCmd(Token.NoToken, Expr.Eq(new IdentifierExpr(Token.NoToken, RSP), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP))))); return(assertions); }
public ExpressionSubstitution(BoundVariable v, Expression e) : this() { add(v.name, e); }
public override BoundVariable VisitBoundVariable(BoundVariable node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <BoundVariable>() != null); return(base.VisitBoundVariable((BoundVariable)node.Clone())); }
public LinearDomain(Program program, string domainName, Type elementType) { this.elementType = elementType; this.axioms = new List <Axiom>(); MapType mapTypeBool = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> { this.elementType }, Type.Bool); MapType mapTypeInt = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> { this.elementType }, Type.Int); this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapOrBool.AddAttribute("builtin", "MapOr"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Or, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapImpBool.AddAttribute("builtin", "MapImp"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Imp, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstBool.AddAttribute("builtin", "MapConst"); } else { BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> { Expr.True }), xie }); var trueAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { x }, trueTerm); trueAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr)); var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> { Expr.False }), xie }); var falseAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm)); falseAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr)); } this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapEqInt.AddAttribute("builtin", "MapEq"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt)); IdentifierExpr bie = new IdentifierExpr(Token.NoToken, b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List <Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Eq, new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List <Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List <Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt", new List <Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstInt.AddAttribute("builtin", "MapConst"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int)); IdentifierExpr aie = new IdentifierExpr(Token.NoToken, a); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = new IdentifierExpr(Token.NoToken, x); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List <Expr> { aie }), xie }); var axiomExpr = new ForallExpr(Token.NoToken, new List <Variable> { a, x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie)); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } foreach (var axiom in axioms) { axiom.Expr.Resolve(new ResolutionContext(null)); axiom.Expr.Typecheck(new TypecheckingContext(null)); } }
////////////////////////////////////////////// public BasicBoundVariableExpression(BoundVariable boundVariable) { Debug.Assert(boundVariable != null); this.boundVariable = boundVariable; }
public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq) { List <Cmd> newCmdSeq = new List <Cmd>(); foreach (Cmd c in cmdSeq) { switch (Utils.getSlashVerifyCmdType(c)) { case SlashVerifyCmdType.Store8: case SlashVerifyCmdType.Store16: case SlashVerifyCmdType.Store32: case SlashVerifyCmdType.Store64: //mem := store(mem, y, e) { Tuple <Variable, Expr, Expr> storeArgs = Utils.getStoreArgs(c as AssignCmd); Expr store_addr = storeArgs.Item2; Expr store_value = storeArgs.Item3; Expr old_RSP = new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)); AssertCmd assertion; Func <int, Expr> OffsetExpr = delegate(int n) { LiteralExpr x = new LiteralExpr(Token.NoToken, BigNum.FromInt(Math.Abs(n)), 64); return(new NAryExpr(Token.NoToken, (n >= 0) ? new FunctionCall(plus_64) : new FunctionCall(minus_64), new List <Expr>() { storeArgs.Item2, x })); }; //Console.WriteLine("store to {0} at addr {1} with value {2}", storeArgs.Item1, storeArgs.Item2, storeArgs.Item3); int iterations = Utils.getSlashVerifyCmdType(c) == SlashVerifyCmdType.Store8 ? 1 : Utils.getSlashVerifyCmdType(c) == SlashVerifyCmdType.Store16 ? 2 : Utils.getSlashVerifyCmdType(c) == SlashVerifyCmdType.Store32 ? 4 : 8; //instrument assert ((addrInStack(PLUS_64(t_a, 0bv64)) && GE_64(PLUS_64(t_a, 0bv64), old(RSP))) ==> // writable(mem,PLUS_64(t_a, 0bv64)) || writable(mem,MINUS_64(t_a, 8bv64))) && (addrInBitmap(PLUS_64(t_a, 0bv64)) ==> // LT_64(largestAddrAffected_8(mem, PLUS_64(t_a, 0bv64), t_v[8:0]), old(RSP - 8))); Expr is_checkworthy_store = Expr.False; foreach (int iter in new List <int>() { 0, iterations - 1 }.Distinct()) //disjunction over a, a+n-1 { Expr addr_in_stack = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr>() { OffsetExpr(iter) }); Expr addr_in_parent_frame = new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(iter), old_RSP }); Expr addr_not_in_backing_space = Expr.Not(Expr.And( new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(iter), new NAryExpr(Token.NoToken, new FunctionCall(plus_64), new List <Expr>() { old_RSP, new LiteralExpr(Token.NoToken, BigNum.FromInt(8), 64) }) }), new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { OffsetExpr(iter), new NAryExpr(Token.NoToken, new FunctionCall(plus_64), new List <Expr>() { old_RSP, new LiteralExpr(Token.NoToken, BigNum.FromInt(40), 64) }) }))); is_checkworthy_store = Expr.Or(is_checkworthy_store, Expr.And(addr_in_stack, Expr.And(addr_not_in_backing_space, addr_in_parent_frame))); } //Fix for the padding issue. Enough to check writability of (addr + 0). It's an invariant that /guard:cfw maintains Expr is_writable = new NAryExpr(Token.NoToken, new FunctionCall(writable), new List <Expr>() { new IdentifierExpr(Token.NoToken, mem_bitmap), OffsetExpr(0) }); Expr check_for_stack_store = Expr.Imp(is_checkworthy_store, is_writable); assertion = new AssertCmd(Token.NoToken, check_for_stack_store); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, Utils.getSlashVerifyCmdType(c)); for (int iter = 0; iter < iterations; iter++) { Expr addr_in_bitmap = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr>() { OffsetExpr(iter) }); Expr largest_addr_affected = new NAryExpr(Token.NoToken, new FunctionCall(largestAddrAffected_8), new List <Expr>() { new IdentifierExpr(Token.NoToken, mem_bitmap), OffsetExpr(iter), new BvExtractExpr(Token.NoToken, store_value, 8 * (iter + 1), 8 * iter) }); //Expr addr_in_own_frame = new NAryExpr(Token.NoToken, new FunctionCall(lt_64), // new List<Expr>() { largest_addr_affected, old_RSP }); //Not using this because of padding issue Expr largest_allowed_address = new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { old_RSP, new LiteralExpr(Token.NoToken, BigNum.FromInt(8), 64) }); Expr addr_in_own_frame = new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { largest_addr_affected, largest_allowed_address }); if (this.bound_stacksize_option) { Utils.Assert(this.bound_stacksize_offset % 8 == 0, "Need stack size estimate to be a multiple of 8"); Expr smallest_addr_affected = new NAryExpr(Token.NoToken, new FunctionCall(smallestAddrAffected_8), new List <Expr>() { new IdentifierExpr(Token.NoToken, mem_bitmap), OffsetExpr(iter), new BvExtractExpr(Token.NoToken, store_value, 8 * (iter + 1), 8 * iter) }); Expr smallest_allowed_address = new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { old_RSP, new LiteralExpr(Token.NoToken, BigNum.FromInt(this.bound_stacksize_offset), 64) }); addr_in_own_frame = Expr.And(addr_in_own_frame, new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { smallest_addr_affected, smallest_allowed_address })); } Expr any_addr_affected = new NAryExpr(Token.NoToken, new FunctionCall(anyAddrAffected_8), new List <Expr>() { new IdentifierExpr(Token.NoToken, mem_bitmap), OffsetExpr(iter), new BvExtractExpr(Token.NoToken, store_value, 8 * (iter + 1), 8 * iter) }); Expr value_not_zero = Expr.Neq(new BvExtractExpr(Token.NoToken, store_value, 8 * (iter + 1), 8 * iter), new LiteralExpr(Token.NoToken, BigNum.FromInt(0), 8)); Expr check_for_bitmap_store = Expr.Imp(Expr.And(Expr.And(addr_in_bitmap, any_addr_affected), value_not_zero), addr_in_own_frame); assertion = new AssertCmd(Token.NoToken, check_for_bitmap_store); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, Utils.getSlashVerifyCmdType(c)); } if (Options.confidentiality) { Expr addr_in_U = Expr.And( Expr.And( new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(0), new IdentifierExpr(Token.NoToken, this.stack_low) }), new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { OffsetExpr(0), new IdentifierExpr(Token.NoToken, this.bitmap_high) })), Expr.And( new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(iterations - 1), new IdentifierExpr(Token.NoToken, this.stack_low) }), new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { OffsetExpr(iterations - 1), new IdentifierExpr(Token.NoToken, this.bitmap_high) })) ); Expr _data_low = new LiteralExpr(Token.NoToken, BigNum.FromInt(Int32.Parse(Options.dataLow.ToUpper(), System.Globalization.NumberStyles.HexNumber)), 64); Expr _data_high = new LiteralExpr(Token.NoToken, BigNum.FromInt(Int32.Parse(Options.dataHigh.ToUpper(), System.Globalization.NumberStyles.HexNumber)), 64); Expr addr_in_Data = Expr.And( Expr.And( new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(0), _data_low }), new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { OffsetExpr(0), _data_high })), Expr.And( new NAryExpr(Token.NoToken, new FunctionCall(ge_64), new List <Expr>() { OffsetExpr(iterations - 1), _data_low }), new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { OffsetExpr(iterations - 1), _data_high })) ); assertion = new AssertCmd(Token.NoToken, Expr.Or(addr_in_U, addr_in_Data)); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, Utils.getSlashVerifyCmdType(c)); } break; } case SlashVerifyCmdType.RepStosB: //x := REP_STOSB(mem, e1, e2, e3) { //TODO: might want to assert that it writes to the bitmap //if its writing zeros to bitmap, we dont need to assert anything break; } case SlashVerifyCmdType.SetRSP: { Expr alignment = Expr.Eq(new BvExtractExpr(Token.NoToken, (c as AssignCmd).Rhss[0], 3, 0), new LiteralExpr(Token.NoToken, BigNum.FromInt(0), 3)); Expr le_old_RSP = new NAryExpr(Token.NoToken, new FunctionCall(le_64), new List <Expr>() { (c as AssignCmd).Rhss[0], new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)) }); AssertCmd assertion = new AssertCmd(Token.NoToken, Expr.And(alignment, le_old_RSP)); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.SetRSP); break; } case SlashVerifyCmdType.Ret: { foreach (AssertCmd a in RemoteTransferAssertions()) { newCmdSeq.Add(a); VCSplitter.Instance.RecordAssertion(this.current_label, c, a, SlashVerifyCmdType.Ret); } break; } case SlashVerifyCmdType.Call: { AssertCmd assertion; string attribute_calltarget = QKeyValue.FindStringAttribute((c as AssertCmd).Attributes, "SlashVerifyCallTarget"); Utils.Assert(attribute_calltarget != null, "Expected SlashVerifyCallTarget attribute on call"); //assert policy(target); Expr is_policy; if (attribute_calltarget.Substring(0, 2).Equals("0x")) { int target = Int32.Parse(attribute_calltarget.ToUpper().Substring(2), System.Globalization.NumberStyles.HexNumber); is_policy = new NAryExpr(Token.NoToken, new FunctionCall(policy), new List <Expr>() { new LiteralExpr(Token.NoToken, BigNum.FromInt(target), 64) }); } else { //indirect call e.g. call rax //first find which register GlobalVariable target = this.globals.FirstOrDefault(v => v.Name.Equals(attribute_calltarget)); Utils.Assert(target != null, "Could not find " + attribute_calltarget); is_policy = new NAryExpr(Token.NoToken, new FunctionCall(policy), new List <Expr>() { new IdentifierExpr(Token.NoToken, target) }); } if (!Options.disablePolicyChecking) { assertion = new AssertCmd(Token.NoToken, is_policy); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.Call); } if (!this.bound_stacksize_option) { //forall i. i < (rsp - 8) ==> ¬writable(mem,i) //rsp - 8 holds return address, and everything below that must start off as non writable BoundVariable i = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "i", this.mem.TypedIdent.Type.AsMap.Arguments[0])); NAryExpr in_local_frame = new NAryExpr(Token.NoToken, new FunctionCall(lt_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, i), new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, RSP), new LiteralExpr(Token.NoToken, BigNum.FromInt(8), 64) }) }); NAryExpr in_stack = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr>() { new IdentifierExpr(Token.NoToken, i) }); Expr not_writable = Expr.Not(new NAryExpr(Token.NoToken, new FunctionCall(writable), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_bitmap), new IdentifierExpr(Token.NoToken, i) })); Expr assert_mem_false_expr = new ForallExpr(Token.NoToken, new List <Variable>() { i }, Expr.Imp(Expr.And(in_stack, in_local_frame), not_writable)); assertion = new AssertCmd(Token.NoToken, assert_mem_false_expr); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.Call); //assert !writable(mem, rsp-8) not_writable = Expr.Not(new NAryExpr(Token.NoToken, new FunctionCall(writable), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_bitmap), new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, RSP), new LiteralExpr(Token.NoToken, BigNum.FromInt(8), 64) }) })); assertion = new AssertCmd(Token.NoToken, not_writable); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.Call); } else { //assert that RSP is not lower than bound_stacksize_offset. if RSP has not gotten lower, than we know everything is writable below Expr smallest_allowed_address = new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)), new LiteralExpr(Token.NoToken, BigNum.FromInt(this.bound_stacksize_offset), 64) }); NAryExpr rsp_in_local_frame = new NAryExpr(Token.NoToken, new FunctionCall(le_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, RSP), smallest_allowed_address }); assertion = new AssertCmd(Token.NoToken, rsp_in_local_frame); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.Call); } //assert RSP <= (old(RSP) - 32) NAryExpr stack_backing_space = new NAryExpr(Token.NoToken, new FunctionCall(le_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, RSP), new NAryExpr(Token.NoToken, new FunctionCall(minus_64), new List <Expr>() { new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, RSP)), new LiteralExpr(Token.NoToken, BigNum.FromInt(32), 64) }) }); assertion = new AssertCmd(Token.NoToken, stack_backing_space); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.Call); break; } case SlashVerifyCmdType.RemoteJmp: case SlashVerifyCmdType.RemoteIndirectJmp: { //assert policy(target); Expr is_policy = Expr.False; if (Utils.getSlashVerifyCmdType(c) == SlashVerifyCmdType.RemoteJmp) { string attribute_jmptarget = QKeyValue.FindStringAttribute((c as AssertCmd).Attributes, "SlashVerifyJmpTarget"); Utils.Assert(attribute_jmptarget != null, "Expected SlashVerifyJmpTarget attribute on jmp"); int target = Int32.Parse(attribute_jmptarget.ToUpper().Substring(2), System.Globalization.NumberStyles.HexNumber); is_policy = new NAryExpr(Token.NoToken, new FunctionCall(policy), new List <Expr>() { new LiteralExpr(Token.NoToken, BigNum.FromInt(target), 64) }); } else if (Utils.getSlashVerifyCmdType(c) == SlashVerifyCmdType.RemoteIndirectJmp) { string attribute_jmpregister = QKeyValue.FindStringAttribute((c as AssertCmd).Attributes, "SlashVerifyJmpRegister"); Utils.Assert(attribute_jmpregister != null, "Exprected jmp register annotation on indirect jump"); GlobalVariable global_register = this.globals.FirstOrDefault(x => x.Name.Equals(attribute_jmpregister)); Utils.Assert(global_register != null, "Could not find global variable " + attribute_jmpregister); is_policy = new NAryExpr(Token.NoToken, new FunctionCall(policy), new List <Expr>() { new IdentifierExpr(Token.NoToken, global_register) }); } AssertCmd assertion = new AssertCmd(Token.NoToken, is_policy); newCmdSeq.Add(assertion); VCSplitter.Instance.RecordAssertion(this.current_label, c, assertion, SlashVerifyCmdType.RemoteJmp); foreach (AssertCmd a in RemoteTransferAssertions()) { newCmdSeq.Add(a); VCSplitter.Instance.RecordAssertion(this.current_label, c, a, SlashVerifyCmdType.RemoteJmp); } break; } } //The assert gets placed prior to the original command newCmdSeq.Add(c); } return(base.VisitCmdSeq(newCmdSeq)); }
public override BoundVariable VisitBoundVariable(BoundVariable node) { add(node); return(base.VisitBoundVariable(node)); }
public override BoundVariable VisitBoundVariable(BoundVariable node) { return(base.VisitBoundVariable((BoundVariable)node.Clone())); }
public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq) { List <Cmd> newCmdSeq = new List <Cmd>(); if (this.currentLabel == this.memCheckpointLabel) { //mem_oldbitmap := mem AssignCmd ac = new AssignCmd(Token.NoToken, new List <AssignLhs>() { new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_oldbitmap)) }, new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_bitmap) }); newCmdSeq.Add(ac); } else if (this.loopHeaderLabels.Contains(this.currentLabel)) { //assert (forall i: bv64 :: addrInBitmap(i) ==> mem[i] == mem_oldbitmap[i]); BoundVariable i = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "i", this.mem.TypedIdent.Type.AsMap.Arguments[0])); Expr in_bitmap = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInBitmap), new List <Expr>() { new IdentifierExpr(Token.NoToken, i) }); Expr assert_expr; Expr mem_bitmap_of_i = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_bitmap), new IdentifierExpr(Token.NoToken, i) }); Expr mem_oldbitmap_of_i = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem_oldbitmap), new IdentifierExpr(Token.NoToken, i) }); assert_expr = new ForallExpr(Token.NoToken, new List <Variable>() { i }, Expr.Imp(in_bitmap, Expr.Eq(mem_bitmap_of_i, mem_oldbitmap_of_i))); //for Houdini Constant existential = this.existentials.Dequeue(); assert_expr = Expr.Imp(new IdentifierExpr(Token.NoToken, existential), assert_expr); newCmdSeq.Add(new AssertCmd(Token.NoToken, assert_expr)); //assert (LOAD_LE_64(mem, _guard_writeTable_ptr) == _bitmap_low); Expr load_mem_guardptr = new NAryExpr(Token.NoToken, new FunctionCall(this.load_64), new List <Expr>() { new IdentifierExpr(Token.NoToken, this.mem), new IdentifierExpr(Token.NoToken, this._guard_writeTable_ptr) }); assert_expr = Expr.Eq(load_mem_guardptr, new IdentifierExpr(Token.NoToken, _bitmap_low)); //for Houdini existential = this.existentials.Dequeue(); assert_expr = Expr.Imp(new IdentifierExpr(Token.NoToken, existential), assert_expr); newCmdSeq.Add(new AssertCmd(Token.NoToken, assert_expr)); } newCmdSeq.AddRange(cmdSeq); return(base.VisitCmdSeq(newCmdSeq)); }
public static Expr EmitEq(IdentifierExpr leftVar, IdentifierExpr rightVar, HashSet <Variable> ignoreSet) { // just blocking poly map for now - hemr if (!(leftVar.Decl.TypedIdent.Type is MapType || leftVar.Decl.TypedIdent.Type is TypeSynonymAnnotation)) { return(Expr.Eq(leftVar, rightVar)); } if (leftVar.Decl.TypedIdent.Type is TypeSynonymAnnotation) { var l = leftVar.Decl.TypedIdent.Type as TypeSynonymAnnotation; System.Diagnostics.Debug.Assert(!l.IsMap, "only handle non map typesynonymAnnotations, found " + l); return(Expr.Eq(leftVar, rightVar)); } List <Variable> bound = null; BoundVariable[] bvs = new BoundVariable[leftVar.Decl.TypedIdent.Type.AsMap.Arguments.Count]; int i = 0; string polyMapName = ""; foreach (Microsoft.Boogie.Type ts in leftVar.Decl.TypedIdent.Type.AsMap.Arguments) { if (leftVar.Decl.TypedIdent.Type is TypeSynonymAnnotation) { int index = 0; index = ts.ToString().IndexOf(" "); if (index >= 0) { polyMapName = ts.ToString().Substring(index + 1); } } bound = new List <Variable>(); var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_x" + i, ts)); // bound.Add(x); bvs[i] = x; i++; } //var bound = new List<Variable>(); //var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_x", leftVar.Decl.TypedIdent.Type.AsMap.Arguments[0])); //bound.Add(x); //var lhs = SelectExpr(leftVar, Expr.Ident(x).); //var rhs = SelectExpr(rightVar, Expr.Ident(x)); IdentifierExpr[] idenExprs = new IdentifierExpr[bvs.Length]; for (int j = 0; j < bvs.Length; j++) { BoundVariable bv = bvs[j]; idenExprs[j] = Expr.Ident(bv); } var lhs = SelectExpr(leftVar, idenExprs); var rhs = SelectExpr(rightVar, idenExprs); bound = new List <Variable>(bvs); if (!polyMapName.Equals("")) { var forall = new ForallExpr(Token.NoToken, new List <TypeVariable>(new TypeVariable[] { new TypeVariable(Token.NoToken, polyMapName) }), bound, Expr.Eq(lhs, rhs)); //var forall2 = new ForallExpr(Token.NoToken, new List<TypeVariable>(new TypeVariable(Token.NoToken, polyMapName)), bound, Expr.Eq(lhs, rhs)); //return Expr.Or(Expr.Eq(leftVar, rightVar), forall); // as mentioned... blocking poly maps for now - hemr return(Expr.Eq(leftVar, rightVar)); } else { return(Expr.Or(Expr.Eq(leftVar, rightVar), new ForallExpr(Token.NoToken, bound, Expr.Eq(lhs, rhs)))); } //bound = new List<Variable>(bvs); //return Expr.Or(Expr.Eq(leftVar, rightVar), new ForallExpr(Token.NoToken, bound, Expr.Eq(lhs, rhs))); //return Expr.True; }
public override BoundVariable VisitBoundVariable(BoundVariable node) { return(node); }
private Expr CalculatePathCondition() { Expr returnExpr = Expr.True; foreach (Variable v in program.GlobalVariables()) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } if (first != null) { foreach (Variable v in first.thisOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } } foreach (Variable v in second.thatOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } Block[] dfsStackAsArray = dfsStack.Reverse().ToArray(); for (int i = dfsStackAsArray.Length - 1; i >= 0; i--) { Block b = dfsStackAsArray[i]; for (int j = b.Cmds.Count - 1; j >= 0; j--) { Cmd cmd = b.Cmds[j]; if (cmd is AssumeCmd) { AssumeCmd assumeCmd = cmd as AssumeCmd; returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr); } else if (cmd is AssignCmd) { AssignCmd assignCmd = (cmd as AssignCmd).AsSimpleAssignCmd; Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); for (int k = 0; k < assignCmd.Lhss.Count; k++) { map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k]; } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr); } else if (cmd is HavocCmd) { HavocCmd havocCmd = cmd as HavocCmd; List <Variable> existVars = new List <Variable>(); Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); foreach (IdentifierExpr ie in havocCmd.Vars) { BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type); map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv); existVars.Add(bv); } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr)); } else { Debug.Assert(false); } } } return(returnExpr); }
public virtual BoundVariable visitBoundVariable(BoundVariable v) { v.type.visit(this); return(v); }
private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second) { Tuple <ActionInfo, ActionInfo> actionPair = new Tuple <ActionInfo, ActionInfo>(first, second); if (failurePreservationCheckerCache.Contains(actionPair)) { return; } failurePreservationCheckerCache.Add(actionPair); List <Variable> inputs = new List <Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute(); Expr expr = Expr.True; foreach (AssertCmd assertCmd in first.thisGate) { expr = Expr.And(assertCmd.Expr, expr); } List <Requires> requires = DisjointnessRequires(program, first, second); requires.Add(new Requires(false, Expr.Not(expr))); foreach (AssertCmd assertCmd in second.thatGate) { requires.Add(new Requires(false, assertCmd.Expr)); } Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> oldMap = new Dictionary <Variable, Expr>(); List <Variable> boundVars = new List <Variable>(); foreach (Variable v in program.GlobalVariables()) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } foreach (Variable v in second.thatOutParams) { { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } } foreach (Variable v in second.thatAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr)); if (boundVars.Count > 0) { Substitution subst = Substituter.SubstitutionFromHashtable(map); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap); ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr) new MySubstituter(subst, oldSubst).Visit(ensuresExpr)); } List <Ensures> ensures = new List <Ensures>(); ensures.Add(new Ensures(false, ensuresExpr)); List <Block> blocks = new List <Block>(); blocks.Add(new Block(Token.NoToken, "L", new List <Cmd>(), new ReturnCmd(Token.NoToken))); string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List <IdentifierExpr> globalVars = new List <IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); Procedure proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), new List <Variable>(), blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
/// <summary> /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing the lambda's /// free variables with bound ones. /// </summary> /// <param name="lambda">A lambda expression /// <code>(lambda x1: T1 ... x_n: T_n :: t)</code> /// where <c>t</c> contains the free variables <c>y1</c>, ..., <c>y_m</c>. /// </param> /// <returns> /// <list type="bullet"> /// <item> /// A function application <c>f(y1, ..., y_m)</c> where <c>f</c>'s body is defined to be the result of /// replacing the free variables <c>y1</c>, ..., <c>y_m</c> in <c>t</c> with bound variables /// <c>b1</c>, ..., <c>b_m</c>. /// </item> /// <item> /// Adds a definition and axiom for <c>f</c> to <see cref="lambdaFunctions"/> and <see cref="lambdaAxioms"/>. /// Memoizes <c>f</c> as the lifted lambda for <para>lambda</para>. /// </item> /// </list> /// </returns> private Expr LiftLambdaFreeVars(LambdaExpr lambda) { // We start by getting rid of any use of "old" inside the lambda. This is done as follows. // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og". // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers. var oldFinder = new OldFinder(); oldFinder.Visit(lambda); var oldSubst = new Dictionary<Variable, Expr>(); // g -> g0 var callOldMapping = new Dictionary<Variable, Expr>(); // g0 -> old(g) foreach (var v in oldFinder.FreeOldVars) { var g = v as GlobalVariable; if (g != null) { var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type)); oldSubst.Add(g, new IdentifierExpr(g0.tok, g0)); callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g))); } } var lambdaBody = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromDictionary(oldSubst), lambda.Body); var lambdaAttrs = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromDictionary(oldSubst), lambda.Attributes); if (0 < CommandLineOptions.Clo.VerifySnapshots && QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null) { // Attach a dummy checksum to avoid issues in the dependency analysis. var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> {"lambda expression"}, null); if (lambdaAttrs == null) { lambdaAttrs = checksumAttr; } else { lambdaAttrs.AddLast(checksumAttr); } } // this is ugly, the output will depend on hashing order var subst = new Dictionary<Variable, Expr>(); var substFnAttrs = new Dictionary<Variable, Expr>(); var formals = new List<Variable>(); var callArgs = new List<Expr>(); var axCallArgs = new List<Expr>(); var dummies = new List<Variable>(lambda.Dummies); var freeTypeVars = new List<TypeVariable>(); var fnTypeVarActuals = new List<Type /*!*/>(); var freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body Set freeVars = new Set(); BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, null, lambdaAttrs, freeVars); foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. if (o is Variable) { var v = o as Variable; var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); var f = new Formal(v.tok, ti, true); formals.Add(f); substFnAttrs.Add(v, new IdentifierExpr(f.tok, f)); var b = new BoundVariable(v.tok, ti); dummies.Add(b); if (callOldMapping.ContainsKey(v)) { callArgs.Add(callOldMapping[v]); } else { callArgs.Add(new IdentifierExpr(v.tok, v)); } Expr id = new IdentifierExpr(b.tok, b); subst.Add(v, id); axCallArgs.Add(id); } else { var tv = (TypeVariable) o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } var sw = new System.IO.StringWriter(); var wr = new TokenTextWriter(sw, true); lambda.Emit(wr); string lam_str = sw.ToString(); FunctionCall fcall; IToken tok = lambda.tok; Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); if (liftedLambdas.TryGetValue(lambda, out fcall)) { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("Old lambda: {0}", lam_str); } } else { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("New lambda: {0}", lam_str); } Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res, "auto-generated lambda function", Substituter.Apply(Substituter.SubstitutionFromDictionary(substFnAttrs), lambdaAttrs)); fn.OriginalLambdaExprAsString = lam_str; fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here liftedLambdas[lambda] = fcall; List<Expr /*!*/> selectArgs = new List<Expr /*!*/>(); foreach (Variable /*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambdaBody.Type; List<Type /*!*/> selectTypeParamActuals = new List<Type /*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable /*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaBody); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> {select}); lambdaFunctions.Add(fn); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaAttrs), trig, body)); } NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; }
public override Absy Visit(Absy node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Absy>() != null); node = base.Visit(node); LambdaExpr lambda = node as LambdaExpr; if (lambda != null) { IToken/*!*/ tok = lambda.tok; Contract.Assert(tok != null); Set freeVars = new Set(); lambda.ComputeFreeVariables(freeVars); // this is ugly, the output will depend on hashing order Dictionary<Variable, Expr> subst = new Dictionary<Variable, Expr>(); List<Variable> formals = new List<Variable>(); List<Expr> callArgs = new List<Expr>(); List<Expr> axCallArgs = new List<Expr>(); List<Variable> dummies = new List<Variable>(lambda.Dummies); List<TypeVariable> freeTypeVars = new List<TypeVariable>(); List<Type/*!*/> fnTypeVarActuals = new List<Type/*!*/>(); List<TypeVariable> freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. Since the lambda desugaring happens only // at the outermost level of a program (where there are no mutable variables) and, for // procedure bodies, after the statements have been passified (when mutable variables have // been replaced by immutable incarnations), we are interested only in BoundVar's and // TypeVariable's. BoundVariable v = o as BoundVariable; if (v != null) { TypedIdent ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); Formal f = new Formal(v.tok, ti, true); formals.Add(f); BoundVariable b = new BoundVariable(v.tok, ti); dummies.Add(b); callArgs.Add(new IdentifierExpr(v.tok, v)); Expr/*!*/ id = new IdentifierExpr(f.tok, b); Contract.Assert(id != null); subst.Add(v, id); axCallArgs.Add(id); } else if (o is TypeVariable) { TypeVariable tv = (TypeVariable)o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); Function fn = new Function(tok, "lambda@" + lambdaid++, freshTypeVars, formals, res, "auto-generated lambda function", lambda.Attributes); lambdaFunctions.Add(fn); FunctionCall fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here List<Expr/*!*/> selectArgs = new List<Expr/*!*/>(); foreach (Variable/*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambda.Body.Type; List<Type/*!*/> selectTypeParamActuals = new List<Type/*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable/*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambda.Body); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> { select }); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, lambda.Attributes, trig, body)); NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; } return node; }