Пример #1
0
            internal PathTranslation(TransitionRelationComputation transitionRelationComputer,
                                     List <Cmd> cmds)
            {
                this.cmds = cmds;
                this.transitionRelationComputer = transitionRelationComputer;
                this.frame  = transitionRelationComputer.frame;
                this.first  = transitionRelationComputer.first;
                this.second = transitionRelationComputer.second;

                allInParams           = new HashSet <Variable>(first.InParams);
                allOutParams          = new HashSet <Variable>(first.OutParams);
                allLocVars            = new HashSet <Variable>(first.LocVars);
                frameIntermediateCopy = new Dictionary <Variable, Variable>();
                if (IsJoint())
                {
                    allInParams.UnionWith(second.InParams);
                    allOutParams.UnionWith(second.OutParams);
                    allLocVars.UnionWith(second.LocVars);
                }

                SetupVarCopies();
                IntroduceIntermediateVars();
                EliminateIntermediateVariables();
                if (IsJoint())
                {
                    EliminateWithIntermediateState();
                }
                ComputeTransitionRelationExpr();
            }
Пример #2
0
        public static void AddChecks(CivlTypeChecker ctc)
        {
            foreach (var x in ctc.inductiveSequentializations)
            {
                var t = x.GenerateBaseCaseChecker();
                ctc.program.AddTopLevelDeclaration(t.Item1);
                ctc.program.AddTopLevelDeclaration(t.Item2);
                t = x.GenerateConclusionChecker();
                ctc.program.AddTopLevelDeclaration(t.Item1);
                ctc.program.AddTopLevelDeclaration(t.Item2);
                t = x.GenerateStepChecker(ctc.pendingAsyncAdd);
                ctc.program.AddTopLevelDeclaration(t.Item1);
                ctc.program.AddTopLevelDeclaration(t.Item2);
            }

            var absChecks = ctc.inductiveSequentializations.SelectMany(x => x.elim).Where(kv => kv.Key != kv.Value).Distinct();

            foreach (var absCheck in absChecks)
            {
                var action = absCheck.Key;
                var abs    = absCheck.Value;

                var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList();
                // TODO: check frame computation
                var frame   = new HashSet <Variable>(action.modifiedGlobalVars.Union(action.gateUsedGlobalVars).Union(abs.modifiedGlobalVars).Union(abs.gateUsedGlobalVars));
                var tr      = TransitionRelationComputation.Refinement(abs, frame);
                var ensures = new List <Ensures> {
                    new Ensures(false, tr)
                    {
                        ErrorData = $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}"
                    }
                };

                var        subst = InductiveSequentialization.GetSubstitution(action, abs);
                List <Cmd> cmds  = InductiveSequentialization.GetGateAsserts(action, subst,
                                                                             $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>();
                cmds.Add(
                    CmdHelper.CallCmd(
                        action.proc,
                        abs.impl.InParams.Select(Expr.Ident).ToList <Expr>(),
                        abs.impl.OutParams.Select(Expr.Ident).ToList()
                        ));
                var blocks = new List <Block> {
                    new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd)
                };

                var proc = new Procedure(Token.NoToken, $"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}", new List <TypeVariable>(),
                                         abs.impl.InParams, abs.impl.OutParams, requires, abs.modifiedGlobalVars.Select(Expr.Ident).ToList(), ensures);
                var impl = new Implementation(Token.NoToken, proc.Name, new List <TypeVariable>(),
                                              proc.InParams, proc.OutParams, new List <Variable>(), blocks)
                {
                    Proc = proc
                };
                ctc.program.AddTopLevelDeclaration(proc);
                ctc.program.AddTopLevelDeclaration(impl);
            }
        }
Пример #3
0
        private Expr GetTransitionRelation(AtomicAction action)
        {
            var tr = TransitionRelationComputation.Refinement(civlTypeChecker, action, frame);

            if (action == invariantAction && HasChoice)
            {
                return(new ChoiceEraser(invariantAction.impl.OutParams.Last()).VisitExpr(tr));
            }
            return(tr);
        }
            public PathTranslation(TransitionRelationComputation trc)
            {
                this.trc = trc;

                SetupVarCopies();
                IntroduceIntermediateVars();
                SetDefinedVariables();
                EliminateIntermediateVariables();
                ComputeTransitionRelationExpr();
            }
Пример #5
0
        private Expr GetTransitionRelation(AtomicAction atomicAction)
        {
            if (!transitionRelationCache.ContainsKey(atomicAction))
            {
                transitionRelationCache[atomicAction] =
                    TransitionRelationComputation.Refinement(civlTypeChecker, atomicAction, new HashSet <Variable>(this.oldGlobalMap.Keys));
            }

            return(transitionRelationCache[atomicAction]);
        }
