예제 #1
0
        private YieldingProcInstrumentation(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            Dictionary <Implementation, Implementation> implMap,
            HashSet <Procedure> yieldingProcs)
        {
            this.civlTypeChecker            = civlTypeChecker;
            this.linearTypeChecker          = linearTypeChecker;
            this.layerNum                   = layerNum;
            this.absyMap                    = absyMap;
            this.implMap                    = implMap;
            this.yieldingProcs              = yieldingProcs;
            asyncAndParallelCallDesugarings = new Dictionary <string, Procedure>();
            yieldCheckerDecls               = 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.sharedVariables)
            {
                inputs.Add(OldGlobalFormal(g));
            }

            yieldProc = new Procedure(Token.NoToken, $"og_yield_{layerNum}", new List <TypeVariable>(),
                                      inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
            CivlUtil.AddInlineAttribute(yieldProc);
        }
예제 #2
0
        public AtomicAction(Procedure proc, Implementation impl, MoverType moverType, LayerRange layerRange)
        {
            this.proc       = proc;
            this.impl       = impl;
            this.moverType  = moverType;
            this.layerRange = layerRange;

            CivlUtil.AddInlineAttribute(proc);
            CivlUtil.AddInlineAttribute(impl);

            // The gate of an atomic action is represented as asserts at the beginning of the procedure body.
            this.gate = impl.Blocks[0].cmds.TakeWhile((c, i) => c is AssertCmd).Cast <AssertCmd>().ToList();
            impl.Blocks[0].cmds.RemoveRange(0, gate.Count);

            gateUsedGlobalVars   = new HashSet <Variable>(VariableCollector.Collect(gate).Where(x => x is GlobalVariable));
            actionUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(impl).Where(x => x is GlobalVariable));
            modifiedGlobalVars   = new HashSet <Variable>(AssignedVariables().Where(x => x is GlobalVariable));

            // We usually declare the Boogie procedure and implementation of an atomic action together.
            // Since Boogie only stores the supplied attributes (in particular linearity) in the procedure parameters,
            // we copy them into the implementation parameters here.
            for (int i = 0; i < proc.InParams.Count; i++)
            {
                impl.InParams[i].Attributes = proc.InParams[i].Attributes;
            }
            for (int i = 0; i < proc.OutParams.Count; i++)
            {
                impl.OutParams[i].Attributes = proc.OutParams[i].Attributes;
            }

            AtomicActionDuplicator.SetupCopy(this, ref firstGate, ref firstImpl, "first_");
            AtomicActionDuplicator.SetupCopy(this, ref secondGate, ref secondImpl, "second_");

            DeclareTriggerFunctions();
        }
예제 #3
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);
        }
예제 #4
0
        private Implementation WrapperNoninterferenceCheckerImpl()
        {
            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));
            }

            List <Block> blocks      = new List <Block>();
            TransferCmd  transferCmd = new ReturnCmd(Token.NoToken);

            if (noninterferenceCheckerDecls.Count > 0)
            {
                List <Block>  blockTargets = new List <Block>();
                List <String> labelTargets = new List <String>();
                int           labelCount   = 0;
                foreach (Procedure proc in noninterferenceCheckerDecls.OfType <Procedure>())
                {
                    List <Expr> exprSeq = new List <Expr>();
                    foreach (Variable v in inputs)
                    {
                        exprSeq.Add(Expr.Ident(v));
                    }

                    CallCmd callCmd = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List <IdentifierExpr>());
                    callCmd.Proc = proc;
                    string label = $"L_{labelCount++}";
                    Block  block = new Block(Token.NoToken, label, new List <Cmd> {
                        callCmd
                    },
                                             new ReturnCmd(Token.NoToken));
                    labelTargets.Add(label);
                    blockTargets.Add(block);
                    blocks.Add(block);
                }

                transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets);
            }

            blocks.Insert(0, new Block(Token.NoToken, "enter", new List <Cmd>(), transferCmd));

            var yieldImpl = new Implementation(Token.NoToken, wrapperNoninterferenceCheckerProc.Name,
                                               new List <TypeVariable>(), inputs,
                                               new List <Variable>(), new List <Variable>(), blocks);

            yieldImpl.Proc = wrapperNoninterferenceCheckerProc;
            CivlUtil.AddInlineAttribute(yieldImpl);
            return(yieldImpl);
        }
예제 #5
0
        public static void AddCheckers(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, List <Declaration> decls)
        {
            Program program = linearTypeChecker.program;

            // Skip procedures do not completely disappear (because of output parameters).
            // We create dummy implementations with empty body.
            Dictionary <Procedure, Procedure> procToSkipProcDummy = new Dictionary <Procedure, Procedure>();

            foreach (SkipProc skipProc in civlTypeChecker.procToYieldingProc.Values.OfType <SkipProc>())
            {
                Procedure proc = (Procedure)skipProc.proc.Clone();
                proc.Name     = $"skip_dummy_{proc.Name}";
                proc.Requires = new List <Requires>();
                proc.Ensures  = new List <Ensures>();
                proc.Modifies = new List <IdentifierExpr>();
                Block        newInitBlock = new Block(Token.NoToken, "_init", new List <Cmd>(), new ReturnCmd(Token.NoToken));
                List <Block> newBlocks    = new List <Block> {
                    newInitBlock
                };
                Implementation impl = new Implementation(Token.NoToken, proc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List <Variable>(), newBlocks);
                impl.Proc = proc;
                CivlUtil.AddInlineAttribute(proc);
                CivlUtil.AddInlineAttribute(impl);
                decls.Add(proc);
                decls.Add(impl);
                procToSkipProcDummy.Add(skipProc.proc, proc);
            }

            // Generate the refinement checks for every layer
            foreach (int layerNum in civlTypeChecker.allRefinementLayers)
            {
                if (CommandLineOptions.Clo.TrustLayersDownto <= layerNum || layerNum <= CommandLineOptions.Clo.TrustLayersUpto)
                {
                    continue;
                }

                YieldingProcDuplicator duplicator = new YieldingProcDuplicator(civlTypeChecker, linearTypeChecker, layerNum, procToSkipProcDummy);

                // We can not simply call VisitProgram, because it does some resolving of calls
                // that is not necessary here (and actually fails).
                foreach (Procedure proc in program.Procedures)
                {
                    duplicator.VisitProcedure(proc);
                }
                foreach (Implementation impl in program.Implementations)
                {
                    duplicator.VisitImplementation(impl);
                }
                decls.AddRange(duplicator.Collect());
            }
        }
예제 #6
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);
            }
        }
예제 #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 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
            });
        }
예제 #9
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
            });
        }
예제 #10
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
            });
        }