protected void Visit(APC pc, AElement pre, int depth)
        {
            APC      lastPC;
            AElement preConditionAtTheBlockEntry;

            if (ShoudStopTheVisit(pc, pre, depth, out lastPC, out preConditionAtTheBlockEntry))
            {
                return;
            }

            pre = preConditionAtTheBlockEntry;
            pc  = lastPC;

            var md = this.Mdriver;

            foreach (var prePC in CFG.Predecessors(lastPC))
            {
                // nothing to do
                if (md.BasicFacts.IsUnreachable(prePC))
                {
                    continue;
                }

                // Widening: stop after one iteration
                if (this.underVisit.Contains(lastPC))
                {
                    this.LoopHit = true;

                    Trace("Applying simple 1-iteration widening", pre);

                    return;
                }

                if (CFG.IsForwardBackEdgeTarget(pc))
                {
                    Trace("Reached the target of a forward backedge", pre);

                    this.LoopHit = true;

                    this.underVisit.Add(lastPC);

                    Visit(prePC, md.BackwardTransfer(pc, prePC, pre, this), depth + 1);

                    this.underVisit.Remove(lastPC);
                }
                else
                {
                    var newPre = md.BackwardTransfer(pc, prePC, pre, this);

                    Visit(prePC, newPre, depth + 1);
                }
            }
        }
                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));
                            }
                        }
                    }
                }
 public bool IsForwardBackEdgeTarget(APC ppoint)
 {
     return(underlying.IsForwardBackEdgeTarget(ppoint));
 }