protected Tuple <Variable, IdentifierExpr> GetBoundVarAndIdExpr(string name, Microsoft.Boogie.Type type)
        {
            var typeIdent = new TypedIdent(Token.NoToken, name, type);
            var v         = new BoundVariable(Token.NoToken, typeIdent);
            var id        = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true);

            return(new Tuple <Variable, IdentifierExpr>(v, id));
        }
        private void CreateDeviceStructConstant()
        {
            var ti       = new TypedIdent(Token.NoToken, "device$struct", Microsoft.Boogie.Type.Int);
            var constant = new Constant(Token.NoToken, ti, true);

            this.AC.TopLevelDeclarations.Add(constant);
            this.AC.DeviceStruct = constant;
        }
示例#3
0
        public void IdentifierExprDecl()
        {
            var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true);

            Assert.IsTrue(id.Immutable);
            var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool);

            Assert.Throws(typeof(InvalidOperationException), () => id.Decl = new GlobalVariable(Token.NoToken, typedIdent));
        }
示例#4
0
        public void IdentifierExprDecl()
        {
            var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true);

            Assert.IsTrue(id.Immutable);
            var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool);

            id.Decl = new GlobalVariable(Token.NoToken, typedIdent);
        }
示例#5
0
        // Return a new local variable
        private LocalVariable getNewLocal(Microsoft.Boogie.Type type)
        {
            string        name = "dontcare_dummy_var_" + (localVarCount.ToString());
            TypedIdent    tid  = new TypedIdent(Token.NoToken, name, type);
            LocalVariable lv   = new LocalVariable(Token.NoToken, tid);

            localsToAdd.Add(lv);
            localVarCount++;
            return(lv);
        }
示例#6
0
 public override TypedIdent VisitTypedIdent(TypedIdent node)
 {
     // dropping the where clauses for now - hemr
     if (node.WhereExpr != null)
     {
         node.WhereExpr = null;
     }
     node.Type = VisitType(node.Type);
     return(node);
 }
示例#7
0
        public void RemoveNoConstraintsBasedOnVars()
        {
            IConstraintManager CM      = new ConstraintManager();
            IExprBuilder       builder = GetBuilder();

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

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

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

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

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

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

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

            Expr queryExpr = builder.Eq(builder.BVAND(s1, s2), builder.ConstantBV(0, 8));

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

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

            bool c0Found = false;
            bool c1Found = false;

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

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

            Assert.IsTrue(c0Found);
            Assert.IsTrue(c1Found);
        }
        public static Variable MakeValueVariable(string name, AccessType access, Type type)
        {
            var ident = new TypedIdent(Token.NoToken, MakeValueVariableName(name, access), type);

            if (RaceCheckingMethod == RaceCheckingMethod.ORIGINAL)
            {
                return(new GlobalVariable(Token.NoToken, ident));
            }

            return(new Constant(Token.NoToken, ident, false));
        }
        public static Variable MakeValueVariable(string Name, AccessType Access, Microsoft.Boogie.Type Type)
        {
            var Ident = new TypedIdent(Token.NoToken, MakeValueVariableName(Name, Access),
                                       Type);

            if (RaceCheckingMethod == RaceCheckingMethod.ORIGINAL)
            {
                return(new GlobalVariable(Token.NoToken, Ident));
            }
            return(new Constant(Token.NoToken, Ident, false));
        }
示例#10
0
        // FIXME: This copied from the ExprBuilder tests. Refactor this
        protected Tuple <IdentifierExpr, BPLType> GetMapVariable(string name, BPLType resultTyp, params BPLType[] indices)
        {
            var mapType = new MapType(Token.NoToken,
                                      new List <Microsoft.Boogie.TypeVariable>(),
                                      indices.ToList(),
                                      resultTyp);
            var typeIdent = new TypedIdent(Token.NoToken, name, mapType);
            var gv        = new GlobalVariable(Token.NoToken, typeIdent);
            var id        = new IdentifierExpr(Token.NoToken, gv, /*immutable=*/ true);

            var result = new Tuple <IdentifierExpr, BPLType>(id, mapType);

            return(result);
        }
示例#11
0
        public bool Initialize(Microsoft.Boogie.Type[] varts)
        {
            if (varts.Length != Count || initialized)
            {
                return(false);
            }

            for (int i = 0; i < Count; i++)
            {
                vars[i] = new TypedIdent(Token.NoToken, baseName + i, varts[i]);
            }

            return(initialized = true);
        }
示例#12
0
        SymbolicVariable GetVar(string name)
        {
            // FIXME: THIS IS A HACK!

            // Dummy Boogie variable
            var IntTypeIdent = new TypedIdent(Token.NoToken, name, Microsoft.Boogie.Type.Int);
            var dummyVarBv   = new GlobalVariable(Token.NoToken, IntTypeIdent);

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

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

            return(new SymbolicVariable(name, dummyVarBv));
        }
        private void AddAccessWatchdogConstants()
        {
            foreach (var mr in this.AC.SharedMemoryRegions)
            {
                var ti = new TypedIdent(Token.NoToken, "WATCHED_ACCESS_" + mr.Name,
                                        this.AC.MemoryModelType);
                var watchdog = new Constant(Token.NoToken, ti, false);
                watchdog.AddAttribute("watchdog", new object[] { });

                if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name)))
                {
                    this.AC.TopLevelDeclarations.Add(watchdog);
                }
            }
        }
