Пример #1
0
        public static List <Declaration> TransformImplementations(
            CivlTypeChecker civlTypeChecker,
            int layerNum,
            AbsyMap absyMap,
            HashSet <Procedure> yieldingProcs,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            var linearPermissionInstrumentation =
                new LinearPermissionInstrumentation(civlTypeChecker, layerNum, absyMap);
            var yieldingProcInstrumentation = new YieldingProcInstrumentation(
                civlTypeChecker,
                linearPermissionInstrumentation,
                layerNum,
                absyMap,
                refinementBlocks);

            yieldingProcInstrumentation.AddNoninterferenceCheckers();
            var implToPreconditions = yieldingProcInstrumentation.CreatePreconditions(linearPermissionInstrumentation);

            yieldingProcInstrumentation
            .InlineYieldRequiresAndEnsures(); // inline after creating the preconditions but before transforming the implementations
            yieldingProcInstrumentation.TransformImpls(yieldingProcs, implToPreconditions);

            List <Declaration> decls = new List <Declaration>();

            decls.AddRange(yieldingProcInstrumentation.noninterferenceCheckerDecls);
            decls.AddRange(yieldingProcInstrumentation.parallelCallAggregators.Values);
            decls.AddRange(yieldingProcInstrumentation.PendingAsyncNoninterferenceCheckers());
            decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc);
            decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl());
            return(decls);
        }
Пример #2
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            LinearPermissionInstrumentation linearPermissionInstrumentation,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            this.civlTypeChecker   = civlTypeChecker;
            this.linearTypeChecker = linearTypeChecker;
            this.layerNum          = layerNum;
            this.absyMap           = absyMap;
            this.linearPermissionInstrumentation = linearPermissionInstrumentation;
            this.refinementBlocks       = refinementBlocks;
            parallelCallAggregators     = new Dictionary <string, Procedure>();
            noninterferenceCheckerDecls = new List <Declaration>();

            List <Variable> inputs = new List <Variable>();

            foreach (string domainName in linearTypeChecker.linearDomains.Keys)
            {
                inputs.Add(linearTypeChecker.LinearDomainInFormal(domainName));
            }

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                inputs.Add(OldGlobalFormal(g));
            }

            wrapperNoninterferenceCheckerProc = new Procedure(Token.NoToken,
                                                              $"Wrapper_NoninterferenceChecker_{layerNum}", new List <TypeVariable>(),
                                                              inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc);
        }
Пример #3
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearPermissionInstrumentation linearPermissionInstrumentation,
            int layerNum,
            AbsyMap absyMap,
            Dictionary <CallCmd, Block> refinementBlocks)
        {
            this.civlTypeChecker = civlTypeChecker;
            this.layerNum        = layerNum;
            this.absyMap         = absyMap;
            this.linearPermissionInstrumentation = linearPermissionInstrumentation;
            this.refinementBlocks       = refinementBlocks;
            parallelCallAggregators     = new Dictionary <string, Procedure>();
            noninterferenceCheckerDecls = new List <Declaration>();

            var             linearTypeChecker = civlTypeChecker.linearTypeChecker;
            List <Variable> inputs            = new List <Variable>();

            foreach (string domainName in linearTypeChecker.linearDomains.Keys)
            {
                inputs.Add(linearTypeChecker.LinearDomainInFormal(domainName));
            }

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                inputs.Add(OldGlobalFormal(g));
            }

            wrapperNoninterferenceCheckerProc = new Procedure(Token.NoToken,
                                                              civlTypeChecker.AddNamePrefix($"Wrapper_NoninterferenceChecker_{layerNum}"), new List <TypeVariable>(),
                                                              inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(wrapperNoninterferenceCheckerProc);

            // initialize globalSnapshotInstrumentation
            globalSnapshotInstrumentation = new GlobalSnapshotInstrumentation(civlTypeChecker);

            // initialize noninterferenceInstrumentation
            if (CommandLineOptions.Clo.TrustNoninterference)
            {
                noninterferenceInstrumentation = new NoneNoninterferenceInstrumentation();
            }
            else
            {
                noninterferenceInstrumentation = new SomeNoninterferenceInstrumentation(
                    civlTypeChecker,
                    linearTypeChecker,
                    linearPermissionInstrumentation,
                    globalSnapshotInstrumentation.OldGlobalMap,
                    wrapperNoninterferenceCheckerProc);
            }
        }
        public static List <Declaration> TransformImplementations(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            HashSet <Procedure> yieldingProcs)
        {
            var linearHelper = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap);
            var yieldingProcInstrumentation = new YieldingProcInstrumentation(
                civlTypeChecker,
                linearTypeChecker,
                linearHelper,
                layerNum,
                absyMap,
                yieldingProcs);

            foreach (var impl in absyMap.Keys.OfType <Implementation>())
            {
                // Add disjointness assumptions at beginning, loop headers, and after each call or parallel call.
                // These are added for each duplicate implementation of yielding procedures.
                // Disjointness assumptions after yields are added inside TransformImpl which is called for
                // all implementations except for a mover procedure at its disappearing layer.
                // But this is fine because a mover procedure at its disappearing layer does not have a yield in it.
                linearHelper.AddDisjointnessAssumptions(impl, yieldingProcs);
                var originalImpl = absyMap[impl] as Implementation;
                var proc         = civlTypeChecker.procToYieldingProc[originalImpl.Proc];
                if (!(proc is MoverProc && proc.upperLayer == layerNum))
                {
                    yieldingProcInstrumentation.TransformImpl(originalImpl, impl);
                }
            }

            List <Declaration> decls = new List <Declaration>(yieldingProcInstrumentation.noninterferenceCheckerDecls);

            foreach (Procedure proc in yieldingProcInstrumentation.parallelCallPreconditionCheckers.Values)
            {
                decls.Add(proc);
            }
            decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc);
            decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl());
            return(decls);
        }
