public bool accept(U[] input) { if (!isValid()) { throw new AutomatonInvalidException(); } var currStates = StartStates; foreach (U u in input) { if (!Alphabet.Contains(u)) { throw new System.ArgumentException($"{u} is not part of alphabet"); } HashSet <T> newStates = new HashSet <T>(); foreach (T state in currStates) { if (!Transitions.ContainsKey(state)) { continue; } if (Transitions[state].ContainsKey(Epsilon)) { newStates.UnionWith(Transitions[state][Epsilon]); } if (Transitions[state].ContainsKey(u)) { newStates.UnionWith(Transitions[state][u]); } } currStates = newStates; } return(EndStates.Intersect(currStates).Count() > 0); }
public DFA <IEnumerable <T>, U> toDFA() { DFA <IEnumerable <T>, U> result = new DFA <IEnumerable <T>, U>(); HashSet <StateSet <T> > curr = new HashSet <StateSet <T> >(); // Add start state StateSet <T> start = new StateSet <T>(); foreach (T startState in StartStates) { start.UnionWith(epsilonClosure(startState)); } curr.Add(start); result.addStartState(start); // Add trap state StateSet <T> trap = new StateSet <T>(); foreach (U terminal in Alphabet) { result.addTransition(terminal, trap, trap); } // Add transitions bool done = false; while (!done) { bool addedNew = false; HashSet <StateSet <T> > next = new HashSet <StateSet <T> >(); // For each current state in set of current states. foreach (StateSet <T> currState in curr) { // For each terminal in the alphabet. foreach (U terminal in Alphabet) { // nextState will become the actual dfa to state. StateSet <T> nextState = new StateSet <T>(); // For each ndfa state of which the dfa state is made. foreach (T subState in currState) { // Get the epsilon closure of the sub state. HashSet <T> preClosure = epsilonClosure(subState); // For each state in the epsilon closure. foreach (T preClosureState in preClosure) { // Check if exists. if (!Transitions.ContainsKey(preClosureState) || !Transitions[preClosureState].ContainsKey(terminal)) { continue; } // Get all the to states for this terminal. HashSet <T> follow = Transitions[preClosureState][terminal]; // Accumulate the epsilon closure of each followed state. foreach (T followedState in follow) { HashSet <T> postClosure = epsilonClosure(followedState); nextState.UnionWith(postClosure); } } } if (nextState.Count() > 0) { next.Add(nextState); // Add transition. if (result.addTransition(terminal, currState, nextState)) { addedNew = true; } // Add end state if (EndStates.Intersect(nextState).Count() > 0) { result.addEndState(nextState); } } else { /* * . . . . . . . . . . . . . . . . ____________ * . . . . . . . . . . . . . . . . / It’s a trap! \ * . . . . . . . . . . . . . . . . \ _____________/ * __...------------._ * ,-' `-. * ,-' `. * ,' ,-`. * ; `-' `. * ; .-. \ * ; .-. `-' \ * ; `-' \ * ; `. * ; : * ; | * ; ; * ; ___ ; * ; ,-;-','.`.__ | * _..; ,-' ;`,'.`,'.--`. | * ///; ,-' `. ,-' ;` ;`,','_.--=: / |'': ,' : ;` ;,;,,-'_.-._`. ,' * ' : ;_.-. `. :' ;;;'.ee. \| / \.' _..-'/8o. `. : :! ' ':8888) || / ||`-'' \\88o\ : : :! : :`""' ;;/ || \"88o\; `. \ `. `. ;,' ||/) ___ `."'/(--.._ `. `.`. `-..-' ;--. \(.="""""==.. `'-' `.| `-`-..__.-' `. `. | `"==.__ ) ) ; | || `"=== ' .' .' | /\,,|||| | | \ .' .' | |||'|' |'|' \| .' _.' \ | |\' | | || || .' .' \ | ' | \ ' |' . ``-- `| || .' .' \ | ' | ' | . ``-.._ | ; .' .' `. | _.--,;`. . -- ...._,' .' .' `.__ | ,' ,'; `. . --..__..--'.' .' __/_\ | ,' ; ; | . --..__.._.' .' ,' `. | / ; : ; . -.. _.' _.' / ` | / : `-._ | . _.--' _.' | | / `. `--....--'' _.' | | `._ _..-' | | `-..____...-'' | | | */ result.addTransition(terminal, currState, trap); } } } curr = next; done = !addedNew; } return(result); }