public Dfa <TAlphabet> ToMinimumDfa(bool skipRemovalOfUnreachableStates = false) { // First eliminate any state(s) that cannot be reached from the start state var minimizedStates = skipRemovalOfUnreachableStates ? new Set <int>(_delta.Keys) : GetReachableStates(); // Use the table filling algorithm to find all the pairs of equivalent states TriangularPair <int>[] eqStatePairs = GetEquivalentPairs(); // Partition the set of states Q into blocks of mutually equivalent states Set <int>[] blocksWithEqStates = GetMergedEqSets(eqStatePairs); Set <int>[] blocksWithSingleState = minimizedStates.Difference(blocksWithEqStates).Select(state => new Set <int>(new [] { state })).ToArray(); List <Set <int> > blockStates = blocksWithEqStates.Concat(blocksWithSingleState).ToList(); Set <int> startBlockState = null; List <Set <int> > acceptBlocks = new List <Set <int> >(); // The transition relation of the DFA = (States, Transition) var blockTrans = new Dictionary <Set <int>, IDictionary <TAlphabet, Set <int> > >(); foreach (var blockState in blockStates) { if (blockState.Contains(StartState)) { startBlockState = blockState; } if (blockState.Any(s => _acceptStates.Contains(s))) { acceptBlocks.Add(blockState); } IDictionary <TAlphabet, Set <int> > transition = new Dictionary <TAlphabet, Set <int> >(); foreach (var label in GetLabels()) { //int toState = Trans[blockState.First()][label]; if (_delta[blockState.First()].TryGetValue(label, out var toState)) { Set <int> toBlockState = blockStates.First(block => block.Contains(toState)); transition.Add(label, toBlockState); } } blockTrans.Add(blockState, transition); } var renamer = new MinimizedDfaRenamer(blockStates, _renamer); var minDfaTrans = Rename(renamer, blockTrans); int minDfaStartState = renamer.ToDfaStateIndex(startBlockState); Set <int> minDfaAcceptStates = AcceptStates(blockStates, renamer, acceptBlocks); return(new Dfa <TAlphabet>(minDfaStartState, minDfaAcceptStates, minDfaTrans, renamer)); }
static IDictionary <int, Dictionary <TAlphabet, int> > Rename( MinimizedDfaRenamer renamer, IDictionary <Set <int>, IDictionary <TAlphabet, Set <int> > > trans) { var newDfaTrans = new SortedDictionary <int, Dictionary <TAlphabet, int> >(); // keys/states are sorted foreach (KeyValuePair <Set <int>, IDictionary <TAlphabet, Set <int> > > entry in trans) { Set <int> blockState = entry.Key; var newDfaTransRow = new Dictionary <TAlphabet, int>(); foreach (KeyValuePair <TAlphabet, Set <int> > tr in entry.Value) { newDfaTransRow.Add(tr.Key, renamer.ToDfaStateIndex(tr.Value)); } newDfaTrans.Add(renamer.ToDfaStateIndex(blockState), newDfaTransRow); } return(newDfaTrans); }
static Set <int> AcceptStates( IEnumerable <Set <int> > blockStates, MinimizedDfaRenamer renamer, List <Set <int> > acceptBlocks) { Set <int> acceptStates = new Set <int>(); foreach (Set <int> blockState in blockStates) { if (acceptBlocks.Any(finalState => blockState.Equals(finalState))) { acceptStates.Add(renamer.ToDfaStateIndex(blockState)); } } return(acceptStates); }