Пример #6
0
 private Expr GetTransitionRelation(AtomicActionCopy atomicActionCopy)
 {
     if (!transitionRelationCache.ContainsKey(atomicActionCopy))
     {
         transitionRelationCache[atomicActionCopy] =
             TransitionRelationComputation.
             Refinement(atomicActionCopy, new HashSet <Variable>(this.oldGlobalMap.Keys));
     }
     return(transitionRelationCache[atomicActionCopy]);
 }
Пример #7
0
        private static Tuple <Procedure, Implementation> GenerateAbstractionChecker(CivlTypeChecker civlTypeChecker, AtomicAction action, AtomicAction abs)
        {
            var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList();
            // TODO: check frame computation
            var frame = new HashSet <Variable>(
                action.modifiedGlobalVars
                .Union(action.gateUsedGlobalVars)
                .Union(abs.modifiedGlobalVars)
                .Union(abs.gateUsedGlobalVars));
            var tr      = TransitionRelationComputation.Refinement(civlTypeChecker, abs, frame);
            var ensures = new List <Ensures> {
                new Ensures(false, tr)
                {
                    ErrorData = $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}"
                }
            };

            var        subst = InductiveSequentialization.GetSubstitution(action, abs);
            List <Cmd> cmds  = InductiveSequentialization.GetGateAsserts(action, subst,
                                                                         $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>();

            cmds.Add(
                CmdHelper.CallCmd(
                    action.proc,
                    abs.impl.InParams.Select(Expr.Ident).ToList <Expr>(),
                    abs.impl.OutParams.Select(Expr.Ident).ToList()
                    ));
            var blocks = new List <Block> {
                new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd)
            };

            var proc = new Procedure(
                Token.NoToken,
                civlTypeChecker.AddNamePrefix($"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}"),
                new List <TypeVariable>(),
                abs.impl.InParams,
                abs.impl.OutParams,
                requires,
                action.proc.Modifies,
                ensures);
            var impl = new Implementation(
                Token.NoToken,
                proc.Name,
                new List <TypeVariable>(),
                proc.InParams,
                proc.OutParams,
                new List <Variable>(),
                blocks)
            {
                Proc = proc
            };

            return(Tuple.Create(proc, impl));
        }
Пример #8
0
        private static Tuple <Procedure, Implementation> GenerateAbstractionChecker(CivlTypeChecker civlTypeChecker, AtomicAction action, AtomicAction abs)
        {
            var requires = abs.gate.Select(g => new Requires(false, g.Expr)).ToList();
            // TODO: check frame computation
            var frame = new HashSet <Variable>(
                action.modifiedGlobalVars
                .Union(action.gateUsedGlobalVars)
                .Union(abs.modifiedGlobalVars)
                .Union(abs.gateUsedGlobalVars));

            var        subst = InductiveSequentialization.GetSubstitution(action, abs);
            List <Cmd> cmds  = InductiveSequentialization.GetGateAsserts(action, subst,
                                                                         $"Abstraction {abs.proc.Name} fails gate of {action.proc.Name}").ToList <Cmd>();

            cmds.Add(
                CmdHelper.CallCmd(
                    action.proc,
                    abs.impl.InParams,
                    abs.impl.OutParams
                    ));
            cmds.Add(
                CmdHelper.AssertCmd(
                    abs.proc.tok,
                    TransitionRelationComputation.Refinement(civlTypeChecker, abs, frame),
                    $"Abstraction {abs.proc.Name} does not summarize {action.proc.Name}"
                    ));

            var blocks = new List <Block> {
                BlockHelper.Block("init", cmds)
            };

            var proc = DeclHelper.Procedure(
                civlTypeChecker.AddNamePrefix($"AbstractionCheck_{action.proc.Name}_{abs.proc.Name}"),
                abs.impl.InParams,
                abs.impl.OutParams,
                requires,
                action.proc.Modifies,
                new List <Ensures>());
            var impl = DeclHelper.Implementation(
                proc,
                proc.InParams,
                proc.OutParams,
                new List <Variable>(),
                blocks);

            return(Tuple.Create(proc, impl));
        }
        private static Expr ComputeTransitionRelation(
            Implementation first, Implementation second,
            IEnumerable <Variable> frame, Dictionary <Variable, Function> triggers, IEnumerable <CommutativityWitness> witnesses, bool ignorePostState,
            string messagePrefix)
        {
            var trc = new TransitionRelationComputation(first, second, frame, witnesses, triggers, ignorePostState, messagePrefix);

            trc.EnumeratePaths();
            var transitionRelation = Expr.Or(trc.pathTranslations);

            transitionRelation.Resolve(new ResolutionContext(null)
            {
                StateMode = ResolutionContext.State.Two
            });
            transitionRelation.Typecheck(new TypecheckingContext(null));
            return(transitionRelation);
        }
