Пример #1
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> Or(
            Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> > pattern1,
            Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> > pattern2,
            params Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> >[] patterns)
        {
            var allPatterns = new Afa <TPayload, TRegister, TAccumulator> [patterns.Length + 2];

            allPatterns[0] = pattern1(new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;
            allPatterns[1] = pattern2(new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;

            for (int i = 0; i < patterns.Length; i++)
            {
                allPatterns[i + 2] = patterns[i](new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;
            }

            var result = new Afa <TPayload, TRegister, TAccumulator>(this.defaultRegister, this.defaultAccumulator);

            int oldMax;

            for (int i = 0; i < allPatterns.Length; i++)
            {
                var nextPattern = allPatterns[i];

                oldMax = result.MaxState + 1;

                result.AddArc(0, nextPattern.StartState + oldMax, new EpsilonArc <TPayload, TRegister>());

                // If the next pattern start state is also a final state, add it directly, as it will not necessarily have a transition entry
                if (nextPattern.finalStates.Contains(nextPattern.StartState))
                {
                    if (!result.finalStates.Contains(nextPattern.StartState + oldMax))
                    {
                        result.finalStates.Add(nextPattern.StartState + oldMax);
                    }
                }

                foreach (var kvp1 in nextPattern.transitionInfo)
                {
                    foreach (var kvp2 in kvp1.Value)
                    {
                        int from = kvp1.Key + oldMax;
                        int to   = kvp2.Key + oldMax;

                        result.AddArc(from, to, kvp2.Value);

                        if (nextPattern.finalStates.Contains(kvp2.Key))
                        {
                            if (!result.finalStates.Contains(to))
                            {
                                result.finalStates.Add(to);
                            }
                        }
                    }
                }
            }
            result.StartState = 0;

            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, result)));
        }
Пример #2
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> Or(
            Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> > pattern1,
            Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> > pattern2,
            params Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> >[] patterns)
        {
            var allPatterns = new Afa <TPayload, TRegister, TAccumulator> [patterns.Length + 2];

            allPatterns[0] = pattern1(new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;
            allPatterns[1] = pattern2(new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;

            for (int i = 0; i < patterns.Length; i++)
            {
                allPatterns[i + 2] = patterns[i](new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>()).AFA;
            }

            var result = new Afa <TPayload, TRegister, TAccumulator>();

            int oldMax;

            for (int i = 0; i < allPatterns.Length; i++)
            {
                var nextPattern = allPatterns[i];

                oldMax = result.MaxState + 1;

                result.AddArc(0, nextPattern.StartState + oldMax, new EpsilonArc <TPayload, TRegister>());

                foreach (var kvp1 in nextPattern.transitionInfo)
                {
                    foreach (var kvp2 in kvp1.Value)
                    {
                        int from = kvp1.Key;
                        int to   = kvp2.Key;

                        from = from + oldMax;
                        to   = to + oldMax;

                        result.AddArc(from, to, kvp2.Value);

                        if (nextPattern.finalStates.Contains(kvp2.Key))
                        {
                            if (!result.finalStates.Contains(to))
                            {
                                result.finalStates.Add(to);
                            }
                        }
                    }
                }
            }
            result.StartState = 0;


            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, result)));
        }
Пример #3
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> KleeneStar(
            Func <IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator>, IPattern <TKey, TPayload, TRegister, TAccumulator> > pattern)
        {
            var newConcreteRegex = pattern(new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>());

            var result = new Afa <TPayload, TRegister, TAccumulator>();

            var pattern_ = (Afa <TPayload, TRegister, TAccumulator>)newConcreteRegex.AFA;

            // Every final state maps back to the start state
            foreach (var kvp1 in pattern_.transitionInfo)
            {
                foreach (var kvp2 in kvp1.Value)
                {
                    var to = kvp2.Key;
                    if (pattern_.finalStates.Contains(to))
                    {
                        to = pattern_.StartState;
                    }
                    result.AddArc(kvp1.Key, to, kvp2.Value);
                }
            }

            // Start state becomes the single final state
            result.finalStates.Add(pattern_.StartState);
            result.StartState = pattern_.StartState;

            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, result)));
        }
