Beispiel #1
0
        private List <Block> SubstituteBlocks(List <Block> blocks, Substitution subst, string blockLabelPrefix)
        {
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> otherBlocks           = new List <Block>();

            foreach (Block block in blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block otherBlock = new Block();
                otherBlock.Cmds  = otherCmds;
                otherBlock.Label = blockLabelPrefix + block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
            }
            foreach (Block block in blocks)
            {
                if (block.TransferCmd is ReturnCmd)
                {
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List <Block>  otherGotoCmdLabelTargets = new List <Block>();
                List <string> otherGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            return(otherBlocks);
        }
Beispiel #2
0
 private void Search(Block b, bool inFirst)
 {
     dfsStack.Push(b);
     if (b.TransferCmd is ReturnCmd)
     {
         if (first == null || inFirst)
         {
             transitionRelation = Expr.Or(transitionRelation, CalculatePathCondition());
         }
         else
         {
             Search(first.thisAction.Blocks[0], true);
         }
     }
     else
     {
         GotoCmd gotoCmd = b.TransferCmd as GotoCmd;
         foreach (Block target in gotoCmd.labelTargets)
         {
             Search(target, inFirst);
         }
     }
     dfsStack.Pop();
 }
Beispiel #3
0
        private static List <Block> CloneBlocks(List <Block> blocks)
        {
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> otherBlocks           = new List <Block>();

            foreach (Block block in blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(cmd);
                }
                Block otherBlock = new Block();
                otherBlock.Cmds  = otherCmds;
                otherBlock.Label = block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
            }
            foreach (Block block in blocks)
            {
                if (block.TransferCmd is ReturnCmd)
                {
                    continue;
                }
                List <Block>  otherGotoCmdLabelTargets = new List <Block>();
                List <string> otherGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            return(otherBlocks);
        }
        /// <summary>
        /// Instrument the if-else block.
        /// </summary>
        /// <param name="node">The lca node.</param>
        private void InstrumentIfElse(ProgramNode node)
        {
            ProgramNode next = node.Successors.First();

            // the block should have source location information for instrumentation to work
            if (next.Block.Cmds.Count > 1 && next.Block.Cmds[1] is AssertCmd)
            {
                AssertCmd assert = next.Block.Cmds[1] as AssertCmd;
                assert = DuplicateAssertCmd(assert);

                if (assert != null)
                {
                    Block lca = null;
                    foreach (Block block in program.Implementations.SelectMany(x => x.Blocks))
                    {
                        if (block.TransferCmd is GotoCmd)
                        {
                            GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                            if (gotoCmd.labelTargets.Contains(next.Block))
                            {
                                lca = block;
                                break;
                            }
                        }
                    }

                    int index = lca.Cmds.Count;
                    lca.Cmds.Insert(index, assert);

                    Implementation implementation = program.Implementations.First(x => x.Blocks.Contains(lca));

                    // insert a barrier at the end of the header block
                    AddBarrier(implementation, lca, index + 1);
                }
            }
        }
Beispiel #5
0
        List <Block> getTheFFinalBlock(Block b)
        {
            List <Block> lb = new List <Block>();
            GotoCmd      gc = b.TransferCmd as GotoCmd;

            if (gc == null)
            {
                lb.Add(b);
            }
            else
            {
                foreach (Block s in gc.labelTargets)
                {
                    foreach (Block r in getTheFFinalBlock(s))
                    {
                        if (!lb.Contains(r))
                        {
                            lb.Add(r);
                        }
                    }
                }
            }
            return(lb);
        }
Beispiel #6
0
        void ComputeBestSplit()
        {
            if (scoreComputed)
            {
                return;
            }
            scoreComputed = true;

            assertionCount = 0;

            foreach (Block b in blocks)
            {
                Contract.Assert(b != null);
                CountAssertions(b);
            }

            foreach (Block b in blocks)
            {
                Contract.Assert(b != null);
                BlockStats bs = GetBlockStats(b);
                if (bs.bigBlock)
                {
                    bigBlocks.Add(b);
                    foreach (Block ch in bs.virtualSuccessors)
                    {
                        Contract.Assert(ch != null);
                        BlockStats chs = GetBlockStats(ch);
                        if (!chs.bigBlock)
                        {
                            Console.WriteLine("non-big {0} accessed from {1}", ch, b);
                            DumpDot(-1);
                            Contract.Assert(false);
                            throw new cce.UnreachableException();
                        }

                        chs.virtualPredecessors.Add(b);
                    }
                }
            }

            assumizedBranches.Clear();
            totalCost = ProverCost(DoComputeScore(false));

            score = double.PositiveInfinity;
            Block        bestSplit     = null;
            List <Block> savedBranches = new List <Block>();

            foreach (Block b in bigBlocks)
            {
                Contract.Assert(b != null);
                GotoCmd gt = b.TransferCmd as GotoCmd;
                if (gt == null)
                {
                    continue;
                }
                List <Block> targ = cce.NonNull(gt.labelTargets);
                if (targ.Count < 2)
                {
                    continue;
                }
                // caution, we only consider two first exits

                double left0, right0, left1, right1;
                splitBlock = b;

                assumizedBranches.Clear();
                assumizedBranches.Add(cce.NonNull(targ[0]));
                left0  = DoComputeScore(true);
                right0 = DoComputeScore(false);

                assumizedBranches.Clear();
                for (int idx = 1; idx < targ.Count; idx++)
                {
                    assumizedBranches.Add(cce.NonNull(targ[idx]));
                }

                left1  = DoComputeScore(true);
                right1 = DoComputeScore(false);

                double currentScore = ProverCost(left1) + ProverCost(right1);
                double otherScore   = ProverCost(left0) + ProverCost(right0);

                if (otherScore < currentScore)
                {
                    currentScore = otherScore;
                    assumizedBranches.Clear();
                    assumizedBranches.Add(cce.NonNull(targ[0]));
                }

                if (currentScore < score)
                {
                    score     = currentScore;
                    bestSplit = splitBlock;
                    savedBranches.Clear();
                    savedBranches.AddRange(assumizedBranches);
                }
            }

            if (CommandLineOptions.Clo.VcsPathSplitMult * score > totalCost)
            {
                splitBlock = null;
                score      = -1;
            }
            else
            {
                assumizedBranches = savedBranches;
                splitBlock        = bestSplit;
            }
        }
Beispiel #7
0
        public ActionInfo(Procedure proc, CodeExpr codeExpr, MoverType moverType, int phaseNum)
        {
            this.proc            = proc;
            this.moverType       = moverType;
            this.phaseNum        = phaseNum;
            this.callerPhaseNums = new HashSet <int>();
            this.thisGate        = new List <AssertCmd>();
            this.thisAction      = codeExpr;
            this.thisInParams    = new List <Variable>();
            this.thisOutParams   = new List <Variable>();
            this.thatGate        = new List <AssertCmd>();
            this.thatInParams    = new List <Variable>();
            this.thatOutParams   = new List <Variable>();

            var cmds = thisAction.Blocks[0].Cmds;

            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null)
                {
                    break;
                }
                thisGate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, assertCmd.Expr);
            }

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

            foreach (Variable x in proc.InParams)
            {
                this.thisInParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true);
                this.thatInParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            foreach (Variable x in proc.OutParams)
            {
                this.thisOutParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                this.thatOutParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            List <Variable> otherLocVars = new List <Variable>();

            foreach (Variable x in thisAction.LocVars)
            {
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                map[x] = new IdentifierExpr(Token.NoToken, y);
                otherLocVars.Add(y);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);

            foreach (AssertCmd assertCmd in thisGate)
            {
                thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd));
            }
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> otherBlocks           = new List <Block>();

            foreach (Block block in thisAction.Blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block otherBlock = new Block();
                otherBlock.Cmds  = otherCmds;
                otherBlock.Label = "that_" + block.Label;
                block.Label      = "this_" + block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
                if (block.TransferCmd is GotoCmd)
                {
                    GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                    for (int i = 0; i < gotoCmd.labelNames.Count; i++)
                    {
                        gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i];
                    }
                }
            }
            foreach (Block block in thisAction.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd           = new ReturnCmd(block.TransferCmd.tok);
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List <Block>  otherGotoCmdLabelTargets = new List <Block>();
                List <string> otherGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            this.thatAction = new CodeExpr(otherLocVars, otherBlocks);
        }
