public static NFA Union(NFA m1, NFA m2) { var ret = new NFA(m1); m1.MakeSingleEndState(); var ret2 = new NFA(m2); m1.MakeSingleEndState(); // Renames elements before combining them var newNames = Enumerable.Range(0, ret.States.Count + ret2.States.Count) .Select(s => $"q{s}"); ret.Rename(newNames.Take(ret.States.Count).ToArray()); ret2.Rename(newNames.Skip(ret.States.Count).Take(ret2.States.Count).ToArray()); // Combines the tow states ret.States = ret.States.Concat(ret2.States).ToDictionary(s => s.Key, s => s.Value); // Sets new start state ret.StartState.IsStartState = false; ret2.StartState.IsStartState = false; var startState = new NFAState(ret.GetUniqueName(), false, true); startState.Transitions['λ'] = new List <NFAState> { ret.StartState, ret2.StartState }; ret.StartState = startState; ret.States.Add(startState.Name, startState); ret.SetFinalStates(); ret.MakeSingleEndState(); ret.Rename(); return(ret); }