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))); }
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))); }
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))); }
/// <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); }
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))); }
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))); }
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))); }
/// <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); }