Beispiel #8
0
 public override GotoCmd VisitGotoCmd(GotoCmd node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <GotoCmd>() != null);
     return(base.VisitGotoCmd((GotoCmd)node.Clone()));
 }
Beispiel #9
0
        public override Implementation VisitImplementation(Implementation node)
        {
            HashSet <Variable> start = new HashSet <Variable>(globalVarToDomainName.Keys);

            for (int i = 0; i < node.InParams.Count; i++)
            {
                string domainName = FindDomainName(node.Proc.InParams[i]);
                if (domainName != null)
                {
                    inoutParamToDomainName[node.InParams[i]] = domainName;
                    start.Add(node.InParams[i]);
                }
            }
            for (int i = 0; i < node.OutParams.Count; i++)
            {
                string domainName = FindDomainName(node.Proc.OutParams[i]);
                if (domainName != null)
                {
                    inoutParamToDomainName[node.OutParams[i]] = domainName;
                }
            }

            var oldErrorCount = this.errorCount;
            var impl          = base.VisitImplementation(node);

            if (oldErrorCount < this.errorCount)
            {
                return(impl);
            }

            Stack <Block>   dfsStack      = new Stack <Block>();
            HashSet <Block> dfsStackAsSet = new HashSet <Block>();

            availableLinearVars[node.Blocks[0]] = start;
            dfsStack.Push(node.Blocks[0]);
            dfsStackAsSet.Add(node.Blocks[0]);
            while (dfsStack.Count > 0)
            {
                Block b = dfsStack.Pop();
                dfsStackAsSet.Remove(b);
                HashSet <Variable> end = PropagateAvailableLinearVarsAcrossBlock(b);
                if (b.TransferCmd is ReturnCmd)
                {
                    foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(end))
                    {
                        Error(b.TransferCmd, string.Format("Global variable {0} must be available at a return", g.Name));
                    }
                    foreach (Variable v in node.OutParams)
                    {
                        if (FindDomainName(v) == null || end.Contains(v))
                        {
                            continue;
                        }
                        Error(b.TransferCmd, string.Format("Output variable {0} must be available at a return", v.Name));
                    }
                    continue;
                }
                GotoCmd gotoCmd = b.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    if (!availableLinearVars.ContainsKey(target))
                    {
                        availableLinearVars[target] = new HashSet <Variable>(end);
                        dfsStack.Push(target);
                        dfsStackAsSet.Add(target);
                    }
                    else
                    {
                        var savedAvailableVars = new HashSet <Variable>(availableLinearVars[target]);
                        availableLinearVars[target].IntersectWith(end);
                        if (savedAvailableVars.IsProperSupersetOf(availableLinearVars[target]) && !dfsStackAsSet.Contains(target))
                        {
                            dfsStack.Push(target);
                            dfsStackAsSet.Add(target);
                        }
                    }
                }
            }
            return(impl);
        }
Beispiel #10
0
        private string CreateNewImplementation(Implementation impl, List <Block> blocks)
        {
            if (!this.NameCounter.ContainsKey(impl.Name))
            {
                this.NameCounter.Add(impl.Name, 0);
            }
            this.NameCounter[impl.Name]++;

            var newInParams = new List <Variable>();

            foreach (var v in impl.Proc.InParams)
            {
                newInParams.Add(new Duplicator().VisitVariable(v.Clone() as Variable) as Variable);
            }

            var newOutParams = new List <Variable>();

            foreach (var v in impl.Proc.OutParams)
            {
                newOutParams.Add(new Duplicator().VisitVariable(v.Clone() as Variable) as Variable);
            }

            var newLocalParams = new List <Variable>();

            foreach (var v in impl.LocVars)
            {
                newLocalParams.Add(new Duplicator().VisitVariable(v.Clone() as Variable) as Variable);
            }

            var newBlocks = new List <Block>();

            foreach (var b in impl.Blocks)
            {
                if (blocks.Any(val => val.Label.Equals(b.Label)))
                {
                    continue;
                }

                var newCmds = new List <Cmd>();
                foreach (var cmd in b.Cmds)
                {
                    newCmds.Add(new Duplicator().Visit(cmd.Clone()) as Cmd);
                }

                TransferCmd transferCmd = null;
                if (b.TransferCmd is GotoCmd)
                {
                    transferCmd = new GotoCmd(Token.NoToken, new List <string>(), new List <Block>());
                }
                else
                {
                    transferCmd = new ReturnCmd(Token.NoToken);
                }

                newBlocks.Add(new Block(Token.NoToken, b.Label, newCmds, transferCmd));
            }

            foreach (var b in newBlocks)
            {
                if (!(b.TransferCmd is GotoCmd))
                {
                    continue;
                }

                var originalBlock    = impl.Blocks.Find(val => val.Label.Equals(b.Label));
                var originalTransfer = originalBlock.TransferCmd as GotoCmd;

                var gotoCmd = b.TransferCmd as GotoCmd;
                foreach (var target in originalTransfer.labelTargets)
                {
                    if (blocks.Any(val => val.Label.Equals(target.Label)))
                    {
                        continue;
                    }

                    var newTarget = newBlocks.Find(val => val.Label.Equals(target.Label));
                    gotoCmd.labelTargets.Add(newTarget);
                    gotoCmd.labelNames.Add(newTarget.Label);
                }
            }

            var newImpl = new Implementation(Token.NoToken, impl.Name + "#" + this.NameCounter[impl.Name],
                                             new List <TypeVariable>(), newInParams, newOutParams, newLocalParams, newBlocks, impl.Attributes);

            var newProc = this.CreateNewProcedure(newImpl, impl.Proc.Modifies);
            var newCons = this.CreateNewConstant(newImpl);

            this.AC.TopLevelDeclarations.Add(newProc);
            this.AC.TopLevelDeclarations.Add(newImpl);
            this.AC.TopLevelDeclarations.Add(newCons);

            return(newImpl.Name);
        }
