/// <summary> /// Reduces this automaton. /// An automaton is "reduced" by combining overlapping and adjacent edge intervals with same /// destination. /// </summary> public void Reduce() { if (this.IsSingleton) { return; } HashSet <State> states = this.GetStates(); Automaton.SetStateNumbers(states); foreach (State s in states) { IList <Transition> st = s.GetSortedTransitions(true); s.ResetTransitions(); State p = null; int min = -1, max = -1; foreach (Transition t in st) { if (p == t.To) { if (t.Min <= max + 1) { if (t.Max > max) { max = t.Max; } } else { if (p != null) { s.Transitions.Add(new Transition((char)min, (char)max, p)); } min = t.Min; max = t.Max; } } else { if (p != null) { s.Transitions.Add(new Transition((char)min, (char)max, p)); } p = t.To; min = t.Min; max = t.Max; } } if (p != null) { s.Transitions.Add(new Transition((char)min, (char)max, p)); } } this.ClearHashCode(); }
public static Transition[][] GetSortedTransitions(HashSet <State> states) { Automaton.SetStateNumbers(states); var transitions = new Transition[states.Count][]; foreach (State s in states) { transitions[s.Number] = s.GetSortedTransitions(false).ToArray(); } return(transitions); }
/// <summary> /// Returns true if the given string is accepted by the automaton. /// </summary> /// <param name="a">The automaton.</param> /// <param name="s">The string.</param> /// <returns></returns> /// <remarks> /// Complexity: linear in the length of the string. /// For full performance, use the RunAutomaton class. /// </remarks> public static bool Run(Automaton a, string s) { if (a.IsSingleton) { return(s.Equals(a.Singleton, System.StringComparison.CurrentCulture)); } if (a.IsDeterministic) { State p = a.Initial; foreach (char t in s) { State q = p.Step(t); if (q == null) { return(false); } p = q; } return(p.Accept); } HashSet <State> states = a.GetStates(); Automaton.SetStateNumbers(states); var pp = new LinkedList <State>(); var ppOther = new LinkedList <State>(); var bb = new BitArray(states.Count); var bbOther = new BitArray(states.Count); pp.AddLast(a.Initial); var dest = new List <State>(); bool accept = a.Initial.Accept; foreach (char c in s) { accept = false; ppOther.Clear(); bbOther.SetAll(false); foreach (State p in pp) { dest.Clear(); p.Step(c, dest); foreach (State q in dest) { if (q.Accept) { accept = true; } if (!bbOther.Get(q.Number)) { bbOther.Set(q.Number, true); ppOther.AddLast(q); } } } LinkedList <State> tp = pp; pp = ppOther; ppOther = tp; BitArray tb = bb; bb = bbOther; bbOther = tb; } return(accept); }