Beispiel #1
0
      /// <summary>
      /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing with bound variables
      /// maximally large subexpressions of a lambda that do not contain any of the lambda's bound variables.
      /// </summary>
      /// <param name="lambda">A lambda expression
      ///   <code>(lambda x1: T1 ... x_n: T_n :: t)</code>
      /// where <c>t</c> contains the subexpressions <c>e1</c>, ..., <c>e_m</c>. These are maximally large
      /// subexpressions that do not contain the lambda's bound variables.
      /// </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 expressions <c>e1</c>, ..., <c>e_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 LiftLambdaMaxHoles(LambdaExpr lambda)
      {
        // We start by getting rid of `old` expressions. Instead, we replace the free variables `x_i` that are
        // nested inside of `old` expressions with `old(x_i)` expressions.
        var oldFinder = new OldFinder();
        oldFinder.Visit(lambda);
        var oldSubst = new Dictionary<Variable, Expr>();
        foreach (var v in oldFinder.FreeOldVars)
          if (v is GlobalVariable g)
          {
            oldSubst.Add(g, new OldExpr(g.tok, new IdentifierExpr(g.tok, g)) {Type = g.TypedIdent.Type});
          }

        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);
        var newLambda =
          new LambdaExpr(lambda.tok, lambda.TypeParameters, lambda.Dummies, lambdaAttrs, lambdaBody)
          {
            Type = lambda.Type
          };

        // We perform lambda lifting on the resulting lambda which now contains only `old` expressions of the form
        // `old(x)` where `x` is a variable that is free in the lambda.
        return new MaxHolesLambdaLifter(
            newLambda, liftedLambdas, FreshLambdaFunctionName(), lambdaFunctions, lambdaAxioms)
          .VisitLambdaExpr(newLambda);
      }
Beispiel #2
0
 public Cmd CopyCmd(Cmd cmd) {
   Contract.Requires(cmd != null);
   Contract.Ensures(Contract.Result<Cmd>() != null);
   if (Subst == null) {
     return cmd;
   } else if (OldSubst == null) {
     return Substituter.Apply(Subst, cmd);
   } else {
     return Substituter.ApplyReplacingOldExprs(Subst, OldSubst, cmd);
   }
 }
