Exemple #1
0
        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));
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }