示例#1
0
            protected override UpInfo BeforePopDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack,
                                                          CountedEnum counted, PathInfo down, PathInfo here, UpInfo upSum, UpInfo childUp)
            {
                Dependency top = currentPath.Peek();

                bool isEndOfCycle = _onPath.Get(top.UsedItem) > 0;

                if (childUp.FoundPathBelow || isEnd || isEndOfCycle)
                {
                    _countedObjectsPerItem
                    .GetOrAdd(top.UsedItem, () => new HashSet <IMatchableObject>())
                    .Add(down.CountedObject);
                }

                if (isEnd || isEndOfCycle)
                {
                    if (_ignorePrefixPaths && childUp.FoundPathBelow)
                    {
                        // don't add this prefix path to list of found paths; however, the node will
                        // be reached and have its correct end flag
                    }
                    else
                    {
                        _foundPaths.Add(here);
                    }
                    return(new UpInfo(true));
                }
                else
                {
                    return(new UpInfo(upSum.FoundPathBelow | childUp.FoundPathBelow));
                }
            }
示例#2
0
            protected override DownAndHere AfterPushDependency(Stack <Dependency> currentPath, bool isEnd,
                                                               bool isLoopBack, CountedEnum counted, PathInfo down)
            {
                Dependency top      = currentPath.Peek();
                PathNode   pathNode = new PathNode(down.Tail, top, isEnd,
                                                   isMatchedByCountSymbol: counted != CountedEnum.NotCounted, isEndOfCycle: isLoopBack);
                PathInfo downInfo = new PathInfo(down.Root, down.RootIsCounted,
                                                 counted == CountedEnum.DependencyCounted ? top :
                                                 counted == CountedEnum.UsedItemCounted ? top.UsedItem : down.CountedObject, pathNode);

                return(new DownAndHere(downInfo, downInfo));
            }
示例#3
0
            protected override DownAndHere AfterPushDependency(Stack <Dependency> currentPath, bool isEnd,
                                                               bool isLoopBack, CountedEnum counted, Ignore down)
            {
                if (isEnd)
                {
                    _recordedPaths.Add(string.Join("/", currentPath.Reverse()));
                    switch (counted)
                    {
                    case CountedEnum.DependencyCounted:
                        _countedObjects.Add(currentPath.Peek());
                        break;

                    case CountedEnum.UsedItemCounted:
                        _countedObjects.Add(currentPath.Peek().UsedItem);
                        break;
                    }
                }
                return(new DownAndHere(Ignore.Om, Ignore.Om));
            }
示例#4
0
 protected override Ignore BeforePopDependency(Stack <Dependency> currentPath, bool isEnd, bool isLoopBack, CountedEnum counted, Ignore down, Ignore here,
                                               Ignore upSum, Ignore childUp)
 {
     return(Ignore.Om);
 }
 protected abstract TUpInfo BeforePopDependency(Stack <TDependency> currentPath, bool isEnd, bool isLoopBack,
                                                CountedEnum counted, TDownInfo down, THereInfo here, TUpInfo upSum, TUpInfo childUp);
 protected abstract DownAndHere AfterPushDependency(Stack <TDependency> currentPath, bool isEnd, bool isLoopBack,
                                                    CountedEnum counted, TDownInfo down);
        private TUpInfo Traverse([NotNull] TItem tail, [NotNull] Dictionary <TItem, TDependency[]> incidentDependencies,
                                 IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeDependencyState,
                                 TDownInfo rawDown, HashSet <TPathState> statesOnPath)
        {
            if (!beforeDependencyState.CanContinue)
            {
                throw new ArgumentException("Traverse must be called with continueable state", nameof(beforeDependencyState));
            }
            _checkAbort();

            TUpInfo upSum;
            bool    visitSuccessors = ShouldVisitSuccessors(tail, _currentPath, out upSum);

            if (visitSuccessors)
            {
                // We are at this item for the first time - check whether we find a path to some defined end

                TDependency[] dependencies;
                if (!incidentDependencies.TryGetValue(tail, out dependencies))
                {
                    dependencies = NO_DEPENDENCIES;
                }
                foreach (var nextDep in dependencies)
                {
                    bool dependencyIsCounted;
                    IBeforeItemGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeItemState =
                        beforeDependencyState.Advance(nextDep, (m, d) => m.IsMatch(d), out dependencyIsCounted);
                    if (beforeItemState.CanContinue)
                    {
                        TItem nextTail = nextDep.UsedItem;
                        bool  atEnd;
                        bool  itemIsCounted;
                        IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeNextDependencyState =
                            beforeItemState.Advance(nextTail, (m, i) => ItemMatch.IsMatch(m, i), out atEnd, out itemIsCounted);

                        _currentPath.Push(nextDep);

                        CountedEnum counted =
                            dependencyIsCounted ? CountedEnum.DependencyCounted :
                            itemIsCounted ? CountedEnum.UsedItemCounted :
                            CountedEnum.NotCounted;

                        var  stateElement = CreateStateElement(beforeNextDependencyState, nextDep);
                        bool newOnPath    = statesOnPath.Add(stateElement);

                        DownAndHere downAndHere = AfterPushDependency(_currentPath, atEnd, !newOnPath, counted, rawDown);

                        TUpInfo childUp;
                        if (_currentPath.Count < _maxRecursionDepth &&
                            beforeNextDependencyState.CanContinue &&
                            newOnPath)
                        {
                            childUp = Traverse(nextTail, incidentDependencies, beforeNextDependencyState,
                                               downAndHere.Down, statesOnPath);
                            statesOnPath.Remove(stateElement);
                        }
                        else
                        {
                            childUp = default(TUpInfo); // ??? as above ____
                        }
                        upSum = BeforePopDependency(_currentPath, atEnd, !newOnPath, counted, rawDown, downAndHere.Save, upSum, childUp);

                        _currentPath.Pop();
                    }
                }
            }
            upSum = AfterVisitingSuccessors(visitSuccessors, tail, _currentPath, upSum);

            return(upSum);
        }