Exemplo n.º 1
0
        private void DiscardNotReachable(Partition blocks, List <Transition> transitionList, Func <Transition, int> getFrom, Func <Transition, int> getTo)
        {
            var adjacentTransitions = new AdjacentTransitions(StateCount, transitionList, getFrom);

            foreach (var state in blocks.Marked(0))
            {
                foreach (var transition in adjacentTransitions[state])
                {
                    blocks.Mark(getTo(transitionList[transition]));
                }
            }

            blocks.DiscardUnmarked();

            transitionList.RemoveAll(transition => blocks.SetOf(getFrom(transition)) == -1);
        }
Exemplo n.º 2
0
        public Tuple <IReadOnlyDictionary <State, State>, DFA <TData> > Minimize(Func <State, State, bool> areEquivalent, Func <TData, TData, TData> combine)
        {
            var transitionList = MakeTransitionsList();
            var blocks         = new Partition(StateCount);

            // Reachable from start
            foreach (var startState in StartStates)
            {
                blocks.Mark(startState.Index);
            }

            DiscardNotReachable(blocks, transitionList, t => t.From, t => t.To);

            // Reachable from final
            var finalStates = States.Where(IsFinal).ToList();

            foreach (var finalState in finalStates)
            {
                blocks.Mark(finalState.Index);
            }

            DiscardNotReachable(blocks, transitionList, t => t.To, t => t.From);

            // Split final states from non-final
            foreach (var finalState in finalStates)
            {
                blocks.Mark(finalState.Index);
            }

            blocks.SplitSets();

            // Split final states from other non-equivalent final states
            var possibleEquivalentStates = finalStates;

            while (possibleEquivalentStates.Any())
            {
                var state = possibleEquivalentStates.First();
                var equivalentStatesLookup = possibleEquivalentStates.Skip(1).ToLookup(s => areEquivalent(state, s));

                // Mark states
                blocks.Mark(state.Index);
                foreach (var finalState in equivalentStatesLookup[true])
                {
                    blocks.Mark(finalState.Index);
                }

                blocks.SplitSets();

                possibleEquivalentStates = equivalentStatesLookup[false].ToList();
            }

            // Cords partition to manage transitions
            var cords = new Partition(transitionList.Count);

            // Sort transitions by input
            cords.PartitionBy(transition => transitionList[transition].OnInput);

            //Split blocks and cords
            var adjacentTransitions = new AdjacentTransitions(StateCount, transitionList, t => t.To);
            var blockSet            = 1;

            for (var cordSet = 0; cordSet < cords.SetCount; cordSet++)
            {
                foreach (var transition in cords.Set(cordSet))
                {
                    blocks.Mark(transitionList[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 <TData>(InputValueCount, blocks.SetCount);

            // Create states
            for (var set = 0; set < blocks.SetCount; set++)
            {
                var data  = blocks.Set(set).Select(s => GetData(new State(s))).Aggregate(combine);
                var state = minDFA.AddState(data);
                // Sets are either all final or non-final states
                if (IsFinal(new State(blocks.SomeElementOf(set))))
                {
                    minDFA.SetFinal(state);
                }
            }

            // Create Start State Map
            var startStateMap = (IReadOnlyDictionary <State, State>)StartStates.ToDictionary(s => s, s => new State(blocks.SetOf(s.Index)));

            // Mark Start States
            foreach (var startState in startStateMap.Values)
            {
                minDFA.SetStart(startState);
            }

            // Create transitions
            for (var set = 0; set < cords.SetCount; set++)
            {
                var transition = transitionList[cords.SomeElementOf(set)];
                var from       = new State(blocks.SetOf(transition.From));
                var to         = new State(blocks.SetOf(transition.To));
                minDFA.SetTransition(from, new Input(transition.OnInput), to);
            }

            return(Tuple.Create(startStateMap, minDFA));
        }