Beispiel #3
0
 public Expr CopyExpr(Expr expr) {
   Contract.Requires(expr != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   if (Subst == null) {
     return expr;
   } else if (OldSubst == null) {
     return Substituter.Apply(Subst, expr);
   } else {
     return Substituter.ApplyReplacingOldExprs(Subst, OldSubst, expr);
   }
 }
Beispiel #4
0
 public Cmd CopyCmd(Cmd cmd)
 {
   if (substMap == null)
   {
     return cmd;
   }
   var newCmd = BoundVarAndReplacingOldSubstituter.Apply(substMap, oldSubstMap, prefix, cmd);
   if (cmd is ICarriesAttributes attrCmd && attrCmd.Attributes != null)
   {
     var attrCopy = (QKeyValue) attrCmd.Attributes.Clone();
     ((ICarriesAttributes) newCmd).Attributes = Substituter.ApplyReplacingOldExprs(PartialSubst, PartialOldSubst, attrCopy);
   }
   return newCmd;
 }
Beispiel #5
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;
      }
            private void IntroduceIntermediateVars()
            {
                var oldSub = SubstitutionHelper.FromVariableMap(LatestCopies(trc.PreStateVars));

                assignments = new List <Assignment>();
                assumes     = new List <Expr>();
                for (int k = 0; k < trc.path.Count; k++)
                {
                    if (trc.IsJoint && k == trc.transferIndex)
                    {
                        PopulateIntermediateFrameCopy();
                        oldSub = SubstitutionHelper.FromVariableMap(LatestCopies(trc.PreStateVars));
                    }
                    Cmd cmd = trc.path[k];
                    if (cmd is AssignCmd assignCmd)
                    {
                        assignCmd = assignCmd.AsSimpleAssignCmd;
                        var preState = LatestCopies();
                        foreach (var v in assignCmd.Lhss)
                        {
                            MakeNewCopy(v.DeepAssignedVariable);
                        }
                        var postState = LatestCopies();

                        if (QKeyValue.FindBoolAttribute(assignCmd.Attributes, CivlAttributes.BACKWARD))
                        {
                            var tmp = preState;
                            preState  = postState;
                            postState = tmp;
                        }

                        var rhsSub = SubstitutionHelper.FromVariableMap(preState);

                        for (int i = 0; i < assignCmd.Lhss.Count; i++)
                        {
                            var var  = postState[assignCmd.Lhss[i].DeepAssignedVariable];
                            var expr = Substituter.ApplyReplacingOldExprs(rhsSub, oldSub, assignCmd.Rhss[i]);
                            assignments.Add(new Assignment(var, expr));
                        }
                    }
                    else if (cmd is AssumeCmd assumeCmd)
                    {
                        var sub = SubstitutionHelper.FromVariableMap(LatestCopies());
                        assumes.Add(Substituter.ApplyReplacingOldExprs(sub, oldSub, assumeCmd.Expr));
                    }
                    else if (cmd is HavocCmd havocCmd)
                    {
                        foreach (var v in havocCmd.Vars)
                        {
                            MakeNewCopy(v.Decl);
                        }
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
                // In case there were no commands from the second action
                if (trc.IsJoint && trc.path.Count == trc.transferIndex)
                {
                    PopulateIntermediateFrameCopy();
                }
            }
Beispiel #7
0
        public ActionRefinementInstrumentation(
            CivlTypeChecker civlTypeChecker,
            Implementation impl,
            Implementation originalImpl,
            Dictionary <Variable, Variable> oldGlobalMap)
        {
            this.civlTypeChecker = civlTypeChecker;
            this.tok             = impl.tok;
            this.oldGlobalMap    = new Dictionary <Variable, Variable>();
            ActionProc actionProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc] as ActionProc;

            this.layerNum = actionProc.upperLayer;
            foreach (Variable v in civlTypeChecker.GlobalVariables)
            {
                var layerRange = civlTypeChecker.GlobalVariableLayerRange(v);
                if (layerRange.lowerLayerNum <= layerNum && layerNum < layerRange.upperLayerNum)
                {
                    this.oldGlobalMap[v] = oldGlobalMap[v];
                }
            }

            this.newLocalVars = new List <Variable>();
            pc = civlTypeChecker.LocalVariable("pc", Type.Bool);
            newLocalVars.Add(pc);
            ok = civlTypeChecker.LocalVariable("ok", Type.Bool);
            newLocalVars.Add(ok);

            this.transitionRelationCache = new Dictionary <AtomicAction, Expr>();

            oldOutputMap = new Dictionary <Variable, Variable>();
            foreach (Variable f in impl.OutParams)
            {
                LocalVariable copy = Old(f);
                newLocalVars.Add(copy);
                oldOutputMap[f] = copy;
            }

            Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>();

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                foroldMap[g] = Expr.Ident(oldGlobalMap[g]);
            }

            // The parameters of an atomic action come from the implementation that denotes the atomic action specification.
            // To use the transition relation computed below in the context of the yielding procedure of the refinement check,
            // we need to substitute the parameters.
            AtomicAction   atomicAction           = actionProc.refinedAction;
            Implementation atomicActionImpl       = atomicAction.impl;
            Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>();

            for (int i = 0, j = 0; i < impl.InParams.Count; i++)
            {
                if (civlTypeChecker.FormalRemainsInAction(actionProc, actionProc.proc.InParams[i]))
                {
                    alwaysMap[atomicActionImpl.InParams[j]] = Expr.Ident(impl.InParams[i]);
                    j++;
                }
            }

            for (int i = 0, j = 0; i < impl.OutParams.Count; i++)
            {
                if (civlTypeChecker.FormalRemainsInAction(actionProc, actionProc.proc.OutParams[i]))
                {
                    alwaysMap[atomicActionImpl.OutParams[j]] = Expr.Ident(impl.OutParams[i]);
                    j++;
                }
            }

            if (atomicAction.HasPendingAsyncs)
            {
                Variable collectedPAs = civlTypeChecker.implToPendingAsyncCollector[originalImpl];
                alwaysMap[atomicActionImpl.OutParams.Last()] = Expr.Ident(collectedPAs);
                LocalVariable copy = Old(collectedPAs);
                newLocalVars.Add(copy);
                oldOutputMap[collectedPAs] = copy;
            }

            Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap);
            Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap);
            Expr         transitionRelationExpr = GetTransitionRelation(atomicAction);

            transitionRelation = Substituter.ApplyReplacingOldExprs(always, forold, transitionRelationExpr);
            Expr gateExpr = Expr.And(atomicAction.gate.Select(g => g.Expr));

            gateExpr.Type = Type.Bool;
            gate          = Substituter.Apply(always, gateExpr);
        }
Beispiel #8
0
        public List <Declaration> CreateYieldCheckerProcImpl(
            Implementation impl,
            IEnumerable <List <PredicateCmd> > yields)
        {
            Dictionary <Variable, Expr> map    = new Dictionary <Variable, Expr>();
            List <Variable>             locals = new List <Variable>();
            List <Variable>             inputs = new List <Variable>();

            foreach (Variable local in impl.LocVars.Union(impl.InParams).Union(impl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                map[local] = Expr.Ident(copy);
            }

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                map[linearTypeChecker.domainNameToHoleVar[domainName]] = Expr.Ident(inParam);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.sharedVariables)
            {
                var copy = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            Substitution  assumeSubst        = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst           = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst              = Substituter.SubstitutionFromHashtable(map);
            List <Block>  yieldCheckerBlocks = new List <Block>();
            List <String> labels             = new List <String>();
            List <Block>  labelTargets       = new List <Block>();
            Block         yieldCheckerBlock  = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(yieldCheckerBlock.Label);
            labelTargets.Add(yieldCheckerBlock);
            yieldCheckerBlocks.Add(yieldCheckerBlock);
            int yieldCount = 0;

            foreach (var cs in yields)
            {
                List <Cmd> newCmds = new List <Cmd>();
                foreach (var predCmd in cs)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in cs)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }

                    /*
                     * Disjointness assumes injected by LinearTypeChecker are dropped now because the
                     * previous loop has already substituted the old global state in these assumes.
                     * It would be unsound to have these assumes on the current global state.
                     */
                }

                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(yieldCheckerBlock.Label);
                labelTargets.Add(yieldCheckerBlock);
                yieldCheckerBlocks.Add(yieldCheckerBlock);
            }

            yieldCheckerBlocks.Insert(0,
                                      new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var yieldCheckerName = $"Impl_YieldChecker_{impl.Name}";
            var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                 new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(yieldCheckerProc);

            // Create the yield checker implementation
            var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                      new List <Variable>(), locals, yieldCheckerBlocks);

            yieldCheckerImpl.Proc = yieldCheckerProc;
            CivlUtil.AddInlineAttribute(yieldCheckerImpl);
            return(new List <Declaration> {
                yieldCheckerProc, yieldCheckerImpl
            });
        }
