Example #1
0
        public override void ComputeFreeVariables(Set freeVars)
        {
            //Contract.Requires(freeVars != null);

            foreach (var v in Dummies)
            {
                Contract.Assert(v != null);
                Contract.Assert(!freeVars[v]);
            }
            Body.ComputeFreeVariables(freeVars);
            for (var a = Attributes; a != null; a = a.Next)
            {
                foreach (var o in a.Params)
                {
                    var e = o as Expr;
                    if (e != null)
                    {
                        e.ComputeFreeVariables(freeVars);
                    }
                }
            }
            foreach (var v in Dummies)
            {
                freeVars.AddRange(v.TypedIdent.Type.FreeVariables);
            }
            freeVars.RemoveRange(Dummies);
            foreach (var e in Rhss)
            {
                e.ComputeFreeVariables(freeVars);
            }
        }
Example #2
0
 public override void ComputeFreeVariables(Set /*Variable*/ freeVars)
 {
     //Contract.Requires(freeVars != null);
     foreach (Variable /*!*/ v in Dummies)
     {
         Contract.Assert(v != null);
         Contract.Assert(!freeVars[v]);
     }
     Body.ComputeFreeVariables(freeVars);
     foreach (Variable /*!*/ v in Dummies)
     {
         Contract.Assert(v != null);
         foreach (TypeVariable /*!*/ w in v.TypedIdent.Type.FreeVariables)
         {
             Contract.Assert(w != null);
             freeVars.Add(w);
         }
     }
     foreach (Variable /*!*/ v in Dummies)
     {
         Contract.Assert(v != null);
         freeVars.Remove(v);
     }
     foreach (TypeVariable /*!*/ v in TypeParameters)
     {
         Contract.Assert(v != null);
         freeVars.Remove(v);
     }
 }
Example #3
0
 /// <summary>
 /// Add to "freeVars" the free variables in the triggering expressions.
 /// </summary>
 public void ComputeFreeVariables(Set /*Variable*/ freeVars)
 {
     Contract.Requires(freeVars != null);
     foreach (Expr /*!*/ e in this.Tr)
     {
         Contract.Assert(e != null);
         e.ComputeFreeVariables(freeVars);
     }
 }
Example #4
0
 public override Expr VisitOldExpr(OldExpr node) {
   Set freeVars = new Set();
   node.Expr.ComputeFreeVariables(freeVars);
   foreach (var v in freeVars) {
     // Note, "v" is either a Variable or a TypeVariable
     if (v is Variable) {
       FreeOldVars.Add((Variable)v);
     }
   }
   return node;  // don't visit subexpressions, since ComputeFreeVariables has already gone through those
 }
Example #5
0
 public override void ComputeFreeVariables(Set /*Variable*/ freeVars)
 {
     //Contract.Requires(freeVars != null);
       foreach (Variable/*!*/ v in Dummies) {
     Contract.Assert(v != null);
     Contract.Assert(!freeVars[v]);
       }
       Body.ComputeFreeVariables(freeVars);
       foreach (Variable/*!*/ v in Dummies) {
     Contract.Assert(v != null);
     foreach (TypeVariable/*!*/ w in v.TypedIdent.Type.FreeVariables) {
       Contract.Assert(w != null);
       freeVars.Add(w);
     }
       }
       foreach (Variable/*!*/ v in Dummies) {
     Contract.Assert(v != null);
     freeVars.Remove(v);
       }
       foreach (TypeVariable/*!*/ v in TypeParameters) {
     Contract.Assert(v != null);
     freeVars.Remove(v);
       }
 }
Example #6
0
        public static void ComputeBinderFreeVariables(List <TypeVariable> typeParameters, List <Variable> dummies, Expr body, QKeyValue attributes, Set freeVars)
        {
            Contract.Requires(dummies != null);
            Contract.Requires(body != null);

            foreach (var v in dummies)
            {
                Contract.Assert(v != null);
                Contract.Assert(!freeVars[v]);
            }
            body.ComputeFreeVariables(freeVars);
            for (var a = attributes; a != null; a = a.Next)
            {
                foreach (var o in a.Params)
                {
                    var e = o as Expr;
                    if (e != null)
                    {
                        e.ComputeFreeVariables(freeVars);
                    }
                }
            }
            foreach (var v in dummies)
            {
                freeVars.AddRange(v.TypedIdent.Type.FreeVariables);
            }
            freeVars.RemoveRange(dummies);
            freeVars.RemoveRange(typeParameters);
        }