Пример #4
0
        /// <summary>
        /// Creates a new pattern resulting from the disjunction of other patterns
        /// </summary>
        /// <typeparam name="TInput">The type of stream input data</typeparam>
        /// <typeparam name="TRegister">The type of the register to be mutated as transitions occur</typeparam>
        /// <typeparam name="TAccumulator">The type of the accumulator in the underlying automaton</typeparam>
        /// <param name="pattern1">The first pattern in the disjunction</param>
        /// <param name="pattern2">The second pattern in the disjunction</param>
        /// <param name="patterns">Any remaining patterns to be disjunction, in order</param>
        /// <returns>A pattern whose first transition is the one just created</returns>
        public static Afa <TInput, TRegister, TAccumulator> Or <TInput, TRegister, TAccumulator>(Afa <TInput, TRegister, TAccumulator> pattern1, Afa <TInput, TRegister, TAccumulator> pattern2, params Afa <TInput, TRegister, TAccumulator>[] patterns)
        {
            var allPatterns = new Afa <TInput, TRegister, TAccumulator> [patterns.Length + 2];

            allPatterns[0] = pattern1;
            allPatterns[1] = pattern2;
            patterns.CopyTo(allPatterns, 2);

            var result = new Afa <TInput, TRegister, TAccumulator>();

            int oldMax;

            for (int i = 0; i < allPatterns.Length; i++)
            {
                var nextPattern = allPatterns[i];

                oldMax = result.MaxState + 1;

                result.AddArc(0, nextPattern.StartState + oldMax, new EpsilonArc <TInput, TRegister>());

                foreach (var kvp1 in nextPattern.transitionInfo)
                {
                    foreach (var kvp2 in kvp1.Value)
                    {
                        int from = kvp1.Key;
                        int to   = kvp2.Key;

                        from = from + oldMax;
                        to   = to + oldMax;

                        result.AddArc(from, to, kvp2.Value);

                        if (nextPattern.finalStates.Contains(kvp2.Key))
                        {
                            if (!result.finalStates.Contains(to))
                            {
                                result.finalStates.Add(to);
                            }
                        }
                    }
                }
            }
            result.StartState = 0;

            return(result);
        }
Пример #5
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> Epsilon()
        {
            var afa = new Afa <TPayload, TRegister, TAccumulator>();

            afa.AddArc(0, 1, new EpsilonArc <TPayload, TRegister> {
            });
            afa.Seal();

            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, afa)));
        }
Пример #6
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> SingleElement(Expression <Func <long, TPayload, TRegister, bool> > condition = null, Expression <Func <long, TPayload, TRegister, TRegister> > aggregator = null)
        {
            var afa = new Afa <TPayload, TRegister, TAccumulator>();

            afa.AddArc(0, 1, new SingleElementArc <TPayload, TRegister> {
                Fence = condition, Transfer = aggregator
            });
            afa.Seal();

            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, afa)));
        }
Пример #7
0
        public IPattern <TKey, TPayload, TRegister, TAccumulator> MultiElement(Expression <Func <long, TRegister, TAccumulator> > initialize, Expression <Func <long, TPayload, TRegister, TAccumulator, TAccumulator> > accumulate, Expression <Func <long, TPayload, TAccumulator, bool> > skipToEnd, Expression <Func <long, TAccumulator, TRegister, bool> > fence, Expression <Func <long, TAccumulator, TRegister, TRegister> > transfer, Expression <Action <TAccumulator> > dispose)
        {
            var afa = new Afa <TPayload, TRegister, TAccumulator>();

            afa.AddArc(0, 1, new MultiElementArc <TPayload, TRegister, TAccumulator>
            {
                Initialize = initialize,
                Accumulate = accumulate,
                SkipToEnd  = skipToEnd,
                Fence      = fence,
                Transfer   = transfer,
                Dispose    = dispose
            });
            afa.Seal();

            return(Concat(x => new PatternMatcher <TKey, TPayload, TRegister, TAccumulator>(this.source, afa)));
        }
Пример #8
0
        /// <summary>
        /// Creates a new pattern resulting from zero to many iterations of the given pattern
        /// </summary>
        /// <typeparam name="TInput">The type of stream input data</typeparam>
        /// <typeparam name="TRegister">The type of the register to be mutated as transitions occur</typeparam>
        /// <typeparam name="TAccumulator">The type of the accumulator in the underlying automaton</typeparam>
        /// <param name="pattern">The pattern to iterate</param>
        /// <returns>A pattern whose first transition is the one just created</returns>
        public static Afa <TInput, TRegister, TAccumulator> KleeneStar <TInput, TRegister, TAccumulator>(Afa <TInput, TRegister, TAccumulator> pattern)
        {
            var result = new Afa <TInput, TRegister, TAccumulator>();

            // Every final state maps back to the start state
            foreach (var kvp1 in pattern.transitionInfo)
            {
                foreach (var kvp2 in kvp1.Value)
                {
                    var to = kvp2.Key;
                    if (pattern.finalStates.Contains(to))
                    {
                        to = pattern.StartState;
                    }
                    result.AddArc(kvp1.Key, to, kvp2.Value);
                }
            }

            // Start state becomes the single final state
            result.finalStates.Add(pattern.StartState);
            result.StartState = pattern.StartState;

            return(result);
        }