Beispiel #9
0
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            int layerNum,
            AbsyMap absyMap,
            DeclWithFormals decl,
            List <Variable> declLocalVariables)
        {
            var linearTypeChecker = civlTypeChecker.linearTypeChecker;
            Dictionary <string, Variable>   domainNameToHoleVar = new Dictionary <string, Variable>();
            Dictionary <Variable, Variable> localVarMap         = new Dictionary <Variable, Variable>();
            Dictionary <Variable, Expr>     map = new Dictionary <Variable, Expr>();
            List <Variable> locals = new List <Variable>();
            List <Variable> inputs = new List <Variable>();

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                domainNameToHoleVar[domainName] = inParam;
            }

            foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                localVarMap[local] = copy;
                map[local]         = Expr.Ident(copy);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                var copy = OldGlobalLocal(civlTypeChecker, g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = SnapshotGlobalFormal(civlTypeChecker, g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker,
                                                                                      layerNum, absyMap, domainNameToHoleVar, localVarMap);
            List <YieldInfo> yieldInfos = null;
            string           noninterferenceCheckerName = null;

            if (decl is Implementation impl)
            {
                noninterferenceCheckerName = $"impl_{absyMap.Original(impl).Name}_{layerNum}";
                yieldInfos = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv =>
                                                                                            new YieldInfo(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList();
            }
            else if (decl is Procedure proc)
            {
                yieldInfos = new List <YieldInfo>();
                if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc))
                {
                    noninterferenceCheckerName = $"yield_{proc.Name}";
                    if (proc.Requires.Count > 0)
                    {
                        var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var yieldPredicates  = proc.Requires.Select(requires =>
                                                                    requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(disjointnessCmds, yieldPredicates));
                    }
                }
                else
                {
                    noninterferenceCheckerName = $"proc_{absyMap.Original(proc).Name}_{layerNum}";
                    if (proc.Requires.Count > 0)
                    {
                        var entryDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var entryYieldPredicates = proc.Requires.Select(requires =>
                                                                        requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(entryDisjointnessCmds, entryYieldPredicates));
                    }

                    if (proc.Ensures.Count > 0)
                    {
                        var exitDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false);
                        var exitYieldPredicates = proc.Ensures.Select(ensures =>
                                                                      ensures.Free
                ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition)
                : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(exitDisjointnessCmds, exitYieldPredicates));
                    }
                }
            }
            else
            {
                Debug.Assert(false);
            }

            var filteredYieldInfos = yieldInfos.Where(info =>
                                                      info.invariantCmds.Any(predCmd => new GlobalAccessChecker().AccessesGlobal(predCmd.Expr)));

            if (filteredYieldInfos.Count() == 0)
            {
                return(new List <Declaration>());
            }

            Substitution assumeSubst = Substituter.SubstitutionFromDictionary(assumeMap);
            Substitution oldSubst    = Substituter.SubstitutionFromDictionary(oldLocalMap);
            Substitution subst       = Substituter.SubstitutionFromDictionary(map);
            List <Block> noninterferenceCheckerBlocks = new List <Block>();
            List <Block> labelTargets = new List <Block>();
            Block        noninterferenceCheckerBlock = BlockHelper.Block("exit", new List <Cmd>());

            labelTargets.Add(noninterferenceCheckerBlock);
            noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            int yieldCount = 0;

            foreach (var kv in filteredYieldInfos)
            {
                var newCmds = new List <Cmd>(kv.disjointnessCmds);
                foreach (var predCmd in kv.invariantCmds)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(predCmd.tok, newExpr));
                }

                foreach (var predCmd in kv.invariantCmds)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                }

                newCmds.Add(CmdHelper.AssumeCmd(Expr.False));
                noninterferenceCheckerBlock = BlockHelper.Block("L" + yieldCount++, newCmds);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0, BlockHelper.Block("enter", new List <Cmd>(), labelTargets));

            // Create the yield checker procedure
            noninterferenceCheckerName = civlTypeChecker.AddNamePrefix($"NoninterferenceChecker_{noninterferenceCheckerName}");
            var noninterferenceCheckerProc = DeclHelper.Procedure(noninterferenceCheckerName,
                                                                  inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = DeclHelper.Implementation(noninterferenceCheckerProc,
                                                                       inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks);

            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }
        public SomeRefinementInstrumentation(
            CivlTypeChecker civlTypeChecker,
            Implementation impl,
            Implementation originalImpl,
            Dictionary <Variable, Variable> oldGlobalMap,
            HashSet <Block> yieldingLoopHeaders)
        {
            newLocalVars = new List <Variable>();
            YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc];
            int          layerNum     = yieldingProc.upperLayer;

            pc = Pc();
            newLocalVars.Add(pc);
            ok = Ok();
            newLocalVars.Add(ok);

            this.transitionRelationCache = new Dictionary <AtomicAction, Expr>();

            this.oldGlobalMap = new Dictionary <Variable, Variable>();
            foreach (Variable v in civlTypeChecker.sharedVariables)
            {
                var layerRange = civlTypeChecker.GlobalVariableLayerRange(v);
                if (layerRange.lowerLayerNum <= yieldingProc.upperLayer && yieldingProc.upperLayer < layerRange.upperLayerNum)
                {
                    this.oldGlobalMap[v] = oldGlobalMap[v];
                }
            }

            oldOutputMap = new Dictionary <Variable, Variable>();
            foreach (Variable f in impl.OutParams)
            {
                LocalVariable copy = Old(f);
                newLocalVars.Add(copy);
                oldOutputMap[f] = copy;
            }

            Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>();

            foreach (Variable g in civlTypeChecker.sharedVariables)
            {
                foroldMap[g] = Expr.Ident(oldGlobalMap[g]);
            }
            if (yieldingProc is ActionProc actionProc)
            {
                // The parameters of an atomic action come from the implementation that denotes the atomic action specification.
                // To use the transition relation computed below in the context of the yielding procedure of the refinement check,
                // we need to substitute the parameters.
                AtomicAction   atomicAction           = actionProc.refinedAction;
                Implementation atomicActionImpl       = atomicAction.impl;
                Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>();
                for (int i = 0; i < impl.InParams.Count; i++)
                {
                    alwaysMap[atomicActionImpl.InParams[i]] = Expr.Ident(impl.InParams[i]);
                }

                for (int i = 0; i < impl.OutParams.Count; i++)
                {
                    alwaysMap[atomicActionImpl.OutParams[i]] = Expr.Ident(impl.OutParams[i]);
                }
                if (atomicAction.HasPendingAsyncs)
                {
                    Variable collectedPAs = civlTypeChecker.implToPendingAsyncCollector[originalImpl];
                    alwaysMap[atomicActionImpl.OutParams.Last()] = Expr.Ident(collectedPAs);
                    LocalVariable copy = Old(collectedPAs);
                    newLocalVars.Add(copy);
                    oldOutputMap[collectedPAs] = copy;
                }

                Substitution always   = Substituter.SubstitutionFromHashtable(alwaysMap);
                Substitution forold   = Substituter.SubstitutionFromHashtable(foroldMap);
                Expr         betaExpr = GetTransitionRelation(atomicAction);
                beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr);
                Expr alphaExpr = Expr.And(atomicAction.gate.Select(g => g.Expr));
                alphaExpr.Type = Type.Bool;
                alpha          = Substituter.Apply(always, alphaExpr);
            }
            else
            {
                beta  = Expr.And(this.oldGlobalMap.Keys.Select(v => Expr.Eq(Expr.Ident(v), foroldMap[v])));
                alpha = Expr.True;
            }

            pcsForYieldingLoopsHeaders = new Dictionary <Block, Variable>();
            oksForYieldingLoopHeaders  = new Dictionary <Block, Variable>();
            foreach (Block header in yieldingLoopHeaders)
            {
                var pcForYieldingLoopHeader = PcForYieldingLoopHeader(header);
                newLocalVars.Add(pcForYieldingLoopHeader);
                pcsForYieldingLoopsHeaders[header] = pcForYieldingLoopHeader;
                var okForYieldingLoopHeader = OkForYieldingLoopHeader(header);
                newLocalVars.Add(okForYieldingLoopHeader);
                oksForYieldingLoopHeaders[header] = okForYieldingLoopHeader;
            }
        }