Beispiel #11
0
 public override GotoCmd VisitGotoCmd(GotoCmd node)
 {
     return(base.VisitGotoCmd((GotoCmd)node.Clone()));
 }
Beispiel #12
0
 public override GotoCmd VisitGotoCmd(GotoCmd node)
 {
     add(node);
     return(base.VisitGotoCmd(node));
 }
Beispiel #13
0
 private void AddEdge(GotoCmd gotoCmd, Block b)
 {
     gotoCmd.AddTarget(b);
 }
Beispiel #14
0
        public static void ProcessCounterexamplesWOSymbolicOut(SDiffCounterexamples errors, List <Variable> globals, List <Variable> eqLocVars,
                                                               Implementation vtLeftProcImpl, Implementation vtRightProcImpl, List <Declaration> consts, List <Model> errModelList,
                                                               string v1Name, string v2Name)
        {
            List <Expr>  constraintExprs = new List <Expr>();
            List <Block> listBlocksV1    = new List <Block>();
            List <Block> listBlocksV2    = new List <Block>();

            Model[] errModelArray = errModelList.ToArray();

            var label = new GotoCmd(Token.NoToken, new List <String>()
            {
                "DONE"
            });

            label.labelNames = new List <string>(); // label.labelTargets = new List<Block>();
            label.labelNames.Add("DONE");           //label.labelTargets.Add("DONE");


            // First block
            var labels = new List <String>();

            for (int j = 0; j < errors.Count; j++)
            {
                labels.Add("Cex" + j);
            }

            labels.Add("ELSE");
            var labelEntry = new GotoCmd(Token.NoToken, labels);

            labelEntry.labelTargets = new List <Block>();

            for (int j = 0; j < errors.Count; j++)
            {
                labelEntry.labelNames.Add("Cex" + j);//labelEntry.labelTargets.Add("Cex" + j);
            }

            for (int i = 0; i < errors.Count; i++)
            {
                var impl  = errors[i].Impl;
                var trace = errors[i].Trace;

                //Log.Out(Log.Normal, "Attempting symbolic execution of [" + i + "] $ " + impl.Name);


                if (Options.GenerateCTrace)
                {
                    Log.Out(Log.Normal, "Constructing metatrace from location annotations");
                    var extractor = new SDiff.SymEx.TraceExtractor();
                    extractor.VisitTrace(trace);
                    //Log.Out(Log.CTrace, CTrace.Make(extractor.metaTrace));
                    var cTrace = CTrace.Make(extractor.metaTrace, consts, errModelArray[i], v1Name, v2Name);
                    //var cTrace = "";
                    if (cTrace.Trim() != "")
                    {
                        //note that the index for cex on the output shows 1,2,..., instead of 0,1,2....
                        var fname  = impl.Name + "_cex_" + (i + 1) + "_out.c";
                        var cexOut = new TokenTextWriter(impl.Name + "_cex_" + (i + 1) + "_out.c", true);
                        cexOut.WriteLine(cTrace);
                        cexOut.Close();
                        Log.Out(Log.CTrace, "n:" + (i + 1) + ":" + fname);
                        Log.Out(Log.CTrace, "w:" + fname);
                    }
                }

                Log.Out(Log.Normal, "Desugaring calls");
                //HACK!!!: changes havoc x; assume (x= uf(..)); --> x := uf(...)
                var deCall = new SDiff.SymEx.DesugarCallCmds();
                trace = deCall.VisitTrace(trace);

                //symbolic constants
                var symInParams = new List <Variable>(impl.InParams);
                foreach (var g in globals)
                {
                    symInParams.Add(g);
                }

                Log.Out(Log.Normal, "Executing trace downward");
                //symbolic stores (look at symex.cs for the datastructure)
                // var sTrace = SDiff.SymEx.Cexecutor.ExecDown(trace, symInParams);
                Log.Out(Log.Normal, "Executing trace upward");
                //looks at each assume to create the path constants
                //clean up the duplication of assignments
                //SDiff.SymEx.Cexecutor.ExecUp(sTrace);

                Log.Out(Log.Normal, "Grabbing final execution values");
                // var lastStore = sTrace.LastSCmd().Gammas.Last();
                // var firstCons = sTrace.FirstSCmd().Cons;

                // constraintExprs.Add(firstCons.Conjoin());

                //#hemr - generating new strategy right here with inlining counterexamples!

                // Second block
                List <Cmd> cmdsV1_Diff_inline = new List <Cmd>();
                List <Cmd> cmdsV2_Diff_inline = new List <Cmd>();

                Substitution replaceScopeV1 = delegate(Variable x)
                {
                    return(replaceScopeGeneric(vtLeftProcImpl, x));
                };

                Substitution replaceScopeV2 = delegate(Variable x)
                {
                    return(replaceScopeGeneric(vtRightProcImpl, x));
                };

                foreach (Block currentBlock in trace)
                {
                    if (currentBlock.ToString().Contains("inline$" + v1Name))
                    {
                        foreach (Cmd currentCmd in currentBlock.Cmds)
                        {
                            Cmd newCmd = Substituter.Apply(replaceScopeV1, currentCmd);
                            cmdsV1_Diff_inline.Add(newCmd);
                        }
                    }
                    else if (currentBlock.ToString().Contains("inline$" + v2Name))
                    {
                        foreach (Cmd currentCmd in currentBlock.Cmds)
                        {
                            Cmd newCmd = Substituter.Apply(replaceScopeV2, currentCmd);
                            cmdsV2_Diff_inline.Add(newCmd);
                        }
                    }
                }

                Block blockV1 = new Block(Token.NoToken, "Cex" + i, cmdsV1_Diff_inline, label);
                Block blockV2 = new Block(Token.NoToken, "Cex" + i, cmdsV2_Diff_inline, label);

                listBlocksV1.Add(blockV1);
                listBlocksV2.Add(blockV2);

                //#hemr - displaying values related to error model (at console level)

                Model currentModel = errModelArray[i];

                //var keys = currentModel.identifierToPartition.Keys;
                var keys = currentModel.Functions.Where(f => f.Arity == 0).Select(f => f.GetConstant());
            }

            Expr disjunctionDiffCond = Expr.False;

            foreach (Expr currentExpr in constraintExprs)
            {
                disjunctionDiffCond = Expr.Or(disjunctionDiffCond, currentExpr);
            }

            ProcessCounterexampleForDiffInliningWOSymbolicOut(eqLocVars, vtLeftProcImpl, vtRightProcImpl, v1Name, v2Name, listBlocksV1, listBlocksV2, labelEntry);
        }
