public void Add(State current, char character, State next)
        {
            if (wrappedUp)
                throw new InvalidOperationException("Table is wrapped up.");

            List<State> nextStates;
            var key = new Tuple<State, char>(current, character);

            bool transitionExists = transitions.TryGetValue(key, out nextStates);
            if (!transitionExists)
            {
                nextStates = new List<State>();
                transitions.Add(key, nextStates);
            }

            bool duplicate = nextStates.Contains(next);
            if (duplicate)
                throw new InvalidOperationException("Transition is duplicated.");

            nextStates.Add(next);
        }
 public IEnumerable<State> GetInitialEpsilonClosure(State initial)
 {
     var initialStateArray = new[] { initial };
     return EpsilonClosure(initialStateArray);
 }
        private IEnumerable<State> GetNextStatesOfSingleState(State current, char character)
        {
            List<State> nextStates;
            var key = new Tuple<State, char>(current, character);

            IEnumerable<State> output;
            bool transitionIsDefined = transitions.TryGetValue(key, out nextStates);
            if (transitionIsDefined)
                output = nextStates;
            else
                output = Enumerable.Empty<State>();

            foreach (State state in output)
                yield return state;
        }
 public IEnumerable<State> GetNextStates(State state, char character)
 {
     var nextStates = GetNextStatesOfSingleState(state, character);
     var closure = EpsilonClosure(nextStates);
     foreach (State nextState in closure)
             yield return nextState;
 }