private IntermediateDfaStateModel FindEpsilonTransitions(StateModel originatingState, StateModel currentState, StateModel transitionEndState, char letter, AutomatonModel ndfa, AutomatonModel dfa) { IntermediateDfaStateModel historyItem = new IntermediateDfaStateModel(); foreach (var transition in ndfa.Transitions) { if (transition.BeginState == transitionEndState && transition.Value == letter.ToString()) { //create the new history item and return historyItem.States.Add(transition.EndState); historyItem.Name += transition.EndState.Name; historyItem.Value = transition.Value; historyItem.OriginatingState = originatingState; } else if (transition.BeginState == transitionEndState && transition.Value == _empty) { //continue recursion } } return(historyItem); }
private StateModel AddHistoryToDfa(AutomatonModel dfa, IntermediateDfaStateModel newHistoryItem) { var newState = new StateModel() { Name = newHistoryItem.Name, }; if (dfa.States.All(s => s.Name != newState.Name)) { dfa.States.Add(newState); } else { newState = dfa.States.Find(s => s.Name == newState.Name); } dfa.Transitions.Add(new TransitionModel { BeginState = newHistoryItem.OriginatingState, EndState = newState, Value = newHistoryItem.Value }); return(newState); }
private void TraverseNfa(Queue <IntermediateDfaStateModel> queue, List <StateModel> stateHistory, AutomatonModel ndfa, AutomatonModel dfa) { IntermediateDfaStateModel currentStates = new IntermediateDfaStateModel(); if (queue.Any()) { currentStates = queue.Dequeue(); } else { return; } var originatingState = dfa.States.Find(s => s.Name == currentStates.Name); foreach (var letter in ndfa.Alphabet) { IntermediateDfaStateModel newHistoryItem = new IntermediateDfaStateModel(); foreach (var currentState in currentStates.States) { foreach (var state in ndfa.States) { foreach (var transition in ndfa.Transitions) { if (currentState == state && transition.Value == letter.ToString() && transition.BeginState == currentState) { //create history item //add each state to states list and add statename like += to history name newHistoryItem.States.Add(transition.EndState); newHistoryItem.Name += transition.EndState.Name; newHistoryItem.Value = transition.Value; newHistoryItem.OriginatingState = originatingState; } else if (currentState == state && transition.Value == _empty && transition.BeginState == currentState) { IntermediateDfaStateModel epsilonHistoryItem = FindEpsilonTransitions(originatingState, currentState, transition.EndState, letter, ndfa, dfa); if (epsilonHistoryItem.Name == null) { continue; } newHistoryItem.States.AddRange(epsilonHistoryItem.States); newHistoryItem.Name += epsilonHistoryItem.Name; newHistoryItem.Value = epsilonHistoryItem.Value; newHistoryItem.OriginatingState = originatingState; } } } //build new state and transition of the dfa //also add the new state to the stack } if (newHistoryItem.Name == null) { continue; } var newState = AddHistoryToDfa(dfa, newHistoryItem); if (stateHistory.All(s => s.Name != newState.Name)) { queue.Enqueue(newHistoryItem); stateHistory.Add(newState); } } //from the history add to stack //and also create new state with transition if (queue.Any()) { TraverseNfa(queue, stateHistory, ndfa, dfa); } else { //check also if a final state exists //Im not entirely sure about the theory for dfa's //but i made only one final state possible. //either the last processed one or //if the first processed state was initial already if (dfa.States.Any(s => s.IsFinal)) { return; } var lastState = dfa.States.LastOrDefault(); if (lastState != null) { lastState.IsFinal = true; } } }