Exemple #1
0
 public MotifRunner(Motif <TElement> motif, IReadOnlyList <TElement> sequence)
 {
     Length          = sequence.Count;
     LastCodeIndex   = motif.Code.Length - 1;
     RemainingLength = Length;
     GetMotif        = () => motif;
     GetSequence     = () => sequence;
 }
Exemple #2
0
        private bool Loop(Motif <TElement> motif, int opIndex, int startIndex, int remainingLength)
        {
            var func = motif.Delegates[opIndex];
            int initialRemainingLength = remainingLength;
            int opMatches     = 0;
            var op            = motif.Code[opIndex];
            int minFinalIndex = startIndex + op.Lower;

            bool     isMatch = true;
            TElement current = default(TElement);

            for (int i = startIndex; isMatch && i <= minFinalIndex; ++i)
            {
                current = Sequence[i];
                if (!func(current))
                {
                    isMatch = false;
                }
            }



            if (isMatch)
            {
                // if a range instead of a set count
                if (op.Upper != -1)
                {
                    // doesn't bother running ranges that leave insufficient length for remaining code
                    // remainingLength includes the lower bound of this loop op
                    int  maxFinalIndex = Math.Min(startIndex + op.Upper, startIndex + remainingLength);
                    int  index;
                    bool nextIsLoop = motif.Code[opIndex + 1].Code.HasFlag(MotifCode.Loop);
                    isMatch = false;

                    // potential range includes the previously-confirmed match at the end of the lower bound

                    // sets the index to the maximum of the range
                    for (index = minFinalIndex; func(current) && index <= maxFinalIndex; ++index)
                    {
                    }

                    if (opIndex == LastCodeIndex)
                    {
                        EndMatch(index);
                        return(true);
                    }

                    for (; index >= minFinalIndex; --index) // greedy by default
                    {
                        // forbids matches from being subsequences of each other by default
                        if (nextIsLoop)
                        {
                            if (
                                Loop(
                                    motif,
                                    opIndex + 1,
                                    index + 1,
                                    remainingLength - (index - startIndex)
                                    )
                                )
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            if (
                                Go(
                                    motif,
                                    opIndex + 1,
                                    index + 1,
                                    remainingLength - (index - startIndex)
                                    )
                                )
                            {
                                return(true);
                            }
                        }
                    }
                }
                else if (opIndex == LastCodeIndex)
                {
                    EndMatch(minFinalIndex);
                    return(true);
                }
            }

            return(isMatch);
        }
Exemple #3
0
 private bool Go(Motif <TElement> motif, int opIndex, int startIndex, int remainingLength)
 {
     return(false);
 }