Пример #10
0
        private void CreateNonBlockingChecker(AtomicAction action)
        {
            if (!action.HasAssumeCmd)
            {
                return;
            }

            string checkerName = $"NonBlockingChecker_{action.proc.Name}";

            Implementation     impl  = action.impl;
            HashSet <Variable> frame = new HashSet <Variable>();

            frame.UnionWith(action.gateUsedGlobalVars);
            frame.UnionWith(action.actionUsedGlobalVars);

            List <Requires> requires = new List <Requires>
            {
                DisjointnessRequires(impl.InParams.
                                     Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame)
            };

            foreach (AssertCmd assertCmd in action.gate)
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            Expr nonBlockingExpr = TransitionRelationComputation.
                                   Nonblocking(action, frame);
            AssertCmd nonBlockingAssert = new AssertCmd(action.proc.tok, nonBlockingExpr)
            {
                ErrorData = $"Non-blocking check for {action.proc.Name} failed"
            };

            Block block = new Block(action.proc.tok, "L", new List <Cmd> {
                nonBlockingAssert
            },
                                    new ReturnCmd(Token.NoToken));

            AddChecker(checkerName, new List <Variable>(impl.InParams), new List <Variable>(),
                       new List <Variable>(), requires, new List <Ensures>(), new List <Block> {
                block
            });
        }
Пример #11
0
        private static Expr ComputeTransitionRelation(
            AtomicActionCopyAdapter first, AtomicActionCopyAdapter second,
            IEnumerable <Variable> frame, List <WitnessFunction> witnesses, bool ignorePostState,
            string messagePrefix)
        {
            var trc = new TransitionRelationComputation(first, second, frame, witnesses, ignorePostState, messagePrefix);

            trc.EnumeratePaths();
            var transitionRelation = Expr.Or(trc.pathTranslations);

            ResolutionContext rc = new ResolutionContext(null)
            {
                StateMode = ResolutionContext.State.Two
            };

            transitionRelation.Resolve(rc);
            transitionRelation.Typecheck(new TypecheckingContext(null));

            return(transitionRelation);
        }
Пример #12
0
        private void CreateCooperationChecker(Action action)
        {
            if (!action.HasAssumeCmd)
            {
                return;
            }

            string checkerName = $"CooperationChecker_{action.proc.Name}";

            Implementation     impl  = action.impl;
            HashSet <Variable> frame = new HashSet <Variable>();

            frame.UnionWith(action.gateUsedGlobalVars);
            frame.UnionWith(action.actionUsedGlobalVars);

            List <Requires> requires = new List <Requires>
            {
                DisjointnessRequires(impl.InParams.Where(v => civlTypeChecker.linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT),
                                     frame)
            };

            foreach (AssertCmd assertCmd in action.gate)
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            AssertCmd cooperationCheck = CmdHelper.AssertCmd(
                action.proc.tok,
                TransitionRelationComputation.Cooperation(civlTypeChecker, action, frame),
                $"Cooperation check for {action.proc.Name} failed");

            AddChecker(checkerName, new List <Variable>(impl.InParams), new List <Variable>(),
                       new List <Variable>(), requires, new List <Cmd> {
                cooperationCheck
            });
        }
