예제 #1
0
        private static bool isRegramStateValid(NDFA <T, S> ndfa, T state)
        {
            Dictionary <S, HashSet <T> > otherTransitions = ndfa.GetStates(state);

            foreach (HashSet <T> otherStates in otherTransitions.Values)
            {
                foreach (T otherState in otherStates)
                {
                    if (!otherState.Equals(state))
                    {
                        return(true);
                    }
                }
            }

            if (ndfa.EndStates.Contains(state) && ndfa.GetStates(state).Count != 0)
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        //NDFA --> Regram
        public static Regram <MultiState <T>, S> ConvertToRegram(NDFA <T, S> ndfa, IMultiStateView <T> view)
        {
            Regram <MultiState <T>, S> regram     = new Regram <MultiState <T>, S>(ndfa.Alphabet);
            MultiState <T>             startState = new MultiState <T>(view);
            HashSet <MultiState <T> >  todo       = new HashSet <MultiState <T> >();
            HashSet <MultiState <T> >  done       = new HashSet <MultiState <T> >();

            foreach (T subStartState in ndfa.StartStates)
            {
                startState.Add(subStartState);

                HashSet <T> otherStates = getAllEpsilonStatesFromState(ndfa, subStartState, ndfa.Epsilon);
                foreach (T otherState in otherStates)
                {
                    startState.Add(otherState);
                }
            }

            todo.Add(startState);

            //While there are items that needs to be progressed
            while (todo.Count > 0)
            {
                MultiState <T> from = todo.First <MultiState <T> >();

                foreach (T part in from)
                {
                    if (isRegramStateValid(ndfa, part))
                    {
                        regram.AddState(from);
                    }

                    Dictionary <S, HashSet <T> > partStates = ndfa.GetStates(part);

                    foreach (S symbol in partStates.Keys)
                    {
                        if (symbol.Equals(ndfa.Epsilon))
                        {
                            continue;
                        }

                        HashSet <T> partToStates = partStates[symbol];
                        foreach (T partToState in partToStates)
                        {
                            MultiState <T> newState = new MultiState <T>(view);
                            newState.Add(partToState);
                            if (isRegramStateValid(ndfa, partToState) || ndfa.EndStates.Contains(partToState))
                            {
                                regram.AddTransition(from, newState, symbol);
                            }

                            if (!done.Contains(newState))
                            {
                                todo.Add(newState);
                            }

                            foreach (T epsilonState in getAllEpsilonStatesFromState(ndfa, partToState, ndfa.Epsilon))
                            {
                                MultiState <T> newEpsilonState = new MultiState <T>(view);
                                newEpsilonState.Add(epsilonState);
                                if (isRegramStateValid(ndfa, epsilonState) || ndfa.EndStates.Contains(epsilonState))
                                {
                                    regram.AddTransition(from, newEpsilonState, symbol);
                                }

                                if (!done.Contains(newEpsilonState))
                                {
                                    todo.Add(newEpsilonState);
                                }
                            }
                        }
                    }
                }

                todo.Remove(from);
                done.Add(from);
            }

            foreach (MultiState <T> state in regram.GetStates().Where((t) => t.Any((a) => ndfa.EndStates.Contains(a))))
            {
                regram.EndStates.Add(state);
            }
            regram.StartState = startState;
            return(regram);
        }
예제 #3
0
        private DFA <T, S> ToDFA(NDFA <T, S> ndfa)
        {
            this.Alphabet = ndfa.Alphabet;
            this.states   = new Dictionary <T, Dictionary <S, T> >();
            this.EndStates.Clear();

            Stack <SortedSet <T> > combinedStates    = new Stack <SortedSet <T> >();
            Stack <SortedSet <T> > unprocessedStates = new Stack <SortedSet <T> >();

            // setting new combined start state and push it to unprocessed stack
            unprocessedStates.Push(new SortedSet <T>(ndfa.StartStates));
            this.StartState = concatStates(new SortedSet <T>(ndfa.StartStates));

            // combining and processing new states
            while (unprocessedStates.Count > 0)
            {
                Dictionary <S, SortedSet <T> > newStates = new Dictionary <S, SortedSet <T> >();
                SortedSet <T> unProcessedStateSet        = unprocessedStates.Pop();

                foreach (T unprocessedState in unProcessedStateSet)
                {
                    foreach (S symbol in ndfa.GetStates(unprocessedState).Keys)
                    {
                        foreach (T toState in ndfa.GetStates(unprocessedState)[symbol])
                        {
                            if (!newStates.ContainsKey(symbol))
                            {
                                newStates.Add(symbol, new SortedSet <T>());
                            }
                            newStates[symbol].Add(toState);
                        }
                    }
                }

                combinedStates.Push(unProcessedStateSet);

                foreach (S symbol in newStates.Keys)
                {
                    AddTransition(concatStates(unProcessedStateSet), concatStates(newStates[symbol]), symbol);

                    bool isSetAlreadyProcessed = false;

                    // set new combined end state
                    foreach (T ndfaEndState in ndfa.EndStates)
                    {
                        if (newStates[symbol].Contains(ndfaEndState))
                        {
                            this.EndStates.Add(concatStates(newStates[symbol]));
                        }
                    }
                    // check if newfound combined state was previously found and processed
                    foreach (SortedSet <T> combinedState in combinedStates)
                    {
                        if (combinedState.SetEquals(newStates[symbol]))
                        {
                            isSetAlreadyProcessed = true;
                            break;
                        }
                    }
                    if (!isSetAlreadyProcessed)
                    {
                        foreach (SortedSet <T> unProcessedState in unprocessedStates)
                        {
                            if (unProcessedState.SetEquals(newStates[symbol]))
                            {
                                isSetAlreadyProcessed = true;
                                break;
                            }
                        }
                        // add newfound combined state to unprocessed stack
                        if (!isSetAlreadyProcessed)
                        {
                            unprocessedStates.Push(newStates[symbol]);
                        }
                    }
                }
            }

            // adding trap for missing transitions
            bool isTrapPlaced = false;

            foreach (T transition in states.Keys)
            {
                foreach (S symbol in this.Alphabet)
                {
                    if (!states[transition].ContainsKey(symbol))
                    {
                        AddTransition(transition, Trap, symbol);
                        isTrapPlaced = true;
                    }
                }
            }
            if (isTrapPlaced)
            {
                foreach (S symbol in this.Alphabet)
                {
                    AddTransition(Trap, Trap, symbol);
                }
            }
            return(this);
        }