Beispiel #15
0
        private void Transform4DoomedCheck(Implementation impl)
        {
            variable2SequenceNumber = new Dictionary <Variable, int>();
            incarnationOriginMap    = new Dictionary <Incarnation, Absy>();
            if (impl.Blocks.Count < 1)
            {
                return;
            }

            impl.PruneUnreachableBlocks();
            AddBlocksBetween(impl.Blocks);
            ResetPredecessors(impl.Blocks);

            GraphAnalyzer ga = new GraphAnalyzer(impl.Blocks);
            LoopRemover   lr = new LoopRemover(ga);

            lr.AbstractLoopUnrolling();

            impl.Blocks = ga.ToImplementation(out m_UncheckableBlocks);
            ResetPredecessors(impl.Blocks);

            // Check for the "BlocksBetween" if all their successors are in m_UncheckableBlocks
            List <Block> oldblocks = new List <Block>();

            oldblocks.AddRange(impl.Blocks);
            GenerateHelperBlocks(impl);
            #region Check for the "BlocksBetween" if all their successors are in m_UncheckableBlocks
            foreach (Block b in impl.Blocks)
            {
                if (oldblocks.Contains(b))
                {
                    continue;
                }
                GotoCmd gc = b.TransferCmd as GotoCmd;
                if (gc != null)
                {
                    bool allsuccUncheckable = true;
                    foreach (Block _b in gc.labelTargets)
                    {
                        if (!m_UncheckableBlocks.Contains(_b))
                        {
                            allsuccUncheckable = false; break;
                        }
                    }
                    if (allsuccUncheckable && !m_UncheckableBlocks.Contains(b))
                    {
                        m_UncheckableBlocks.Add(b);
                    }
                }
            }
            #endregion

            impl.Blocks = DeepCopyBlocks(impl.Blocks, m_UncheckableBlocks);

            m_BlockReachabilityMap = new Dictionary <Block, Variable>();
            List <Cmd> cs = GenerateReachabilityPredicates(impl);

            //foreach (Block test in getTheFFinalBlock(impl.Blocks[0]))
            //{
            //    test.Cmds.AddRange(cs);
            //}

            ResetPredecessors(impl.Blocks);
            //EmitImpl(impl,false);

            Dictionary <Variable, Expr> var2Expr = PassifyProgram(impl, new ModelViewInfo(program, impl));

            // Collect the last incarnation of each reachability variable in the passive program
            foreach (KeyValuePair <Block, Variable> kvp in m_BlockReachabilityMap)
            {
                if (var2Expr.ContainsKey(kvp.Value))
                {
                    m_LastReachVarIncarnation[kvp.Value] = (Expr)var2Expr[kvp.Value];
                }
            }
        }
Beispiel #16
0
        public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum)
            : base(proc, layerNum, availableUptoLayerNum)
        {
            CodeExpr codeExpr = ensures.Condition as CodeExpr;

            this.ensures       = ensures;
            this.moverType     = moverType;
            this.thisGate      = new List <AssertCmd>();
            this.thisAction    = codeExpr;
            this.thisInParams  = new List <Variable>();
            this.thisOutParams = new List <Variable>();
            this.thatGate      = new List <AssertCmd>();
            this.thatInParams  = new List <Variable>();
            this.thatOutParams = new List <Variable>();
            this.hasAssumeCmd  = false;

            foreach (Block block in codeExpr.Blocks)
            {
                block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd);
            }

            var cmds = thisAction.Blocks[0].Cmds;

            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null)
                {
                    break;
                }
                thisGate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True);
            }

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

            foreach (Variable x in proc.InParams)
            {
                this.thisInParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes);
                this.thatInParams.Add(y);
                map[x] = Expr.Ident(y);
            }
            foreach (Variable x in proc.OutParams)
            {
                this.thisOutParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes);
                this.thatOutParams.Add(y);
                map[x] = Expr.Ident(y);
            }
            List <Variable> thatLocVars = new List <Variable>();

            foreach (Variable x in thisAction.LocVars)
            {
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                map[x] = Expr.Ident(y);
                thatLocVars.Add(y);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);

            foreach (AssertCmd assertCmd in thisGate)
            {
                thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd));
            }
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> thatBlocks            = new List <Block>();

            foreach (Block block in thisAction.Blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block thatBlock = new Block();
                thatBlock.Cmds  = otherCmds;
                thatBlock.Label = "that_" + block.Label;
                block.Label     = "this_" + block.Label;
                thatBlocks.Add(thatBlock);
                blockMap[block] = thatBlock;
                if (block.TransferCmd is GotoCmd)
                {
                    GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                    for (int i = 0; i < gotoCmd.labelNames.Count; i++)
                    {
                        gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i];
                    }
                }
            }
            foreach (Block block in thisAction.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd           = new ReturnCmd(block.TransferCmd.tok);
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List <Block>  thatGotoCmdLabelTargets = new List <Block>();
                List <string> thatGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    thatGotoCmdLabelTargets.Add(blockMap[target]);
                    thatGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, thatGotoCmdLabelNames, thatGotoCmdLabelTargets);
            }
            this.thatAction = new CodeExpr(thatLocVars, thatBlocks);

            {
                VariableCollector collector = new VariableCollector();
                collector.Visit(codeExpr);
                this.actionUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }

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

            foreach (Block block in codeExpr.Blocks)
            {
                block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars));
            }
            this.modifiedGlobalVars = new HashSet <Variable>(modifiedVars.Where(x => x is GlobalVariable));

            {
                VariableCollector collector = new VariableCollector();
                this.thisGate.ForEach(assertCmd => collector.Visit(assertCmd));
                this.gateUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable));
            }
        }
Beispiel #17
0
        VCExpr LetVC(Block block,
                     Dictionary <int, Absy> label2absy,
                     Hashtable /*<Block, VCExprVar!>*/ blockVariables,
                     List <VCExprLetBinding> bindings,
                     ProverContext proverCtxt,
                     out int assertionCount)
        {
            Contract.Requires(label2absy != null);
            Contract.Requires(blockVariables != null);
            Contract.Requires(proverCtxt != null);
            Contract.Requires(cce.NonNullElements(bindings));
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            assertionCount = 0;
            VCExpressionGenerator gen = proverCtxt.ExprGen;

            Contract.Assert(gen != null);
            VCExprVar v = (VCExprVar)blockVariables[block];

            if (v == null)
            {
                /*
                 * For block A (= block), generate:
                 *   LET_binding A_correct = wp(A_body, (/\ S \in Successors(A) :: S_correct))
                 * with the side effect of adding the let bindings to "bindings" for any
                 * successor not yet visited.
                 */
                VCExpr  SuccCorrect;
                GotoCmd gotocmd = block.TransferCmd as GotoCmd;
                if (gotocmd == null)
                {
                    if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                    {
                        SuccCorrect = VCExpressionGenerator.False;
                    }
                    else
                    {
                        SuccCorrect = VCExpressionGenerator.True;
                    }
                }
                else
                {
                    Contract.Assert(gotocmd.labelTargets != null);
                    List <VCExpr> SuccCorrectVars = new List <VCExpr>(gotocmd.labelTargets.Count);
                    foreach (Block successor in gotocmd.labelTargets)
                    {
                        Contract.Assert(successor != null);
                        int    ac;
                        VCExpr s = LetVC(successor, label2absy, blockVariables, bindings, proverCtxt, out ac);
                        assertionCount += ac;
                        SuccCorrectVars.Add(s);
                    }
                    SuccCorrect = gen.NAry(VCExpressionGenerator.AndOp, SuccCorrectVars);
                }

                VCContext context = new VCContext(label2absy, proverCtxt);
                //        m_Context = context;

                VCExpr vc = Wlp.Block(block, SuccCorrect, context);
                assertionCount += context.AssertionCount;
                v = gen.Variable(block.Label + "_correct", Microsoft.Boogie.Type.Bool);

                bindings.Add(gen.LetBinding(v, vc));
                blockVariables.Add(block, v);
            }
            return(v);
        }