Beispiel #11
0
        public ActionRefinementInstrumentation(
            CivlTypeChecker civlTypeChecker,
            Implementation impl,
            Implementation originalImpl,
            Dictionary <Variable, Variable> oldGlobalMap) :
            base(civlTypeChecker, civlTypeChecker.procToYieldingProc[originalImpl.Proc] as ActionProc, oldGlobalMap)
        {
            newLocalVars = new List <Variable>();
            ActionProc actionProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc] as ActionProc;
            int        layerNum   = actionProc.upperLayer;

            pc = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_pc", Type.Bool));
            newLocalVars.Add(pc);
            ok = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "og_ok", Type.Bool));
            newLocalVars.Add(ok);

            this.transitionRelationCache = new Dictionary <AtomicAction, Expr>();

            oldOutputMap = new Dictionary <Variable, Variable>();
            foreach (Variable f in impl.OutParams)
            {
                LocalVariable copy = Old(f);
                newLocalVars.Add(copy);
                oldOutputMap[f] = copy;
            }

            Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>();

            foreach (Variable g in civlTypeChecker.sharedVariables)
            {
                foroldMap[g] = Expr.Ident(oldGlobalMap[g]);
            }

            // The parameters of an atomic action come from the implementation that denotes the atomic action specification.
            // To use the transition relation computed below in the context of the yielding procedure of the refinement check,
            // we need to substitute the parameters.
            AtomicAction   atomicAction           = actionProc.refinedAction;
            Implementation atomicActionImpl       = atomicAction.impl;
            Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>();

            for (int i = 0; i < impl.InParams.Count; i++)
            {
                alwaysMap[atomicActionImpl.InParams[i]] = Expr.Ident(impl.InParams[i]);
            }

            for (int i = 0; i < impl.OutParams.Count; i++)
            {
                alwaysMap[atomicActionImpl.OutParams[i]] = Expr.Ident(impl.OutParams[i]);
            }
            if (atomicAction.HasPendingAsyncs)
            {
                Variable collectedPAs = civlTypeChecker.implToPendingAsyncCollector[originalImpl];
                alwaysMap[atomicActionImpl.OutParams.Last()] = Expr.Ident(collectedPAs);
                LocalVariable copy = Old(collectedPAs);
                newLocalVars.Add(copy);
                oldOutputMap[collectedPAs] = copy;
            }

            Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap);
            Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap);
            Expr         transitionRelationExpr = GetTransitionRelation(atomicAction);

            transitionRelation = Substituter.ApplyReplacingOldExprs(always, forold, transitionRelationExpr);
            Expr gateExpr = Expr.And(atomicAction.gate.Select(g => g.Expr));

            gateExpr.Type = Type.Bool;
            gate          = Substituter.Apply(always, gateExpr);
        }
