internal SequenceSearchState(SequenceSearchState <T> other, IMinimalDAGNode <T> nextNode, int stepDirection)
 {
     Index       = other.Index + stepDirection;
     CurrentNode = nextNode;
     //PreviousNode = other.CurrentNode;
     ValuePool            = new List <T>(other.ValuePool);             //.ToList();
     UsedValues           = new Dictionary <int, T>(other.UsedValues); // { Index, CurrentNode.GetValue() };
     this.WildCardIndices = new List <int>(other.WildCardIndices);
     this.WildCardCount   = other.WildCardCount;
 }
Example #2
0
        /// <summary>
        /// Performs the actual DFS search, finding all <see cref="SequenceSearchState{T}"/> that match the <see cref="Pattern{char}"/>
        /// </summary>
        /// <param name="searchState"></param>
        /// <param name="nextRelativeSelector"></param>
        /// <param name="sequenceBoundaries"></param>
        /// <param name="stepDirection"></param>
        /// <returns></returns>
        private IEnumerable <SequenceSearchState <char> > DepthFirstSequenceSearch(SequenceSearchState <char> searchState,
                                                                                   Func <IMinimalDAGNode <char>, IEnumerable <IMinimalDAGNode <char> > > nextRelativeSelector,
                                                                                   HashSet <int> sequenceBoundaries,
                                                                                   int stepDirection, Pattern <char> pattern)
        {
            Stack <SequenceSearchState <char> > ToCheck = new Stack <SequenceSearchState <char> >();

            ToCheck.Push(searchState);
            //NB: recursive searches with yield return build a new iterator for every method call.
            //A recursive solution would therefore have performance impact (as well as risking stackoverflow in some very deep pattern).
            while (ToCheck.Count > 0)
            {
                var CurrentState = ToCheck.Pop();
                var Relatives    = nextRelativeSelector(CurrentState.CurrentNode);
                int NextIndex    = CurrentState.Index + stepDirection;

                if (IsOutOfBounds(NextIndex, pattern))
                {
                    if (IsBoundaryCollision(CurrentState, nextRelativeSelector, sequenceBoundaries, pattern))
                    {
                        yield return(CurrentState);
                    }
                }
                else
                {
                    bool IsEnd = false;
                    List <IMinimalDAGNode <char> > OtherRelatives = new List <IMinimalDAGNode <char> >();

                    foreach (var Relative in Relatives)
                    {
                        if (_dawg.IsDAGBoundary(Relative))
                        {
                            IsEnd = true;
                        }
                        else
                        {
                            OtherRelatives.Add(Relative);
                        }
                    }

                    if (IsEnd && IsIndexValidBoundary(CurrentState.Index, sequenceBoundaries))
                    {
                        yield return(CurrentState);
                    }

                    var NextStates = GetNextStates(CurrentState, OtherRelatives, NextIndex, stepDirection, pattern);
                    foreach (var nextState in NextStates)
                    {
                        ToCheck.Push(nextState);
                    }
                }
            }
        }
Example #3
0
 /// <summary>
 /// Searches the <see cref="IMinimalDAG{T}"/> from a starting point in a single direction, returning sequences
 /// that match the valid <see cref="Pattern{T}"/>
 /// </summary>
 /// <param name="searchState"></param>
 /// <param name="nextRelativeSelector"></param>
 /// <param name="sequenceBoundaries"></param>
 /// <param name="stepDirection"></param>
 /// <returns></returns>
 private IEnumerable <SequenceSearchState <char> > SequenceSearch(SequenceSearchState <char> searchState,
                                                                  Func <IMinimalDAGNode <char>, IEnumerable <IMinimalDAGNode <char> > > nextRelativeSelector,
                                                                  HashSet <int> sequenceBoundaries,
                                                                  int stepDirection,
                                                                  Pattern <char> pattern)
 {
     if (IsBoundaryCollision(searchState, nextRelativeSelector, sequenceBoundaries, pattern))
     {
         yield return(searchState);
     }
     else
     {
         foreach (var sequence in DepthFirstSequenceSearch(searchState, nextRelativeSelector, sequenceBoundaries, stepDirection, pattern))
         {
             yield return(sequence);
         }
     }
 }
