/// <summary> /// Minimizes (and determinizes if not already deterministic) the given automaton. /// </summary> /// <param name="a">The automaton.</param> public static void Minimize(Automaton a) { if (!a.IsSingleton) { switch (Automaton.Minimization) { case Automaton.MinimizeHuffman: MinimizationOperations.MinimizeHuffman(a); break; case Automaton.MinimizeBrzozowski: MinimizationOperations.MinimizeBrzozowski(a); break; default: MinimizationOperations.MinimizeHopcroft(a); break; } } a.RecomputeHashCode(); }
/// <summary> /// The minimize. /// </summary> public void Minimize() { MinimizationOperations.Minimize(this); }
/// <summary> /// Minimizes the given automaton using Huffman's algorithm. /// </summary> /// <param name="a">The automaton.</param> internal static void MinimizeHuffman(Automaton a) { a.Determinize(); a.Totalize(); HashSet <State> ss = a.GetStates(); var transitions = new Transition[ss.Count][]; State[] states = ss.ToArray(); var mark = new List <List <bool> >(); var triggers = new List <List <HashSet <IntPair> > >(); foreach (State t in states) { var v = new List <HashSet <IntPair> >(); Initialize(ref v, states.Length); triggers.Add(v); } // Initialize marks based on acceptance status and find transition arrays. for (int n1 = 0; n1 < states.Length; n1++) { states[n1].Number = n1; transitions[n1] = states[n1].GetSortedTransitions(false).ToArray(); for (int n2 = n1 + 1; n2 < states.Length; n2++) { if (states[n1].Accept != states[n2].Accept) { mark[n1][n2] = true; } } } // For all pairs, see if states agree. for (int n1 = 0; n1 < states.Length; n1++) { for (int n2 = n1 + 1; n2 < states.Length; n2++) { if (!mark[n1][n2]) { if (MinimizationOperations.StatesAgree(transitions, mark, n1, n2)) { MinimizationOperations.AddTriggers(transitions, triggers, n1, n2); } else { MinimizationOperations.MarkPair(mark, triggers, n1, n2); } } } } // Assign equivalence class numbers to states. int numclasses = 0; foreach (State t in states) { t.Number = -1; } for (int n1 = 0; n1 < states.Length; n1++) { if (states[n1].Number == -1) { states[n1].Number = numclasses; for (int n2 = n1 + 1; n2 < states.Length; n2++) { if (!mark[n1][n2]) { states[n2].Number = numclasses; } } numclasses++; } } // Make a new state for each equivalence class. var newstates = new State[numclasses]; for (int n = 0; n < numclasses; n++) { newstates[n] = new State(); } // Select a class representative for each class and find the new initial state. for (int n = 0; n < states.Length; n++) { newstates[states[n].Number].Number = n; if (states[n] == a.Initial) { a.Initial = newstates[states[n].Number]; } } // Build transitions and set acceptance. for (int n = 0; n < numclasses; n++) { State s = newstates[n]; s.Accept = states[s.Number].Accept; foreach (Transition t in states[s.Number].Transitions) { s.Transitions.Add(new Transition(t.Min, t.Max, newstates[t.To.Number])); } } a.RemoveDeadTransitions(); }
/// <summary> /// The minimize. /// </summary> internal void Minimize() { MinimizationOperations.Minimize(this); }