public StateMachine(Label initialState, IEnumerable <Label> finalStates, IEnumerable <Transition> transitions, IEnumerable <Label> allStates = null) { if (initialState == null) { throw new ArgumentNullException(nameof(initialState)); } if (finalStates == null) { throw new ArgumentNullException(nameof(finalStates)); } if (transitions == null) { throw new ArgumentNullException(nameof(transitions)); } FinalStates = finalStates.ToSortedSet().AsReadOnly(); Transitions = transitions.ToSortedSet().AsReadOnly(); if (Transitions.AnyNull()) { throw new ArgumentException("One of the transitions is null.", nameof(transitions)); } if (!FinalStates.Any()) { throw new ArgumentException("Final states set is empty.", nameof(finalStates)); } if (FinalStates.AnyNull()) { throw new ArgumentException("One of the final state is null.", nameof(finalStates)); } ISet <Label> states = ExtractStates(Transitions); states.Add(initialState); if (allStates != null) { ISet <Label> allStatesSet = allStates.ToSortedSet(); if (allStatesSet.AnyNull()) { throw new ArgumentException("One of the state is null.", nameof(allStates)); } if (!allStatesSet.IsSupersetOf(states)) { throw new ArgumentException("States are not the superset of real states.", nameof(allStates)); } States = allStatesSet.AsReadOnly(); } else { States = states.AsReadOnly(); } Alphabet = Transitions.Select(t => t.Symbol).ToSortedSet().AsReadOnly(); InitialState = initialState; }