Пример #13
0
        private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second)
        {
            if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0)
            {
                return;
            }
            if (first.CommutesWith(second))
            {
                return;
            }
            if (!commutativityCheckerCache.Add(new Tuple <AtomicActionInfo, AtomicActionInfo>(first, second)))
            {
                return;
            }

            List <Variable> inputs       = Enumerable.Union(first.thatInParams, second.thisInParams).ToList();
            List <Variable> outputs      = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList();
            List <Variable> locals       = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList();
            List <Block>    firstBlocks  = CloneBlocks(first.thatAction.Blocks);
            List <Block>    secondBlocks = CloneBlocks(second.thisAction.Blocks);

            foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd))
            {
                List <Block> bs = new List <Block>  {
                    secondBlocks[0]
                };
                List <string> ls = new List <string> {
                    secondBlocks[0].Label
                };
                b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs);
            }
            List <Block>       blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList();
            HashSet <Variable> frame  = new HashSet <Variable>();

            frame.UnionWith(first.gateUsedGlobalVars);
            frame.UnionWith(first.actionUsedGlobalVars);
            frame.UnionWith(second.gateUsedGlobalVars);
            frame.UnionWith(second.actionUsedGlobalVars);

            List <Requires> requires = new List <Requires>();

            requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame));
            foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate))
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            var  transitionRelationComputation = new TransitionRelationComputation(program, first, second, frame, new HashSet <Variable>());
            Expr transitionRelation            = transitionRelationComputation.TransitionRelationCompute();
            {
                List <Block> bs = new List <Block> {
                    blocks[0]
                };
                List <string> ls = new List <string> {
                    blocks[0].Label
                };
                var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs));
                blocks.Insert(0, initBlock);
            }

            var thisInParamsFiltered            = second.thisInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN);
            IEnumerable <Expr> linearityAssumes = Enumerable.Union(
                DisjointnessExpr(program, first.thatOutParams.Union(thisInParamsFiltered), frame),
                DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame));
            // TODO: add further disjointness expressions?
            Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation));

            ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name);
            List <Ensures> ensures = new List <Ensures> {
                ensureCheck
            };

            string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name);
            List <IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList();

            Procedure      proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, requires, globalVars, ensures);
            Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, locals, blocks);

            impl.Proc = proc;
            this.decls.Add(impl);
            this.decls.Add(proc);
        }
Пример #14
0
        private void CreateCommutativityChecker(AtomicAction first, AtomicAction second)
        {
            if (first == second && first.firstImpl.InParams.Count == 0 && first.firstImpl.OutParams.Count == 0)
            {
                return;
            }
            if (first.TriviallyCommutesWith(second))
            {
                return;
            }
            if (!commutativityCheckerCache.Add(Tuple.Create(first, second)))
            {
                return;
            }

            string checkerName = $"CommutativityChecker_{first.proc.Name}_{second.proc.Name}";

            HashSet <Variable> frame = new HashSet <Variable>();

            frame.UnionWith(first.gateUsedGlobalVars);
            frame.UnionWith(first.actionUsedGlobalVars);
            frame.UnionWith(second.gateUsedGlobalVars);
            frame.UnionWith(second.actionUsedGlobalVars);

            List <Requires> requires = new List <Requires>
            {
                DisjointnessRequires(
                    first.firstImpl.InParams.Union(second.secondImpl.InParams)
                    .Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT),
                    frame)
            };

            foreach (AssertCmd assertCmd in Enumerable.Union(first.firstGate, second.secondGate))
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            var witnesses          = civlTypeChecker.commutativityHints.GetWitnesses(first, second);
            var transitionRelation = TransitionRelationComputation.Commutativity(second, first, frame, witnesses);

            List <Cmd> cmds = new List <Cmd>
            {
                new CallCmd(Token.NoToken,
                            first.proc.Name,
                            first.firstImpl.InParams.Select(Expr.Ident).ToList <Expr>(),
                            first.firstImpl.OutParams.Select(Expr.Ident).ToList()
                            )
                {
                    Proc = first.proc
                },
                new CallCmd(Token.NoToken,
                            second.proc.Name,
                            second.secondImpl.InParams.Select(Expr.Ident).ToList <Expr>(),
                            second.secondImpl.OutParams.Select(Expr.Ident).ToList()
                            )
                {
                    Proc = second.proc
                }
            };

            foreach (var lemma in civlTypeChecker.commutativityHints.GetLemmas(first, second))
            {
                cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(lemma.function, lemma.args.ToArray())));
            }

            var block = new Block(Token.NoToken, "init", cmds, new ReturnCmd(Token.NoToken));

            var secondInParamsFiltered =
                second.secondImpl.InParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN);
            IEnumerable <Expr> linearityAssumes = Enumerable.Union(
                linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(secondInParamsFiltered)
                                                                .Union(frame)),
                linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(second.secondImpl.OutParams)
                                                                .Union(frame)));
            // TODO: add further disjointness expressions?
            Ensures ensureCheck =
                new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null)
            {
                ErrorData = $"Commutativity check between {first.proc.Name} and {second.proc.Name} failed"
            };
            List <Ensures> ensures = new List <Ensures> {
                ensureCheck
            };

            List <Variable> inputs  = Enumerable.Union(first.firstImpl.InParams, second.secondImpl.InParams).ToList();
            List <Variable> outputs = Enumerable.Union(first.firstImpl.OutParams, second.secondImpl.OutParams).ToList();

            AddChecker(checkerName, inputs, outputs, new List <Variable>(), requires, ensures, new List <Block> {
                block
            });
        }
