public NDFA(U epsilon, NDFA <T, U> ndfa1, NDFA <T, U> ndfa2) { Epsilon = epsilon; if (ndfa1 != null) { Alphabet.UnionWith(ndfa1.Alphabet); } if (ndfa2 != null) { Alphabet.UnionWith(ndfa2.Alphabet); } Transitions = ndfa1 != null && ndfa2 != null ? ndfa1.Transitions.Concat(ndfa2.Transitions).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) : ndfa1 != null ? ndfa1.Transitions : ndfa2 != null ? ndfa2.Transitions : Transitions; }
public bool addTransition(U input, T fromState, T toState) { // Check if state and input already exists if (!Transitions.ContainsKey(fromState)) { // Add the transition to the automaton Transitions.Add(fromState, new Dictionary <U, T>()); } // Check if input already exists if (Transitions[fromState].ContainsKey(input)) { // if it already exists we don't need to add it, so the method returns false return(false); } // Add input to alphabet so the alphabet can dynamically be changed Alphabet.Add(input); Transitions[fromState].Add(input, toState); States.Add(fromState); States.Add(toState); return(true); }
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); }