Beispiel #18
0
        public static List <Split /*!*/> /*!*/ DoSplit(Split initial, double maxCost, int max)
        {
            Contract.Requires(initial != null);
            Contract.Ensures(cce.NonNullElements(Contract.Result <List <Split> >()));

            List <Split> res = new List <Split>();

            res.Add(initial);

            while (res.Count < max)
            {
                Split best = null;
                int   bestIdx = 0, pos = 0;
                foreach (Split s in res)
                {
                    Contract.Assert(s != null);
                    s.ComputeBestSplit(); // TODO check totalCost first
                    if (s.totalCost > maxCost &&
                        (best == null || best.totalCost < s.totalCost) &&
                        (s.assertionCount > 1 || s.splitBlock != null))
                    {
                        best    = s;
                        bestIdx = pos;
                    }

                    pos++;
                }

                if (best == null)
                {
                    break; // no split found
                }
                Split s0, s1;

                bool splitStats = CommandLineOptions.Clo.TraceVerify;

                if (splitStats)
                {
                    Console.WriteLine("{0} {1} -->", best.splitBlock == null ? "SLICE" : ("SPLIT@" + best.splitBlock.Label),
                                      best.Stats);
                    if (best.splitBlock != null)
                    {
                        GotoCmd g = best.splitBlock.TransferCmd as GotoCmd;
                        if (g != null)
                        {
                            Console.Write("    exits: ");
                            foreach (Block b in cce.NonNull(g.labelTargets))
                            {
                                Contract.Assert(b != null);
                                Console.Write("{0} ", b.Label);
                            }

                            Console.WriteLine("");
                            Console.Write("    assumized: ");
                            foreach (Block b in best.assumizedBranches)
                            {
                                Contract.Assert(b != null);
                                Console.Write("{0} ", b.Label);
                            }

                            Console.WriteLine("");
                        }
                    }
                }

                if (best.splitBlock != null)
                {
                    s0 = best.SplitAt(0);
                    s1 = best.SplitAt(1);
                }
                else
                {
                    best.splitBlock = null;
                    s0 = best.SliceAsserts(best.assertionCost / 2, true);
                    s1 = best.SliceAsserts(best.assertionCost / 2, false);
                }

                if (true)
                {
                    List <Block> ss = new List <Block>();
                    ss.Add(s0.blocks[0]);
                    ss.Add(s1.blocks[0]);
                    try
                    {
                        best.SoundnessCheck(new HashSet <List <Block> >(new BlockListComparer()), best.blocks[0], ss);
                    }
                    catch (System.Exception e)
                    {
                        Console.WriteLine(e);
                        best.DumpDot(-1);
                        s0.DumpDot(-2);
                        s1.DumpDot(-3);
                        Contract.Assert(false);
                        throw new cce.UnreachableException();
                    }
                }

                if (splitStats)
                {
                    s0.ComputeBestSplit();
                    s1.ComputeBestSplit();
                    Console.WriteLine("    --> {0}", s0.Stats);
                    Console.WriteLine("    --> {0}", s1.Stats);
                }

                if (CommandLineOptions.Clo.TraceVerify)
                {
                    best.Print();
                }

                res[bestIdx] = s0;
                res.Add(s1);
            }

            return(res);
        }
Beispiel #19
0
        /////////////////////////////////////////////////////////////////////////////////////
        private void setControlStatement(BasicBlock current, GotoCmd gotoCmd, BasicBlock next)
        {
            if (gotoCmd.labelNames.Count == 0)
            {
                current.setControlStatement(new Programs.Statements.Block(current));
            }
            else if (gotoCmd.labelNames.Count == 1)
            {
                BasicBlock target = cfg.lookupOrAddNode(gotoCmd.labelNames[0]);
                current.setControlStatement(new UnconditionalBranch(current, target));
            }
            else
            {
                var conditionVariables = new List <ProgramVariable>();
                while ((1 << conditionVariables.Count) < gotoCmd.labelNames.Count)
                {
                    ProgramVariable nd = scope.makeFreshProgramVariable(pathConditionPrefix, makeBooleanType());
                    conditionVariables.Add(nd);
                    nondeterministicConditionVariables.Add(nd);
                }

                string basicLabel = "$cascade_" + labelIndex.ToString();
                labelIndex++;

                int currentTarget = 0;

                for (int i = 0; (1 << i) <= gotoCmd.labelNames.Count; i++)
                {
                    for (int j = 0; (j < (1 << i)) && ((1 << i) + j < gotoCmd.labelNames.Count); j += 2)
                    {
                        int        index = (1 << i) + j;
                        string     label = basicLabel + "_$" + i.ToString() + "_$" + j.ToString();
                        BasicBlock block = (i == 0) ? current : cfg.lookupOrAddNode(label);

                        string targetLabel1 =
                            (index * 2 < gotoCmd.labelNames.Count)
                                ? basicLabel + "_$" + (i + 1).ToString() + "_$" + (j * 2).ToString()
                                : gotoCmd.labelNames[currentTarget++];

                        string targetLabel2 =
                            (index * 2 + 1 < gotoCmd.labelNames.Count)
                                ? basicLabel + "_$" + (i + 1).ToString() + "_$" + (j * 2 + 1).ToString()
                                : (
                                (currentTarget < gotoCmd.labelNames.Count)
                                          ? gotoCmd.labelNames[currentTarget++]
                                          : null
                                );

                        BasicBlock target1 = cfg.lookupOrAddNode(targetLabel1);
                        BasicBlock target2 = (targetLabel2 == null) ? null : cfg.lookupOrAddNode(targetLabel2);

                        if (target2 != null)
                        {
                            block.setControlStatement(new ConditionalBranch(block, conditionVariables[i], target1,
                                                                            target2));
                        }
                        else
                        {
                            block.setControlStatement(new UnconditionalBranch(block, target1));
                        }
                    }
                }
            }
        }
