Exemple #1
0
        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;
         }
     }
 }
Exemple #4
0
        // 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));
        }
Exemple #5
0
        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);
        }
Exemple #7
0
        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
        }
Exemple #8
0
        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;
        }
Exemple #9
0
    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;
    }
Exemple #10
0
        ///////////////////////////////////////////////////////////
        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());
            }
        }
Exemple #11
0
        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);
        }
Exemple #17
0
 public ExpressionSubstitution(BoundVariable v, Expression e)
     : this()
 {
     add(v.name, e);
 }
Exemple #18
0
 public override BoundVariable VisitBoundVariable(BoundVariable node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <BoundVariable>() != null);
     return(base.VisitBoundVariable((BoundVariable)node.Clone()));
 }
Exemple #19
0
        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));
        }
Exemple #22
0
 public override BoundVariable VisitBoundVariable(BoundVariable node)
 {
     add(node);
     return(base.VisitBoundVariable(node));
 }
Exemple #23
0
 public override BoundVariable VisitBoundVariable(BoundVariable node)
 {
     return(base.VisitBoundVariable((BoundVariable)node.Clone()));
 }
Exemple #24
0
        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));
        }
Exemple #25
0
        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;
        }
Exemple #26
0
 public override BoundVariable VisitBoundVariable(BoundVariable node)
 {
     return(node);
 }
Exemple #27
0
            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);
            }
Exemple #28
0
 public virtual BoundVariable visitBoundVariable(BoundVariable v)
 {
     v.type.visit(this);
     return(v);
 }
Exemple #29
0
        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);
        }
Exemple #30
0
      /// <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;
      }
Exemple #31
0
      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;
      }