public bool HasSinglePredecessor(APC ppoint, out APC singlePredecessor, bool skipContracts)
 {
     CallAdaption.Push <IEdgeSubroutineAdaptor>(this);
     try
     {
         return(underlying.HasSinglePredecessor(ppoint, out singlePredecessor, skipContracts));
     }
     finally {
         CallAdaption.Pop(this);
     }
 }
        protected APC VisitBlock(APC pc, AElement preCondition, out AElement newPrecondition)
        {
            var pcHead = pc.FirstInBlock();

            newPrecondition = preCondition;

            APC prePC;

            while (CFG.HasSinglePredecessor(pc, out prePC))
            {
                // We found the head!
                if (pc.Equals(pcHead))
                {
                    return(pcHead);
                }

                // nothing to do, kill search
                if (this.Mdriver.BasicFacts.IsUnreachable(pc))
                {
                    Trace("Killing path as pc is unreachable", newPrecondition);

                    newPrecondition = this.NoCondition;
                    return(pc);
                }

                newPrecondition = this.Mdriver.BackwardTransfer(pc, prePC, newPrecondition, this);

                if (this.IsNoCondition(newPrecondition))
                {
                    Trace("Killing path as we the underlyng analysis returned bottom", newPrecondition);
                    return(pc);
                }

                pc = prePC;
            }

            return(pc);
        }
                private void FixpointComputation(APC entry, Postconditions initialState)
                {
                    var todo = new List <Tuple <APC, Preconditions> >()
                    {
                        new Tuple <APC, Preconditions>(entry, initialState)
                    };
                    var stable = new Set <APC>();

                    while (todo.Count != 0)
                    {
                        this.timeout.CheckTimeOut("backwards postcondition propagation");

                        var next = todo.ExtractFirst();

                        var nextPC    = next.Item1;
                        var nextState = next.Item2;

                        var newPre = nextState;

                        // do the block
                        {
                            APC pred;
                            while (CFG.HasSinglePredecessor(nextPC, out pred) && !CFG.IsJoinPoint(nextPC))
                            {
                                this.timeout.CheckTimeOut("backwards postcondition propagation (block)");

                                //var post = CFG.Predecessors(nextPC).First();
                                newPre = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this);

                                // no pre, killing the path
                                if (newPre == null)
                                {
                                    break;
                                }

                                // TODO: check for contraddictions

                                nextPC = pred;
                            }
                        }
                        if (nextPC.Equals(CFG.EntryAfterRequires) || nextPC.Equals(CFG.Entry))
                        {
                            this.invariants = newPre;

                            continue;
                        }

                        var fixpointReached = false;

                        if (CFG.IsJoinPoint(nextPC))
                        {
                            Preconditions prev;
                            if (this.joinPoints.TryGetValue(nextPC, out prev))
                            {
                                newPre = Join(prev, newPre, CFG.IsForwardBackEdgeTarget(nextPC.Block.First), out fixpointReached);

                                if (fixpointReached)
                                {
                                    stable.Add(nextPC.Block.First);
                                }
                            }
                            joinPoints[nextPC] = newPre;
                        }

                        // Split in the backwards analysis
                        foreach (var pred in CFG.Predecessors(nextPC))
                        {
                            if (fixpointReached && CFG.IsForwardBackEdge(pred, nextPC))
                            {
                                continue;
                            }
                            if (this.Mdriver.IsUnreachable(nextPC))
                            {
                                continue;
                            }
                            var transf = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this);
                            if (transf != null)
                            {
                                todo.Add(new Tuple <APC, Preconditions>(pred, transf));
                            }
                        }
                    }
                }