private void DiscardNotReachable(Partition blocks, List <Transition> transitions, Func <Transition, int> getFrom, Func <Transition, int> getTo) { var adjacentTransitions = new AdjacentTransitions(StateCount, transitions, getFrom); foreach (var state in blocks.MarkedInSet(0)) { foreach (var transition in adjacentTransitions[state]) { blocks.Mark(getTo(transitions[transition])); } } blocks.DiscardUnmarked(); transitions.RemoveAll(transition => blocks.SetOf(getFrom(transition)) == -1); }
public DFA Minimize() { // We will be modifying this list of transitions and we don't want to mess up our own var transitions = new List <Transition>(this.transitions); var blocks = new Partition(StateCount); // Reachable from start blocks.Mark(StartState); DiscardNotReachable(blocks, transitions, t => t.From, t => t.To); // Reachable from final foreach (var finalState in finalStates) { blocks.Mark(finalState); } DiscardNotReachable(blocks, transitions, t => t.To, t => t.From); // Split final states from non-final foreach (var finalState in finalStates) { blocks.Mark(finalState); } blocks.SplitSets(); // Cords partition to manage transitions var cords = new Partition(transitions.Count); // Split transitions by input cords.PartitionBy(transition => transitions[transition].OnInput); //Split blocks and cords var adjacentTransitions = new AdjacentTransitions(StateCount, transitions, t => t.To); var blockSet = 1; for (var cordSet = 0; cordSet < cords.SetCount; cordSet++) { foreach (var transition in cords.Set(cordSet)) { blocks.Mark(transitions[transition].From); } blocks.SplitSets(); for (; blockSet < blocks.SetCount; blockSet++) { foreach (var state in blocks.Set(blockSet)) { foreach (var transition in adjacentTransitions[state]) { cords.Mark(transition); } } cords.SplitSets(); } } // Generate minimized DFA var minDFA = new DFA(blocks.SetCount, blocks.SetOf(StartState)); // Set Final States foreach (var finalState in finalStates) { var set = blocks.SetOf(finalState); if (set != -1) // not all final states may have been reachable { minDFA.AddFinalState(set); } } // Create transitions for (var set = 0; set < cords.SetCount; set++) { var transition = transitions[cords.SomeElementOf(set)]; var @from = blocks.SetOf(transition.From); var to = blocks.SetOf(transition.To); minDFA.AddTransition(@from, transition.OnInput, to); } return(minDFA); }