示例#14
0
        private void AddAccessWatchdogConstants()
        {
            for (int i = 0; i < this.MemoryRegions.Count; i++)
            {
                var ti = new TypedIdent(Token.NoToken,
                                        this.AC.GetAccessWatchdogConstantName(this.MemoryRegions[i].Name),
                                        this.AC.MemoryModelType);
                var watchdog = new Constant(Token.NoToken, ti, false);
                watchdog.AddAttribute("watchdog", new object[] { });

                if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name)))
                {
                    this.AC.TopLevelDeclarations.Add(watchdog);
                }
            }
        }
示例#15
0
        private Variable VarOfKind(TypedIdent x, StateKind k)
        {
            switch (k)
            {
            case StateKind.Local:
                return(new LocalVariable(Token.NoToken, x));

            case StateKind.Global:
                return(new GlobalVariable(Token.NoToken, x));

            case StateKind.FormalIn:
                return(new Formal(Token.NoToken, x, true));

            case StateKind.FormalOut:
                return(new Formal(Token.NoToken, x, false));
            }
            return(null); //impossible!
        }
示例#16
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));
        }
示例#17
0
        /// <summary>
        /// Creates a global variable with the given name.
        /// </summary>
        /// <param name="name">The name of the variable.</param>
        /// <returns>A reference to the variable.</returns>
        private Variable CreateGlobalVariable(string name)
        {
            Dictionary <string, object> attributes = new Dictionary <string, object>();

            attributes.Add("repair", null);
            attributes.Add("race_checking", null);
            attributes.Add("global", null);
            attributes.Add("elem_width", Expr.Literal(32));
            attributes.Add("source_elem_width", Expr.Literal(32));
            attributes.Add("source_dimensions", "*");

            TypedIdent ident    = new TypedIdent(Token.NoToken, name, Type.Bool);
            Variable   variable = useAxioms ? new Constant(Token.NoToken, ident, false)
                : new GlobalVariable(Token.NoToken, ident) as Variable;

            variable.Attributes = ConvertAttributes(attributes);
            program.AddTopLevelDeclaration(variable);

            return(variable);
        }
示例#18
0
        // Return a new local variable. Also add it to impl if it is not null
        private static LocalVariable getNewLocal(Microsoft.Boogie.Type type, Implementation impl)
        {
            Debug.Assert(type != null);

            string        name = "";
            LocalVariable lv   = null;

            do
            {
                name = "vslice_dummy_var_" + (localVarCount.ToString());
                TypedIdent tid = new TypedIdent(Token.NoToken, name, type);
                lv = new LocalVariable(Token.NoToken, tid);
                localVarCount++;
            } while (impl != null && impl.LocVars.Any(v => v.Name == name));

            if (impl != null)
            {
                impl.LocVars.Add(lv);
            }
            return(lv);
        }
示例#19
0
        public void MapWithTypeConstructorTypesNoArguments()
        {
            var tcDecl  = new TypeCtorDecl(Token.NoToken, "fox", 0);
            var tc      = new CtorType(Token.NoToken, tcDecl, new List <Microsoft.Boogie.Type>());
            var tcDecl2 = new TypeCtorDecl(Token.NoToken, "fox_two", 0);
            var tc2     = new CtorType(Token.NoToken, tcDecl2, new List <Microsoft.Boogie.Type>());
            var tcDecl3 = new TypeCtorDecl(Token.NoToken, "fox_three", 0);
            var tc3     = new CtorType(Token.NoToken, tcDecl3, new List <Microsoft.Boogie.Type>());
            var mapType = new MapType(
                Token.NoToken,
                new List <Microsoft.Boogie.TypeVariable>(),
                new List <Microsoft.Boogie.Type>()
            {
                tc, tc2
            },
                tc3);
            var mapTypeTypeIdent = new TypedIdent(Token.NoToken, "mapx", mapType);
            var gv = new GlobalVariable(Token.NoToken, mapTypeTypeIdent);

            // FIXME: The Symbolic constructor shouldn't really need the program location
            gv.SetMetadata <ProgramLocation>((int)AnnotationIndex.PROGRAM_LOCATION, new ProgramLocation(gv));
            var sym = new SymbolicVariable("y", gv);

            var builder = new SimpleExprBuilder(/*immutable=*/ true);
            var eq      = builder.Eq(sym.Expr, sym.Expr);

            Assert.IsNotInstanceOf <LiteralExpr>(eq); // Check that it wasn't constant folded

            using (var writer = new StringWriter()) {
                var printer = GetPrinter(writer);
                printer.AddDeclarations(eq);
                printer.PrintSortDeclarations();
                var str = writer.ToString().Trim();
                // Check we can see all the sort declarations we expect but don't depend on their order
                Assert.IsTrue(str.Contains("(declare-sort @fox)"));
                Assert.IsTrue(str.Contains("(declare-sort @fox_two)"));
                Assert.IsTrue(str.Contains("(declare-sort @fox_three)"));
            }
        }