Beispiel #20
0
        Block Visit(GraphNode node)
        {
            Contract.Requires(node != null);
            Contract.Ensures(Contract.Result <Block>() != null);
            Block orig = node.Block;

            if (newBlocks.TryGetValue(orig, out var nw))
            {
                Contract.Assert(nw != null);
            }
            else
            {
                List <Cmd>  body;
                TransferCmd tcmd;
                Contract.Assert(orig.TransferCmd != null);

                if (next == null && node.IsCutPoint)
                {
                    // as the body, use the assert/assume commands that make up the loop invariant
                    body = new List <Cmd>();
                    foreach (Cmd /*!*/ c in node.Body)
                    {
                        Contract.Assert(c != null);
                        if (c is PredicateCmd || c is CommentCmd)
                        {
                            body.Add(c);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (soundLoopUnrolling)
                    {
                        body.Add(new AssertCmd(orig.tok, Bpl.Expr.False));
                    }
                    else
                    {
                        body.Add(new AssumeCmd(orig.tok, Bpl.Expr.False));
                    }

                    tcmd = new ReturnCmd(orig.TransferCmd.tok);
                }
                else
                {
                    body = node.Body;
                    List <Block> newSuccs = new List <Block>();

                    foreach (GraphNode succ in node.ForwardEdges)
                    {
                        Block s;
                        if (containingSCC[node] == containingSCC[succ])
                        {
                            s = Visit(succ);
                        }
                        else
                        {
                            Contract.Assert(head != null); // follows from object invariant
                            s = head.Visit(succ);
                        }

                        newSuccs.Add(s);
                    }

                    Contract.Assert(next != null ||
                                    node.BackEdges.Count == 0); // follows from if-else test above and the GraphNode invariant
                    foreach (GraphNode succ in node.BackEdges)
                    {
                        Contract.Assert(next != null); // since if we get here, node.BackEdges.Count != 0
                        Block s = next.Visit(succ);
                        newSuccs.Add(s);
                    }

                    if (newSuccs.Count == 0)
                    {
                        tcmd = new ReturnCmd(orig.TransferCmd.tok);
                    }
                    else
                    {
                        tcmd = new GotoCmd(orig.TransferCmd.tok, newSuccs);
                    }
                }

                nw = new Block(orig.tok, orig.Label + "#" + this.c, body, tcmd);
                newBlocks.Add(orig, nw);
                newBlockSeqGlobal.Add(nw);
            }

            return(nw);
        }
Beispiel #21
0
    private int InlineCallCmd(Block block, CallCmd callCmd, Implementation impl, List<Cmd> newCmds,
      List<Block> newBlocks, int lblCount)
    {
      Contract.Assume(impl != null);
      Contract.Assert(cce.NonNull(impl.OriginalBlocks).Count > 0);

      // do inline now
      int nextlblCount = lblCount + 1;
      string nextBlockLabel = block.Label + "$" + nextlblCount;

      // run the callback before each inline
      if (inlineCallback != null)
      {
        inlineCallback(impl);
      }

      // increment the counter for the procedure to be used in constructing the locals and formals
      NextInlinedProcLabel(impl.Proc.Name);

      BeginInline(impl);

      List<Block /*!*/> /*!*/
        inlinedBlocks = CreateInlinedBlocks(callCmd, impl, nextBlockLabel);
      Contract.Assert(cce.NonNullElements(inlinedBlocks));

      EndInline();

      if (inlineDepth >= 0)
      {
        Debug.Assert(inlineDepth > 0);
        inlineDepth = inlineDepth - 1;
      }
      else
      {
        recursiveProcUnrollMap[impl.Name] = recursiveProcUnrollMap[impl.Name] - 1;
      }

      bool inlinedSomething = true;
      inlinedBlocks = DoInlineBlocks(inlinedBlocks, ref inlinedSomething);

      if (inlineDepth >= 0)
      {
        inlineDepth = inlineDepth + 1;
      }
      else
      {
        recursiveProcUnrollMap[impl.Name] = recursiveProcUnrollMap[impl.Name] + 1;
      }

      Block /*!*/
        startBlock = inlinedBlocks[0];
      Contract.Assert(startBlock != null);

      GotoCmd gotoCmd = new GotoCmd(Token.NoToken, new List<String> {startBlock.Label});
      Block newBlock = new Block(block.tok, ((lblCount == 0) ? (block.Label) : (block.Label + "$" + lblCount)), newCmds,
        gotoCmd);

      newBlocks.Add(newBlock);
      newBlocks.AddRange(inlinedBlocks);

      return nextlblCount;
    }
Beispiel #22
0
 public override GotoCmd VisitGotoCmd(GotoCmd node)
 {
     node.labelTargets = null;
     return(node);
 }
Beispiel #23
0
        private static void ProcessCounterexampleForDiffInliningWOSymbolicOut(List <Variable> eqLocVars, Implementation vtLeftProcImpl, Implementation vtRightProcImpl, string v1Name, string v2Name, List <Block> listBlocksV1, List <Block> listBlocksV2, GotoCmd labelEntry)
        {
            if (vtLeftProcImpl != null && vtRightProcImpl != null) //only when diff inlining is on
            {
                var blocksLeftProcImpl      = vtLeftProcImpl.Blocks.ToArray();
                var blocksRightProcImpl     = vtRightProcImpl.Blocks.ToArray();
                var firstCmdThirdBlockLeft  = new AssumeCmd(Token.NoToken, Expr.Not(Expr.True));
                var firstCmdThirdBlockRight = new AssumeCmd(Token.NoToken, Expr.Not(Expr.True));

                var leftThirdBlockCmdElems  = blocksLeftProcImpl[2].Cmds;
                var rightThirdBlockCmdElems = blocksRightProcImpl[2].Cmds;

                leftThirdBlockCmdElems[0]  = firstCmdThirdBlockLeft;
                rightThirdBlockCmdElems[0] = firstCmdThirdBlockRight;

                blocksLeftProcImpl[2].Cmds  = leftThirdBlockCmdElems;
                blocksRightProcImpl[2].Cmds = rightThirdBlockCmdElems;

                // re-building the first block (only the goto cmds)
                blocksLeftProcImpl[0].TransferCmd  = labelEntry;
                blocksRightProcImpl[0].TransferCmd = labelEntry;

                // removing the second block
                vtLeftProcImpl.Blocks.RemoveAt(1);
                vtRightProcImpl.Blocks.RemoveAt(1);

                foreach (Block currentBlockV1 in listBlocksV1)
                {
                    vtLeftProcImpl.Blocks.Add(currentBlockV1);
                }

                foreach (Block currentBlockV2 in listBlocksV2)
                {
                    vtRightProcImpl.Blocks.Add(currentBlockV2);
                }

                //vtLeftProcImpl.Blocks.Add(blockV1);
                //vtRightProcImpl.Blocks.Add(blockV2);

                //hemr - handling local variable declarations
                List <Variable> locVarsV1_diff_inline = new List <Variable>();
                List <Variable> locVarsV2_diff_inline = new List <Variable>();

                foreach (Variable currentVariable in eqLocVars)
                {
                    if (currentVariable.ToString().Contains("inline$" + v1Name))
                    {
                        locVarsV1_diff_inline.Add(currentVariable);
                    }

                    else if (currentVariable.ToString().Contains("inline$" + v2Name))
                    {
                        locVarsV2_diff_inline.Add(currentVariable);
                    }
                }

                vtLeftProcImpl.LocVars  = locVarsV1_diff_inline;
                vtRightProcImpl.LocVars = locVarsV2_diff_inline;
            }
        }
Beispiel #24
0
 private void AddEdge(GotoCmd gotoCmd, Block b)
 {
     gotoCmd.labelNames.Add(b.Label);
     gotoCmd.labelTargets.Add(b);
 }
Beispiel #25
0
            public static GraphNode ComputeGraphInfo(GraphNode from, Block b,
                                                     Dictionary <Block /*!*/, GraphNode /*!*/> /*!*/ gd, HashSet <Block> beingVisited)
            {
                Contract.Requires(beingVisited != null);
                Contract.Requires(b != null);
                Contract.Requires(cce.NonNullDictionaryAndValues(gd));
                Contract.Ensures(Contract.Result <GraphNode>() != null);
                GraphNode g;

                if (gd.TryGetValue(b, out g))
                {
                    Contract.Assume(from != null);
                    Contract.Assert(g != null);
                    if (beingVisited.Contains(b))
                    {
                        // it's a cut point
                        g.isCutPoint = true;
                        from.BackEdges.Add(g);
                        g.Predecessors.Add(from);
                    }
                    else
                    {
                        from.ForwardEdges.Add(g);
                        g.Predecessors.Add(from);
                    }
                }
                else
                {
                    List <Cmd> body = GetOptimizedBody(b.Cmds);
                    g = new GraphNode(b, body);
                    gd.Add(b, g);
                    if (from != null)
                    {
                        from.ForwardEdges.Add(g);
                        g.Predecessors.Add(from);
                    }

                    if (body != b.Cmds)
                    {
                        // the body was optimized -- there is no way through this block
                    }
                    else
                    {
                        beingVisited.Add(b);

                        GotoCmd gcmd = b.TransferCmd as GotoCmd;
                        if (gcmd != null)
                        {
                            Contract.Assume(gcmd.labelTargets != null);
                            foreach (Block /*!*/ succ in gcmd.labelTargets)
                            {
                                Contract.Assert(succ != null);
                                ComputeGraphInfo(g, succ, gd, beingVisited);
                            }
                        }

                        beingVisited.Remove(b);
                    }
                }

                return(g);
            }
Beispiel #26
0
    public override Implementation VisitImplementation(Implementation node)
    {
      if (civlTypeChecker.procToAtomicAction.ContainsKey(node.Proc) ||
          civlTypeChecker.procToIntroductionAction.ContainsKey(node.Proc) ||
          civlTypeChecker.procToLemmaProc.ContainsKey(node.Proc))
        return node;

      node.PruneUnreachableBlocks();
      node.ComputePredecessorsForBlocks();
      GraphUtil.Graph<Block> graph = Program.GraphFromImpl(node);
      graph.ComputeLoops();

      HashSet<Variable> start = new HashSet<Variable>(globalVarToDomainName.Keys);
      for (int i = 0; i < node.InParams.Count; i++)
      {
        Variable v = node.Proc.InParams[i];
        string domainName = FindDomainName(v);
        if (domainName != null)
        {
          var kind = FindLinearKind(v);
          inParamToLinearQualifier[node.InParams[i]] = new LinearQualifier(domainName, kind);
          if (kind == LinearKind.LINEAR || kind == LinearKind.LINEAR_IN)
          {
            start.Add(node.InParams[i]);
          }
        }
      }

      for (int i = 0; i < node.OutParams.Count; i++)
      {
        string domainName = FindDomainName(node.Proc.OutParams[i]);
        if (domainName != null)
        {
          outParamToDomainName[node.OutParams[i]] = domainName;
        }
      }

      var oldErrorCount = checkingContext.ErrorCount;
      var impl = base.VisitImplementation(node);
      if (oldErrorCount < checkingContext.ErrorCount)
        return impl;

      Stack<Block> dfsStack = new Stack<Block>();
      HashSet<Block> dfsStackAsSet = new HashSet<Block>();
      availableLinearVars[node.Blocks[0]] = start;
      dfsStack.Push(node.Blocks[0]);
      dfsStackAsSet.Add(node.Blocks[0]);
      while (dfsStack.Count > 0)
      {
        Block b = dfsStack.Pop();
        dfsStackAsSet.Remove(b);
        HashSet<Variable> end = PropagateAvailableLinearVarsAcrossBlock(b);
        if (b.TransferCmd is ReturnCmd)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(end))
          {
            Error(b.TransferCmd, $"Global variable {g.Name} must be available at a return");
          }

          foreach (Variable v in node.InParams)
          {
            if (FindDomainName(v) == null || FindLinearKind(v) == LinearKind.LINEAR_IN || end.Contains(v)) continue;
            Error(b.TransferCmd, $"Input variable {v.Name} must be available at a return");
          }

          foreach (Variable v in node.OutParams)
          {
            if (FindDomainName(v) == null || end.Contains(v)) continue;
            Error(b.TransferCmd, $"Output variable {v.Name} must be available at a return");
          }

          continue;
        }

        GotoCmd gotoCmd = b.TransferCmd as GotoCmd;
        foreach (Block target in gotoCmd.labelTargets)
        {
          if (!availableLinearVars.ContainsKey(target))
          {
            availableLinearVars[target] = new HashSet<Variable>(end);
            dfsStack.Push(target);
            dfsStackAsSet.Add(target);
          }
          else
          {
            var savedAvailableVars = new HashSet<Variable>(availableLinearVars[target]);
            availableLinearVars[target].IntersectWith(end);
            if (savedAvailableVars.IsProperSupersetOf(availableLinearVars[target]) && !dfsStackAsSet.Contains(target))
            {
              dfsStack.Push(target);
              dfsStackAsSet.Add(target);
            }
          }
        }
      }

      if (graph.Reducible)
      {
        foreach (Block header in graph.Headers)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(availableLinearVars[header]))
          {
            Error(header, $"Global variable {g.Name} must be available at a loop head");
          }
        }
      }

      return impl;
    }