Пример #5
0
        private Dictionary <Implementation, List <Cmd> > CreatePreconditions(
            LinearPermissionInstrumentation linearPermissionInstrumentation)
        {
            var implToInitCmds = new Dictionary <Implementation, List <Cmd> >();

            foreach (var impl in absyMap.Keys.OfType <Implementation>())
            {
                var initCmds = new List <Cmd>();
                if (civlTypeChecker.GlobalVariables.Count() > 0)
                {
                    initCmds.Add(new HavocCmd(Token.NoToken,
                                              civlTypeChecker.GlobalVariables.Select(v => Expr.Ident(v)).ToList()));
                    linearPermissionInstrumentation.DisjointnessExprs(impl, true).ForEach(
                        expr => initCmds.Add(new AssumeCmd(Token.NoToken, expr)));

                    Substitution procToImplInParams = Substituter.SubstitutionFromHashtable(impl.Proc.InParams
                                                                                            .Zip(impl.InParams).ToDictionary(x => x.Item1, x => (Expr)Expr.Ident(x.Item2)));

                    impl.Proc.Requires.ForEach(req =>
                                               initCmds.Add(new AssumeCmd(req.tok, Substituter.Apply(procToImplInParams, req.Condition))));

                    foreach (var callCmd in GetYieldingProc(impl).yieldRequires)
                    {
                        var yieldInvariant = civlTypeChecker.procToYieldInvariant[callCmd.Proc];
                        if (layerNum == yieldInvariant.LayerNum)
                        {
                            Substitution callFormalsToActuals = Substituter.SubstitutionFromHashtable(callCmd.Proc.InParams
                                                                                                      .Zip(callCmd.Ins)
                                                                                                      .ToDictionary(x => x.Item1, x => (Expr) new OldExpr(Token.NoToken, x.Item2)));
                            callCmd.Proc.Requires.ForEach(req => initCmds.Add(new AssumeCmd(req.tok,
                                                                                            Substituter.Apply(procToImplInParams,
                                                                                                              Substituter.Apply(callFormalsToActuals, req.Condition)))));
                        }
                    }
                }

                implToInitCmds[impl] = initCmds;
            }

            return(implToInitCmds);
        }
 public SomeNoninterferenceInstrumentation(
     CivlTypeChecker civlTypeChecker,
     LinearTypeChecker linearTypeChecker,
     LinearPermissionInstrumentation linearPermissionInstrumentation,
     Dictionary <Variable, Variable> oldGlobalMap,
     Procedure yieldProc)
 {
     this.civlTypeChecker   = civlTypeChecker;
     this.linearTypeChecker = linearTypeChecker;
     this.linearPermissionInstrumentation = linearPermissionInstrumentation;
     this.oldGlobalMap        = oldGlobalMap;
     this.yieldProc           = yieldProc;
     this.newLocalVars        = new List <Variable>();
     this.domainNameToHoleVar = new Dictionary <string, Variable>();
     foreach (string domainName in linearTypeChecker.linearDomains.Keys)
     {
         Variable l = linearTypeChecker.LinearDomainAvailableLocal(domainName);
         domainNameToHoleVar[domainName] = l;
         newLocalVars.Add(l);
     }
 }
Пример #7
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
            });
        }
Пример #8
0
        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
            });
        }
Пример #9
0
        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
            });
        }