示例#20
0
        public void NoArguments()
        {
            var tcDecl      = new TypeCtorDecl(Token.NoToken, "fox", 0);
            var tc          = new CtorType(Token.NoToken, tcDecl, new List <Microsoft.Boogie.Type>());
            var tcTypeIdent = new TypedIdent(Token.NoToken, "fox", tc);
            var gv          = new GlobalVariable(Token.NoToken, tcTypeIdent);

            // FIXME: The Symbolic constructor shouldn't really need the program location
            gv.SetMetadata <ProgramLocation>((int)AnnotationIndex.PROGRAM_LOCATION, new ProgramLocation(gv));
            var sym = new SymbolicVariable("y", gv);

            var builder = new SimpleExprBuilder(/*immutable=*/ true);
            var eq      = builder.Eq(sym.Expr, sym.Expr);

            Assert.IsNotInstanceOf <LiteralExpr>(eq); // Check that it wasn't constant folded

            using (var writer = new StringWriter())
            {
                var printer = GetPrinter(writer);
                printer.AddDeclarations(eq);
                printer.PrintSortDeclarations();
                Assert.AreEqual("(declare-sort @fox)", writer.ToString().Trim());
            }
        }
示例#21
0
 public FreeVariable(TypedIdent ti) : base(Token.NoToken, ti)
 {
 }
示例#22
0
        public void WholeProgram()
        {
            var p  = new Program();
            var t  = new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.Bool);
            var gv = new GlobalVariable(Token.NoToken, t);

            p.AddTopLevelDeclaration(gv);
            string metaDataString = "This is a test";

            p.SetMetadata(0, metaDataString);

            // Now try to clone
            var p2 = (Program)d.Visit(p);

            // Check global is a copy
            int            counter = 0;
            GlobalVariable gv2     = null;

            foreach (var g in p2.TopLevelDeclarations)
            {
                ++counter;
                Assert.IsInstanceOf <GlobalVariable>(g);
                gv2 = g as GlobalVariable;
            }

            Assert.AreEqual(1, counter);
            Assert.AreNotSame(gv, gv2);
            Assert.AreEqual(metaDataString, p2.GetMetadata <string>(0));


            // Check Top level declarations list is duplicated properly
            var t2  = new TypedIdent(Token.NoToken, "bar", Microsoft.Boogie.Type.Bool);
            var gv3 = new GlobalVariable(Token.NoToken, t2);

            p2.AddTopLevelDeclaration(gv3);

            counter = 0;
            foreach (var g in p2.TopLevelDeclarations)
            {
                ++counter;
                Assert.IsInstanceOf <GlobalVariable>(g);
            }

            Assert.AreEqual(2, counter);

            // The original program should still only have one global variable
            counter = 0;
            foreach (var g in p.TopLevelDeclarations)
            {
                ++counter;
                Assert.IsInstanceOf <GlobalVariable>(g);
                Assert.AreSame(g, gv);
            }

            Assert.AreEqual(1, counter);

            // Change Metadata in p2, this shouldn't affect p
            string newMetaDataString = "Another test";

            p2.SetMetadata(0, newMetaDataString);

            Assert.AreNotEqual(p2.GetMetadata <string>(0), p.GetMetadata <string>(0));
        }
示例#23
0
 public override TypedIdent VisitTypedIdent(TypedIdent node)
 {
     add(node);
     return(base.VisitTypedIdent(node));
 }
示例#24
0
 public override TypedIdent VisitTypedIdent(TypedIdent node)
 {
     return(base.VisitTypedIdent((TypedIdent)node.Clone()));
 }
        public static Variable MakeAsyncHandleVariable(string name, AccessType access, Type type)
        {
            var ident = new TypedIdent(Token.NoToken, MakeAsyncHandleVariableName(name, access), type);

            return(new GlobalVariable(Token.NoToken, ident));
        }
示例#26
0
        public void RemoveOneConstraintBasedOnVarsAndFunctions()
        {
            IConstraintManager CM = new ConstraintManager();
            var builder           = GetBuilder();

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

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

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

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

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

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

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

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

            // The query expression does not use the "foobar" function so we don't need to keep constraints on that function
            Expr queryExpr = builder.Eq(builder.BVAND(s1, s2), builder.ConstantBV(0, 8));


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

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

            bool c0Found = false;
            bool c1Found = false;

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

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

            Assert.IsTrue(c0Found);
            Assert.IsTrue(c1Found);
        }
示例#27
0
 public override TypedIdent VisitTypedIdent(TypedIdent node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <TypedIdent>() != null);
     return(base.VisitTypedIdent((TypedIdent)node.Clone()));
 }
示例#28
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;
      }
示例#29
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;
      }