Example #7
0
 public override void ComputeFreeVariables(Set freeVars)
 {
     //Contract.Requires(freeVars != null);
     ComputeBinderFreeVariables(TypeParameters, Dummies, Body, Attributes, freeVars);
 }
Example #8
0
 /// <summary>
 /// Add to "freeVars" the free variables in the triggering expressions.
 /// </summary>
 public void ComputeFreeVariables(Set /*Variable*/ freeVars) {
   Contract.Requires(freeVars != null);
   foreach (Expr/*!*/ e in this.Tr) {
     Contract.Assert(e != null);
     e.ComputeFreeVariables(freeVars);
   }
 }
Example #9
0
    public static void ComputeBinderFreeVariables(List<TypeVariable> typeParameters, List<Variable> dummies, Expr body, QKeyValue attributes, Set freeVars) {
      Contract.Requires(dummies != null);
      Contract.Requires(body != null);

      foreach (var v in dummies) {
        Contract.Assert(v != null);
        Contract.Assert(!freeVars[v]);
      }
      body.ComputeFreeVariables(freeVars);
      for (var a = attributes; a != null; a = a.Next) {
        foreach (var o in a.Params) {
          var e = o as Expr;
          if (e != null) {
            e.ComputeFreeVariables(freeVars);
          }
        }
      }
      foreach (var v in dummies) {
        freeVars.AddRange(v.TypedIdent.Type.FreeVariables);
      }
      freeVars.RemoveRange(dummies);
      freeVars.RemoveRange(typeParameters);
    }
Example #10
0
 public override void ComputeFreeVariables(Set freeVars) {
   //Contract.Requires(freeVars != null);
   ComputeBinderFreeVariables(TypeParameters, Dummies, Body, Attributes, freeVars);
 }
Example #11
0
      public override Expr VisitLambdaExpr(LambdaExpr lambda) {
        var baseResult = base.VisitLambdaExpr(lambda);
        lambda = baseResult as LambdaExpr;
        if (lambda == null) {
          return baseResult;  // apparently, the base visitor already turned the lambda into something else
        }

        // 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.SubstitutionFromHashtable(new Dictionary<Variable,Expr>()),
          Substituter.SubstitutionFromHashtable(oldSubst),
          lambda.Body);
        var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromHashtable(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> { "stable" }, 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, 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.SubstitutionFromHashtable(substFnAttrs), lambdaAttrs));

          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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(subst), lambdaAttrs),
            trig, body));
        }

        NAryExpr call = new NAryExpr(tok, fcall, callArgs);
        call.Type = res.TypedIdent.Type;
        call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);

        return call;
      }