Beispiel #27
0
 public TerminatedAtGotoWithUnsatisfiableTargets(GotoCmd gotoCmd)
 {
     this.ExitLocation = gotoCmd.GetProgramLocation();
 }
Beispiel #28
0
    // result[0] is the entry block
    protected List<Block /*!*/> /*!*/ CreateInlinedBlocks(CallCmd callCmd, Implementation impl, string nextBlockLabel)
    {
      Contract.Requires(nextBlockLabel != null);
      Contract.Requires(impl != null);
      Contract.Requires(impl.Proc != null);
      Contract.Requires(callCmd != null);
      Contract.Requires(codeCopier.substMap != null);
      Contract.Requires(codeCopier.oldSubstMap != null);

      Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
      List<Block /*!*/> /*!*/
        implBlocks = cce.NonNull(impl.OriginalBlocks);
      Contract.Assert(implBlocks.Count > 0);

      Procedure proc = impl.Proc;
      string startLabel = implBlocks[0].Label;

      List<Block /*!*/> /*!*/
        inlinedBlocks = new List<Block /*!*/>();

      // create in block
      List<Cmd> inCmds = new List<Cmd>();

      // assign in parameters
      for (int i = 0; i < impl.InParams.Count; ++i)
      {
        Cmd cmd = Cmd.SimpleAssign(impl.tok,
          (IdentifierExpr) codeCopier.Subst(cce.NonNull(impl.InParams[i])),
          cce.NonNull(callCmd.Ins[i]));
        inCmds.Add(cmd);
      }

      // inject requires
      for (int i = 0; i < proc.Requires.Count; i++)
      {
        Requires /*!*/
          req = cce.NonNull(proc.Requires[i]);
        inCmds.Add(InlinedRequires(callCmd, req));
      }

      List<Variable> locVars = cce.NonNull(impl.OriginalLocVars);

      // havoc locals and out parameters in case procedure is invoked in a loop
      List<IdentifierExpr> havocVars = new List<IdentifierExpr>();
      foreach (Variable v in locVars)
      {
        havocVars.Add((IdentifierExpr) codeCopier.Subst(v));
      }

      foreach (Variable v in impl.OutParams)
      {
        havocVars.Add((IdentifierExpr) codeCopier.Subst(v));
      }

      if (havocVars.Count > 0)
      {
        inCmds.Add(new HavocCmd(Token.NoToken, havocVars));
      }

      // add where clauses of local vars as assume
      for (int i = 0; i < locVars.Count; ++i)
      {
        Expr whereExpr = (cce.NonNull(locVars[i])).TypedIdent.WhereExpr;
        if (whereExpr != null)
        {
          whereExpr = codeCopier.CopyExpr(whereExpr);
          // FIXME we cannot overwrite it, can we?!
          (cce.NonNull(locVars[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd /*!*/
            a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // add where clauses of output params as assume
      for (int i = 0; i < impl.OutParams.Count; ++i)
      {
        Expr whereExpr = (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr;
        if (whereExpr != null)
        {
          whereExpr = codeCopier.CopyExpr(whereExpr);
          // FIXME likewise
          (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd /*!*/
            a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // assign modifies old values
      foreach (IdentifierExpr /*!*/ mie in proc.Modifies)
      {
        Contract.Assert(mie != null);
        Variable /*!*/
          mvar = cce.NonNull(mie.Decl);
        AssignCmd assign = Cmd.SimpleAssign(impl.tok, (IdentifierExpr) cce.NonNull(codeCopier.OldSubst(mvar)), mie);
        inCmds.Add(assign);
      }

      GotoCmd inGotoCmd =
        new GotoCmd(callCmd.tok, new List<String> {GetInlinedProcLabel(proc.Name) + "$" + startLabel});
      Block inBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Entry", inCmds, inGotoCmd);
      inlinedBlocks.Add(inBlock);

      // inject the blocks of the implementation
      Block intBlock;
      foreach (Block block in implBlocks)
      {
        List<Cmd> copyCmds = codeCopier.CopyCmdSeq(block.Cmds);
        if (0 <= inlineDepth)
        {
          copyCmds = RemoveAsserts(copyCmds);
        }

        TransferCmd transferCmd =
          CreateInlinedTransferCmd(cce.NonNull(block.TransferCmd), GetInlinedProcLabel(proc.Name));
        intBlock = new Block(block.tok, GetInlinedProcLabel(proc.Name) + "$" + block.Label, copyCmds, transferCmd);
        inlinedBlocks.Add(intBlock);
      }

      // create out block
      List<Cmd> outCmds = new List<Cmd>();

      // inject ensures
      for (int i = 0; i < proc.Ensures.Count; i++)
      {
        Ensures /*!*/
          ens = cce.NonNull(proc.Ensures[i]);
        outCmds.Add(InlinedEnsures(callCmd, ens));
      }

      // assign out params
      for (int i = 0; i < impl.OutParams.Count; ++i)
      {
        Expr /*!*/
          cout_exp = (IdentifierExpr) cce.NonNull(codeCopier.Subst(cce.NonNull(impl.OutParams[i])));
        Cmd cmd = Cmd.SimpleAssign(impl.tok, cce.NonNull(callCmd.Outs[i]), cout_exp);
        outCmds.Add(cmd);
      }

      // create out block
      GotoCmd outGotoCmd = new GotoCmd(Token.NoToken, new List<String> {nextBlockLabel});
      Block outBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Return", outCmds, outGotoCmd);
      inlinedBlocks.Add(outBlock);

      return inlinedBlocks;
    }
        /// <summary>
        /// Instrument the loop.
        /// </summary>
        /// <param name="node">The merge node.</param>
        private void InstrumentLoop(ProgramNode node)
        {
            // skips asserts to preserve the invariants at the loop head
            int i = 1;

            while (node.Block.Cmds.Count > i && node.Block.Cmds[i] is AssertCmd)
            {
                AssertCmd assert = node.Block.Cmds[i] as AssertCmd;
                if (!ContainsAttribute(assert, "originated_from_invariant"))
                {
                    break;
                }

                i = i + 1;
            }

            // the block should have source location information for instrumentation to work
            if (node.Block.Cmds[0] is AssertCmd)
            {
                AssertCmd assert = node.Block.Cmds[0] as AssertCmd;
                if (ContainsAttribute(assert, SourceLocationKey))
                {
                    node.Block.Cmds.Insert(i, assert);
                    node.Block.Cmds.RemoveAt(0);

                    // insert a barrier at the beginning of the merge block
                    AddBarrier(node.Implementation, node.Block, i);

                    // get the header nodes in the loop
                    List <Block> predecessors = new List <Block>();
                    foreach (Block block in program.Implementations.SelectMany(x => x.Blocks))
                    {
                        if (block.TransferCmd is GotoCmd)
                        {
                            GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                            if (gotoCmd.labelTargets.Contains(node.Block))
                            {
                                predecessors.Add(block);
                            }
                        }
                    }

                    foreach (Block predecessor in predecessors)
                    {
                        if (analyzer.Graph.BackEdges.Any(x => x.Destination == node && x.Source.Block == predecessor))
                        {
                            continue;
                        }

                        // identify the location of the initialize statement of the loop
                        int index = predecessor.Cmds.Count - 1;
                        while (index >= 0)
                        {
                            if (predecessor.Cmds[index] is AssertCmd)
                            {
                                break;
                            }
                            index = index - 1;
                        }

                        if (index != -1)
                        {
                            // create an assert from the block source location since initializers don't have source locations
                            int location = QKeyValue.FindIntAttribute(assert.Attributes, SourceLocationKey, -1);
                            if (location != -1)
                            {
                                assert = predecessor.Cmds[index] as AssertCmd;

                                // becomes true when there is only one command in the block
                                // in those cases, we don't need to need to add a new assert attribute
                                if (!ContainsAttribute(assert, BlockSourceKey))
                                {
                                    // create a new assert to store the location information
                                    LiteralExpr locationValue     = new LiteralExpr(Token.NoToken, BigNum.FromInt(location));
                                    QKeyValue   sourceLocationKey = new QKeyValue(Token.NoToken, SourceLocationKey, new List <object>()
                                    {
                                        locationValue
                                    }, null);

                                    LiteralExpr literal = new LiteralExpr(Token.NoToken, true);
                                    assert            = new AssertCmd(Token.NoToken, literal);
                                    assert.Attributes = sourceLocationKey;

                                    index = index + 2;
                                    predecessor.Cmds.Insert(index, assert);
                                }

                                Implementation implementation = program.Implementations.First(x => x.Blocks.Contains(predecessor));

                                // insert a barrier at the end of the header block
                                AddBarrier(implementation, predecessor, index + 1);
                            }
                        }
                    }
                }
            }
        }