Example #4
0
 /// <summary>
 /// Checks for a collision with an edge of the search space. In the event of a collision, returns all valid affixes terminating
 /// at that point, then breaks.
 /// </summary>
 /// <param name="searchState"></param>
 /// <param name="nextRelativeSelector"></param>
 /// <param name="sequenceBoundaries"></param>
 /// <returns></returns>
 private bool IsBoundaryCollision(SequenceSearchState <char> searchState,
                                  Func <IMinimalDAGNode <char>, IEnumerable <IMinimalDAGNode <char> > > nextRelativeSelector,
                                  HashSet <int> sequenceBoundaries,
                                  Pattern <char> pattern)
 {
     if (searchState.Index == 0 || searchState.Index == pattern.SearchSpace.Length - 1) //if we're at the edge of the searchspace
     {
         if (sequenceBoundaries.Contains(searchState.Index))                            //and the edge of the searchspace is a valid boundary (we're heading out of bounds)
         {
             foreach (var Relative in nextRelativeSelector(searchState.CurrentNode))
             {
                 if (_dawg.IsDAGBoundary(Relative))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
        internal SequenceSearchState(SequenceSearchState <T> other, IMinimalDAGNode <T> nextNode, int stepDirection, T UsedValue, bool wildCard)
        {
            this.WildCardIndices = new List <int>(other.WildCardIndices);
            Index       = other.Index + stepDirection;
            CurrentNode = nextNode;
            UsedValues  = new Dictionary <int, T>(other.UsedValues);

            //doesn't make sense:
            //if(!UsedValues.ContainsKey(Index))
            UsedValues.Add(Index, UsedValue);
            // PreviousNode = other.CurrentNode;
            if (wildCard)
            {
                WildCardCount = other.WildCardCount - 1;
                ValuePool     = new List <T>(other.ValuePool);
                WildCardIndices.Add(Index);
            }
            else
            {
                WildCardCount = other.WildCardCount;
                ValuePool     = other.ValuePool.ExceptFirst(UsedValue).ToList();
            }
        }
Example #6
0
        /// <summary>
        /// From the current state, find all the next states that are valid.
        /// </summary>
        /// <param name="currentState"></param>
        /// <param name="relatives"></param>
        /// <param name="nextLocation"></param>
        /// <param name="stepDirection"></param>
        /// <returns></returns>
        private List <SequenceSearchState <char> > GetNextStates(SequenceSearchState <char> currentState, List <IMinimalDAGNode <char> > relatives, int nextLocation,
                                                                 int stepDirection, Pattern <char> pattern)
        {
            List <SequenceSearchState <char> > NextStates = new List <SequenceSearchState <char> >();
            char concrete;

            if (pattern.TryGetConcreteValue(nextLocation, out concrete))
            {
                foreach (var relative in relatives.Where(x => concrete.Equals(x.Value)))
                {
                    NextStates.Add(new SequenceSearchState <char>(currentState, relative, stepDirection));
                }
            }
            else
            {
                var ValidValues = pattern.SearchSpace[nextLocation];
                var ValidNext   = relatives;
                if (ValidValues != null)// && !ValidValues.Contains(pattern.EmptyValue))
                {
                    ValidNext = relatives.Where(x => ValidValues.Contains(x.Value)).ToList();
                }

                foreach (var next in ValidNext)
                {
                    if (currentState.ValuePool.Contains(next.Value))
                    {
                        NextStates.Add(new SequenceSearchState <char>(currentState, next, stepDirection, next.Value, false));
                    }
                    if (currentState.WildCardCount > 0)
                    {
                        NextStates.Add(new SequenceSearchState <char>(currentState, next, stepDirection, next.Value, true));
                    }
                }
            }
            return(NextStates);
        }