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); }
//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); }
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); }