Example #12
0
    void CreateProceduresForLoops(Implementation impl, Graph<Block/*!*/>/*!*/ g,
                                  List<Implementation/*!*/>/*!*/ loopImpls,
                                  Dictionary<string, Dictionary<string, Block>> fullMap) {
      Contract.Requires(impl != null);
      Contract.Requires(cce.NonNullElements(loopImpls));
      // Enumerate the headers
      // for each header h:
      //   create implementation p_h with
      //     inputs = inputs, outputs, and locals of impl
      //     outputs = outputs and locals of impl
      //     locals = empty set
      //   add call o := p_h(i) at the beginning of the header block
      //   break the back edges whose target is h
      // Enumerate the headers again to create the bodies of p_h
      // for each header h:
      //   compute the loop corresponding to h
      //   make copies of all blocks in the loop for h
      //   delete all target edges that do not go to a block in the loop
      //   create a new entry block and a new return block
      //   add edges from entry block to the loop header and the return block
      //   add calls o := p_h(i) at the end of the blocks that are sources of back edges
      foreach (Block block in impl.Blocks)
      {
          AddToFullMap(fullMap, impl.Name, block.Label, block);
      }

      bool detLoopExtract = CommandLineOptions.Clo.DeterministicExtractLoops;

      Dictionary<Block/*!*/, List<Variable>/*!*/>/*!*/ loopHeaderToInputs = new Dictionary<Block/*!*/, List<Variable>/*!*/>();
      Dictionary<Block/*!*/, List<Variable>/*!*/>/*!*/ loopHeaderToOutputs = new Dictionary<Block/*!*/, List<Variable>/*!*/>();
      Dictionary<Block/*!*/, Dictionary<Variable, Expr>/*!*/>/*!*/ loopHeaderToSubstMap = new Dictionary<Block/*!*/, Dictionary<Variable, Expr>/*!*/>();
      Dictionary<Block/*!*/, LoopProcedure/*!*/>/*!*/ loopHeaderToLoopProc = new Dictionary<Block/*!*/, LoopProcedure/*!*/>();
      Dictionary<Block/*!*/, CallCmd/*!*/>/*!*/ loopHeaderToCallCmd1 = new Dictionary<Block/*!*/, CallCmd/*!*/>();
      Dictionary<Block, CallCmd> loopHeaderToCallCmd2 = new Dictionary<Block, CallCmd>();
      Dictionary<Block, AssignCmd> loopHeaderToAssignCmd = new Dictionary<Block, AssignCmd>();

      foreach (Block/*!*/ header in g.Headers) {
        Contract.Assert(header != null);
        Contract.Assert(header != null);
        List<Variable> inputs = new List<Variable>();
        List<Variable> outputs = new List<Variable>();
        List<Expr> callInputs1 = new List<Expr>();
        List<IdentifierExpr> callOutputs1 = new List<IdentifierExpr>();
        List<Expr> callInputs2 = new List<Expr>();
        List<IdentifierExpr> callOutputs2 = new List<IdentifierExpr>();
        List<AssignLhs> lhss = new List<AssignLhs>();
        List<Expr> rhss = new List<Expr>();
        Dictionary<Variable, Expr> substMap = new Dictionary<Variable, Expr>(); // Variable -> IdentifierExpr

        List<Variable>/*!*/ targets = new List<Variable>();
        HashSet<Variable> footprint = new HashSet<Variable>();

        foreach (Block/*!*/ b in g.BackEdgeNodes(header))
        {
            Contract.Assert(b != null);
            foreach (Block/*!*/ block in g.NaturalLoops(header, b))
            {
                Contract.Assert(block != null);
                foreach (Cmd/*!*/ cmd in block.Cmds)
                {
                    Contract.Assert(cmd != null);
                    cmd.AddAssignedVariables(targets);

                    VariableCollector c = new VariableCollector();
                    c.Visit(cmd);
                    footprint.UnionWith(c.usedVars);
                }
            }
        }

        List<IdentifierExpr>/*!*/ globalMods = new List<IdentifierExpr>();
        Set targetSet = new Set();
        foreach (Variable/*!*/ v in targets)
        {
            Contract.Assert(v != null);
            if (targetSet.Contains(v))
                continue;
            targetSet.Add(v);
            if (v is GlobalVariable)
                globalMods.Add(new IdentifierExpr(Token.NoToken, v));
        }

        foreach (Variable v in impl.InParams) {
          Contract.Assert(v != null);
          if (!footprint.Contains(v)) continue;
          callInputs1.Add(new IdentifierExpr(Token.NoToken, v));
          Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "in_" + v.Name, v.TypedIdent.Type), true);
          inputs.Add(f);
          callInputs2.Add(new IdentifierExpr(Token.NoToken, f));
          substMap[v] = new IdentifierExpr(Token.NoToken, f);
        }
        foreach (Variable v in impl.OutParams) {
          Contract.Assert(v != null);
          if (!footprint.Contains(v)) continue;
          callInputs1.Add(new IdentifierExpr(Token.NoToken, v));
          Formal f1 = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "in_" + v.Name, v.TypedIdent.Type), true);
          inputs.Add(f1);
          if (targetSet.Contains(v))
          {
              callOutputs1.Add(new IdentifierExpr(Token.NoToken, v));
              Formal f2 = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "out_" + v.Name, v.TypedIdent.Type), false);
              outputs.Add(f2);
              callInputs2.Add(new IdentifierExpr(Token.NoToken, f2));
              callOutputs2.Add(new IdentifierExpr(Token.NoToken, f2));
              lhss.Add(new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, f2)));
              rhss.Add(new IdentifierExpr(Token.NoToken, f1));
              substMap[v] = new IdentifierExpr(Token.NoToken, f2);
          }
          else
          {
              callInputs2.Add(new IdentifierExpr(Token.NoToken, f1));
              substMap[v] = new IdentifierExpr(Token.NoToken, f1);
          }
        }
        foreach (Variable v in impl.LocVars) {
          Contract.Assert(v != null);
          if (!footprint.Contains(v)) continue;
          callInputs1.Add(new IdentifierExpr(Token.NoToken, v));
          Formal f1 = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "in_" + v.Name, v.TypedIdent.Type), true);
          inputs.Add(f1);
          if (targetSet.Contains(v))
          {
              callOutputs1.Add(new IdentifierExpr(Token.NoToken, v));
              Formal f2 = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "out_" + v.Name, v.TypedIdent.Type), false);
              outputs.Add(f2);
              callInputs2.Add(new IdentifierExpr(Token.NoToken, f2));
              callOutputs2.Add(new IdentifierExpr(Token.NoToken, f2));
              lhss.Add(new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, f2)));
              rhss.Add(new IdentifierExpr(Token.NoToken, f1));
              substMap[v] = new IdentifierExpr(Token.NoToken, f2);
          }
          else
          {
              callInputs2.Add(new IdentifierExpr(Token.NoToken, f1));
              substMap[v] = new IdentifierExpr(Token.NoToken, f1);
          }
        }

        loopHeaderToInputs[header] = inputs;
        loopHeaderToOutputs[header] = outputs;
        loopHeaderToSubstMap[header] = substMap;
        LoopProcedure loopProc = new LoopProcedure(impl, header, inputs, outputs, globalMods);
        loopHeaderToLoopProc[header] = loopProc;

        CallCmd callCmd1 = new CallCmd(Token.NoToken, loopProc.Name, callInputs1, callOutputs1);
        callCmd1.Proc = loopProc;
        loopHeaderToCallCmd1[header] = callCmd1;

        CallCmd callCmd2 = new CallCmd(Token.NoToken, loopProc.Name, callInputs2, callOutputs2);
        callCmd2.Proc = loopProc;
        loopHeaderToCallCmd2[header] = callCmd2;

        Debug.Assert(lhss.Count == rhss.Count);
        if (lhss.Count > 0)
        {
            AssignCmd assignCmd = new AssignCmd(Token.NoToken, lhss, rhss);
            loopHeaderToAssignCmd[header] = assignCmd;
        }
      }

      // Keep track of the new blocks created: maps a header node to the
      // header_last block that was created because of splitting header.
      Dictionary<Block, Block> newBlocksCreated = new Dictionary<Block, Block>();

      bool headRecursion = false; // testing an option to put recursive call before loop body

      IEnumerable<Block> sortedHeaders = g.SortHeadersByDominance();
      foreach (Block/*!*/ header in sortedHeaders)
      {
        Contract.Assert(header != null);
        LoopProcedure loopProc = loopHeaderToLoopProc[header];
        Dictionary<Block, Block> blockMap = new Dictionary<Block, Block>();
        HashSet<string> dummyBlocks = new HashSet<string>();

        CodeCopier codeCopier = new CodeCopier(loopHeaderToSubstMap[header]);  // fix me
        List<Variable> inputs = loopHeaderToInputs[header];
        List<Variable> outputs = loopHeaderToOutputs[header];
        int si_unique_loc = 1; // Added by AL: to distinguish the back edges
        foreach (Block/*!*/ source in g.BackEdgeNodes(header)) {
          Contract.Assert(source != null);
          foreach (Block/*!*/ block in g.NaturalLoops(header, source)) {
            Contract.Assert(block != null);
            if (blockMap.ContainsKey(block))
              continue;
            Block newBlock = new Block();
            newBlock.Label = block.Label;
            if (headRecursion && block == header)
            {
                CallCmd callCmd = (CallCmd)(loopHeaderToCallCmd2[header]).Clone();
                addUniqueCallAttr(si_unique_loc, callCmd);
                si_unique_loc++;
                newBlock.Cmds.Add(callCmd);  // add the recursive call at head of loop
                var rest = codeCopier.CopyCmdSeq(block.Cmds);
                newBlock.Cmds.AddRange(rest);
            }
            else
              newBlock.Cmds = codeCopier.CopyCmdSeq(block.Cmds);
            blockMap[block] = newBlock;
            if (newBlocksCreated.ContainsKey(block))
            {
                Block newBlock2 = new Block();
                newBlock2.Label = newBlocksCreated[block].Label;
                newBlock2.Cmds = codeCopier.CopyCmdSeq(newBlocksCreated[block].Cmds);
                blockMap[newBlocksCreated[block]] = newBlock2;
            }
            //for detLoopExtract, need the immediate successors even outside the loop
            if (detLoopExtract) {
                GotoCmd auxGotoCmd = block.TransferCmd as GotoCmd;
                Contract.Assert(auxGotoCmd != null && auxGotoCmd.labelNames != null && 
                    auxGotoCmd.labelTargets != null && auxGotoCmd.labelTargets.Count >= 1);
                foreach(var bl in auxGotoCmd.labelTargets) {
                    bool found = false;
                    foreach(var n in g.NaturalLoops(header, source)) { //very expensive, can we do a contains?
                        if (bl == n) { //clarify: is this the right comparison?
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        Block auxNewBlock = new Block();
                        auxNewBlock.Label = ((Block)bl).Label;
                        auxNewBlock.Cmds = codeCopier.CopyCmdSeq(((Block)bl).Cmds);
                        //add restoration code for such blocks
                        if (loopHeaderToAssignCmd.ContainsKey(header))
                        {
                            AssignCmd assignCmd = loopHeaderToAssignCmd[header];
                            auxNewBlock.Cmds.Add(assignCmd);
                        }
                        List<AssignLhs> lhsg = new List<AssignLhs>();
                        List<IdentifierExpr>/*!*/ globalsMods = loopHeaderToLoopProc[header].Modifies;
                        foreach (IdentifierExpr gl in globalsMods)
                            lhsg.Add(new SimpleAssignLhs(Token.NoToken, gl));
                        List<Expr> rhsg = new List<Expr>();
                        foreach (IdentifierExpr gl in globalsMods)
                            rhsg.Add(new OldExpr(Token.NoToken, gl));
                        if (lhsg.Count != 0)
                        {
                            AssignCmd globalAssignCmd = new AssignCmd(Token.NoToken, lhsg, rhsg);
                            auxNewBlock.Cmds.Add(globalAssignCmd);
                        }
                        blockMap[(Block)bl] = auxNewBlock;
                    }
                }

            }
          }

          List<Cmd> cmdSeq;
          if (headRecursion)
              cmdSeq = new List<Cmd>();
          else
          {
              CallCmd callCmd = (CallCmd)(loopHeaderToCallCmd2[header]).Clone();
              addUniqueCallAttr(si_unique_loc, callCmd);
              si_unique_loc++;
              cmdSeq = new List<Cmd> { callCmd };
          }

          Block/*!*/ block1 = new Block(Token.NoToken, source.Label + "_dummy",
                              new List<Cmd>{ new AssumeCmd(Token.NoToken, Expr.False) }, new ReturnCmd(Token.NoToken));
          Block/*!*/ block2 = new Block(Token.NoToken, block1.Label,
                              cmdSeq, new ReturnCmd(Token.NoToken));
          impl.Blocks.Add(block1);
          dummyBlocks.Add(block1.Label);

          GotoCmd gotoCmd = source.TransferCmd as GotoCmd;
          Contract.Assert(gotoCmd != null && gotoCmd.labelNames != null && gotoCmd.labelTargets != null && gotoCmd.labelTargets.Count >= 1);
          List<String>/*!*/ newLabels = new List<String>();
          List<Block>/*!*/ newTargets = new List<Block>();
          for (int i = 0; i < gotoCmd.labelTargets.Count; i++) {
            if (gotoCmd.labelTargets[i] == header)
              continue;
            newTargets.Add(gotoCmd.labelTargets[i]);
            newLabels.Add(gotoCmd.labelNames[i]);
          }
          newTargets.Add(block1);
          newLabels.Add(block1.Label);
          gotoCmd.labelNames = newLabels;
          gotoCmd.labelTargets = newTargets;
          blockMap[block1] = block2;
        }
        List<Block/*!*/>/*!*/ blocks = new List<Block/*!*/>();
        Block exit = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken));
        GotoCmd cmd = new GotoCmd(Token.NoToken,
                                    new List<String> { cce.NonNull(blockMap[header]).Label, exit.Label },
                                    new List<Block> { blockMap[header], exit });

        if (detLoopExtract) //cutting the non-determinism
            cmd = new GotoCmd(Token.NoToken,
                                    new List<String> { cce.NonNull(blockMap[header]).Label },
                                    new List<Block> { blockMap[header] });

        Block entry;
        List<Cmd> initCmds = new List<Cmd>();
        if (loopHeaderToAssignCmd.ContainsKey(header)) {
            AssignCmd assignCmd = loopHeaderToAssignCmd[header];
            initCmds.Add(assignCmd);
        }

        entry = new Block(Token.NoToken, "entry", initCmds, cmd);
        blocks.Add(entry);

        foreach (Block/*!*/ block in blockMap.Keys) {
          Contract.Assert(block != null);
          Block/*!*/ newBlock = cce.NonNull(blockMap[block]);
          GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
          if (gotoCmd == null) {
            newBlock.TransferCmd = new ReturnCmd(Token.NoToken);
          } else {
            Contract.Assume(gotoCmd.labelNames != null && gotoCmd.labelTargets != null);
            List<String> newLabels = new List<String>();
            List<Block> newTargets = new List<Block>();
            for (int i = 0; i < gotoCmd.labelTargets.Count; i++) {
              Block target = gotoCmd.labelTargets[i];
              if (blockMap.ContainsKey(target)) {
                newLabels.Add(gotoCmd.labelNames[i]);
                newTargets.Add(blockMap[target]);
              }  
            }
            if (newTargets.Count == 0) {
                if (!detLoopExtract)
                    newBlock.Cmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                newBlock.TransferCmd = new ReturnCmd(Token.NoToken);
            } else {
              newBlock.TransferCmd = new GotoCmd(Token.NoToken, newLabels, newTargets);
            }
          }
          blocks.Add(newBlock);
        }
        blocks.Add(exit);
        Implementation loopImpl =
            new Implementation(Token.NoToken, loopProc.Name,
                                new List<TypeVariable>(), inputs, outputs, new List<Variable>(), blocks);
        loopImpl.Proc = loopProc;
        loopImpls.Add(loopImpl);

        // Make a (shallow) copy of the header before splitting it
        Block origHeader = new Block(header.tok, header.Label, header.Cmds, header.TransferCmd);

        // Finally, add call to the loop in the containing procedure
        string lastIterBlockName = header.Label + "_last";
        Block lastIterBlock = new Block(Token.NoToken, lastIterBlockName, header.Cmds, header.TransferCmd);
        newBlocksCreated[header] = lastIterBlock;
        header.Cmds = new List<Cmd> { loopHeaderToCallCmd1[header] };
        header.TransferCmd = new GotoCmd(Token.NoToken, new List<String> { lastIterBlockName }, new List<Block> { lastIterBlock });
        impl.Blocks.Add(lastIterBlock);
        blockMap[origHeader] = blockMap[header];
        blockMap.Remove(header);

        Contract.Assert(fullMap[impl.Name][header.Label] == header);
        fullMap[impl.Name][header.Label] = origHeader;

        foreach (Block block in blockMap.Keys)
        {
            // Don't add dummy blocks to the map
            if (dummyBlocks.Contains(blockMap[block].Label)) continue;

            // Following two statements are for nested loops: compose map
            if (!fullMap[impl.Name].ContainsKey(block.Label)) continue;
            var target = fullMap[impl.Name][block.Label];

            AddToFullMap(fullMap, loopProc.Name, blockMap[block].Label, target);
        }

        fullMap[impl.Name].Remove(header.Label);
        fullMap[impl.Name][lastIterBlockName] = origHeader;
      }
    }
Example #13
0
      public override Expr VisitLambdaExpr(LambdaExpr lambda) {
        var baseResult = base.VisitLambdaExpr(lambda);
        lambda = baseResult as LambdaExpr;
        if (lambda == null) {
          return baseResult;  // apparently, the base visitor already turned the lambda into something else
        }

        // 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.SubstitutionFromHashtable(new Dictionary<Variable,Expr>()),
          Substituter.SubstitutionFromHashtable(oldSubst),
          lambda.Body);
        var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromHashtable(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, 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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(subst), lambdaAttrs),
            trig, body));
        }

        NAryExpr call = new NAryExpr(tok, fcall, callArgs);
        call.Type = res.TypedIdent.Type;
        call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);

        return call;
      }
Example #14
0
 public override Expr VisitOldExpr(OldExpr node) {
   Set freeVars = new Set();
   node.Expr.ComputeFreeVariables(freeVars);
   foreach (var v in freeVars) {
     // Note, "v" is either a Variable or a TypeVariable
     if (v is Variable) {
       FreeOldVars.Add((Variable)v);
     }
   }
   return node;  // don't visit subexpressions, since ComputeFreeVariables has already gone through those
 }
Example #15
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;
            }
Example #16
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;
      }