Пример #15
0
        private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second)
        {
            if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0)
                return;
            if (first.CommutesWith(second))
                return;
            if (!commutativityCheckerCache.Add(new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second)))
                return;

            List<Variable> inputs  = Enumerable.Union(first.thatInParams, second.thisInParams).ToList();
            List<Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList();
            List<Variable> locals  = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList();
            List<Block> firstBlocks = CloneBlocks(first.thatAction.Blocks);
            List<Block> secondBlocks = CloneBlocks(second.thisAction.Blocks);
            foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd))
            {
                List<Block>  bs = new List<Block>  { secondBlocks[0] };
                List<string> ls = new List<string> { secondBlocks[0].Label };
                b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs);
            }
            List<Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList();
            HashSet<Variable> frame = new HashSet<Variable>();
            frame.UnionWith(first.gateUsedGlobalVars);
            frame.UnionWith(first.actionUsedGlobalVars);
            frame.UnionWith(second.gateUsedGlobalVars);
            frame.UnionWith(second.actionUsedGlobalVars);
            
            List<Requires> requires = new List<Requires>();
            requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame));
            foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate))
                requires.Add(new Requires(false, assertCmd.Expr));

            var transitionRelationComputation = new TransitionRelationComputation(program, first, second, frame, new HashSet<Variable>());
            Expr transitionRelation = transitionRelationComputation.TransitionRelationCompute();
            {
                List<Block> bs = new List<Block> { blocks[0] };
                List<string> ls = new List<string> { blocks[0].Label };
                var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs));
                blocks.Insert(0, initBlock);
            }
            IEnumerable<Expr> linearityAssumes = DisjointnessExpr(program, first.thatOutParams.Union(second.thisInParams), frame).Union(DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame));
            Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation));
            ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name);
            List<Ensures> ensures = new List<Ensures> { ensureCheck };
            
            string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name);
            List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList();

            Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures);
            Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks);
            impl.Proc = proc;
            this.decls.Add(impl);
            this.decls.Add(proc);
        }
Пример #16
0
        private void CreateCommutativityChecker(AtomicActionCopy first, AtomicActionCopy second)
        {
            if (first == second && first.firstInParams.Count == 0 && first.firstOutParams.Count == 0)
            {
                return;
            }
            if (first.TriviallyCommutesWith(second))
            {
                return;
            }
            if (!commutativityCheckerCache.Add(Tuple.Create(first, second)))
            {
                return;
            }

            List <Variable>    inputs  = Enumerable.Union(first.firstInParams, second.secondInParams).ToList();
            List <Variable>    outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList();
            List <Variable>    locals  = Enumerable.Union(first.firstAction.LocVars, second.secondAction.LocVars).ToList();
            List <Block>       blocks  = ComposeBlocks(first, second);
            HashSet <Variable> frame   = new HashSet <Variable>();

            frame.UnionWith(first.gateUsedGlobalVars);
            frame.UnionWith(first.actionUsedGlobalVars);
            frame.UnionWith(second.gateUsedGlobalVars);
            frame.UnionWith(second.actionUsedGlobalVars);

            List <Requires> requires = new List <Requires>();

            requires.Add(DisjointnessRequires(first.firstInParams.Union(second.secondInParams).Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame));
            foreach (AssertCmd assertCmd in Enumerable.Union(first.firstGate, second.secondGate))
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

            var  transitionRelationComputation = new TransitionRelationComputation(first, second, frame, new HashSet <Variable>());
            Expr transitionRelation            = transitionRelationComputation.TransitionRelationCompute();
            {
                List <Block> bs = new List <Block> {
                    blocks[0]
                };
                List <string> ls = new List <string> {
                    blocks[0].Label
                };
                var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs));
                blocks.Insert(0, initBlock);
            }

            var secondInParamsFiltered          = second.secondInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN);
            IEnumerable <Expr> linearityAssumes = Enumerable.Union(
                DisjointnessExpr(first.firstOutParams.Union(secondInParamsFiltered), frame),
                DisjointnessExpr(first.firstOutParams.Union(second.secondOutParams), frame));
            // TODO: add further disjointness expressions?
            Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null);

            ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name);
            List <Ensures> ensures = new List <Ensures> {
                ensureCheck
            };

            string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name);

            AddChecker(checkerName, inputs, outputs, locals, requires, ensures, blocks);
        }