Beispiel #12
0
            private void IntroduceIntermediateVars()
            {
                var oldSub = Substituter.SubstitutionFromHashtable(GetPreStateVars().
                                                                   ToDictionary <Variable, Variable, Expr>(v => v, v => Expr.Ident(varCopies[0][v])));

                newCmds = new List <Cmd>();
                for (int k = 0; k < cmds.Count; k++)
                {
                    if (IsJoint() && k == transitionRelationComputer.transferIndex)
                    {
                        PopulateIntermediateFrameCopy();
                        oldSub = Substituter.SubstitutionFromHashtable(GetPreStateVars().
                                                                       ToDictionary <Variable, Variable, Expr>(v => v, v => Expr.Ident(varCopies[varLastCopyId[v]][v])));
                    }
                    Cmd cmd = cmds[k];
                    if (cmd is AssignCmd)
                    {
                        AssignCmd assignCmd = ((AssignCmd)cmd).AsSimpleAssignCmd;
                        var       preState  = GetVarCopiesFromIds(varLastCopyId);
                        foreach (var v in assignCmd.Lhss)
                        {
                            MakeNewCopy(v.DeepAssignedVariable);
                        }
                        var postState = GetVarCopiesFromIds(varLastCopyId);

                        Dictionary <Variable, Variable> lhsMap = postState, rhsMap = preState;
                        if (QKeyValue.FindBoolAttribute(assignCmd.Attributes, CivlAttributes.BACKWARD))
                        {
                            lhsMap = preState;
                            rhsMap = postState;
                        }

                        var rhsSub = Substituter.SubstitutionFromHashtable(
                            rhsMap.ToDictionary(
                                kvp => kvp.Key, kvp => Expr.Ident(kvp.Value) as Expr
                                ));

                        List <AssignLhs> lhss = assignCmd.Lhss.Select(x => (AssignLhs) new SimpleAssignLhs(Token.NoToken,
                                                                                                           new IdentifierExpr(Token.NoToken, lhsMap[x.DeepAssignedVariable]))).ToList();
                        List <Expr> rhss = assignCmd.Rhss.Select(x =>
                                                                 Substituter.ApplyReplacingOldExprs(rhsSub, oldSub, x)).ToList();

                        newCmds.Add(new AssignCmd(Token.NoToken, lhss, rhss, assignCmd.Attributes));
                    }
                    else if (cmd is AssumeCmd)
                    {
                        var sub = Substituter.SubstitutionFromHashtable(
                            GetVarCopiesFromIds(varLastCopyId).ToDictionary(
                                kvp => kvp.Key, kvp => Expr.Ident(kvp.Value) as Expr
                                ));
                        newCmds.Add(new AssumeCmd(cmd.tok,
                                                  Substituter.ApplyReplacingOldExprs(sub, oldSub, ((AssumeCmd)cmd).Expr)));
                    }
                    else if (cmd is HavocCmd havocCmd)
                    {
                        foreach (var v in havocCmd.Vars)
                        {
                            MakeNewCopy(v.Decl);
                        }
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
                // TODO: Add note on this
                if (!IsJoint() || cmds.Count == transitionRelationComputer.transferIndex)
                {
                    PopulateIntermediateFrameCopy();
                }
            }
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Implementation impl,
            Dictionary <YieldCmd, List <PredicateCmd> > yields)
        {
            Dictionary <string, Variable>   domainNameToHoleVar = new Dictionary <string, Variable>();
            Dictionary <Variable, Variable> localVarMap         = new Dictionary <Variable, Variable>();
            Dictionary <Variable, Expr>     map = new Dictionary <Variable, Expr>();
            List <Variable> locals = new List <Variable>();
            List <Variable> inputs = new List <Variable>();

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                domainNameToHoleVar[domainName] = inParam;
            }

            foreach (Variable local in impl.LocVars.Union(impl.InParams).Union(impl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                localVarMap[local] = copy;
                map[local]         = Expr.Ident(copy);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                var copy = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var           linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap);
            Substitution  assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst    = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst       = Substituter.SubstitutionFromHashtable(map);
            List <Block>  noninterferenceCheckerBlocks = new List <Block>();
            List <String> labels       = new List <String>();
            List <Block>  labelTargets = new List <Block>();
            Block         noninterferenceCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(noninterferenceCheckerBlock.Label);
            labelTargets.Add(noninterferenceCheckerBlock);
            noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            int yieldCount = 0;

            foreach (var kv in yields)
            {
                var        yieldCmd        = kv.Key;
                var        yieldPredicates = kv.Value;
                List <Cmd> newCmds         = linearPermissionInstrumentation.DisjointnessAssumeCmds(yieldCmd, false);
                foreach (var predCmd in yieldPredicates)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in yieldPredicates)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                }

                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                noninterferenceCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(noninterferenceCheckerBlock.Label);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0,
                                                new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var noninterferenceCheckerName = $"NoninterferenceChecker_{impl.Name}";
            var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs,
                                                           new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName, impl.TypeParameters, inputs,
                                                                new List <Variable>(), locals, noninterferenceCheckerBlocks);

            noninterferenceCheckerImpl.Proc = noninterferenceCheckerProc;
            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            DeclWithFormals decl,
            List <Variable> declLocalVariables)
        {
            Dictionary <string, Variable>   domainNameToHoleVar = new Dictionary <string, Variable>();
            Dictionary <Variable, Variable> localVarMap         = new Dictionary <Variable, Variable>();
            Dictionary <Variable, Expr>     map = new Dictionary <Variable, Expr>();
            List <Variable> locals = new List <Variable>();
            List <Variable> inputs = new List <Variable>();

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                domainNameToHoleVar[domainName] = inParam;
            }
            foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                localVarMap[local] = copy;
                map[local]         = Expr.Ident(copy);
            }
            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                var copy = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap, domainNameToHoleVar, localVarMap);
            List <Tuple <List <Cmd>, List <PredicateCmd> > > yieldInfo = null;

            if (decl is Implementation impl)
            {
                yieldInfo = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv => new Tuple <List <Cmd>, List <PredicateCmd> >(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList();
            }
            else if (decl is Procedure proc)
            {
                yieldInfo = new List <Tuple <List <Cmd>, List <PredicateCmd> > >();
                if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc))
                {
                    if (proc.Requires.Count > 0)
                    {
                        var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var yieldPredicates  = proc.Requires.Select(requires =>
                                                                    requires.Free
                                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfo.Add(new Tuple <List <Cmd>, List <PredicateCmd> >(disjointnessCmds, yieldPredicates));
                    }
                }
                else
                {
                    if (proc.Requires.Count > 0)
                    {
                        var entryDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var entryYieldPredicates = proc.Requires.Select(requires =>
                                                                        requires.Free
                                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfo.Add(
                            new Tuple <List <Cmd>, List <PredicateCmd> >(entryDisjointnessCmds, entryYieldPredicates));
                    }
                    if (proc.Ensures.Count > 0)
                    {
                        var exitDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false);
                        var exitYieldPredicates = proc.Ensures.Select(ensures =>
                                                                      ensures.Free
                                ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition)
                                : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList();
                        yieldInfo.Add(
                            new Tuple <List <Cmd>, List <PredicateCmd> >(exitDisjointnessCmds, exitYieldPredicates));
                    }
                }
            }
            else
            {
                Debug.Assert(false);
            }

            Substitution  assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst    = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst       = Substituter.SubstitutionFromHashtable(map);
            List <Block>  noninterferenceCheckerBlocks = new List <Block>();
            List <String> labels       = new List <String>();
            List <Block>  labelTargets = new List <Block>();
            Block         noninterferenceCheckerBlock = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(noninterferenceCheckerBlock.Label);
            labelTargets.Add(noninterferenceCheckerBlock);
            noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            int yieldCount = 0;

            foreach (var kv in yieldInfo)
            {
                var disjointnessCmds = kv.Item1;
                var yieldPredicates  = kv.Item2;
                var newCmds          = new List <Cmd>(disjointnessCmds);
                foreach (var predCmd in yieldPredicates)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in yieldPredicates)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                }

                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                noninterferenceCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(noninterferenceCheckerBlock.Label);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0,
                                                new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var noninterferenceCheckerName = decl is Procedure ? $"NoninterferenceChecker_proc_{decl.Name}" : $"NoninterferenceChecker_impl_{decl.Name}";
            var noninterferenceCheckerProc = new Procedure(Token.NoToken, noninterferenceCheckerName, decl.TypeParameters, inputs,
                                                           new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName, decl.TypeParameters, inputs,
                                                                new List <Variable>(), locals, noninterferenceCheckerBlocks);

            noninterferenceCheckerImpl.Proc = noninterferenceCheckerProc;
            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }