private static bool Accepts(this INfa <char> nfa, string input, IState state, Dictionary <Tuple <IState, string>, bool> cache) { if (input == string.Empty && nfa.IsAccepting(state)) { return(true); } var key = Tuple.Create(state, input); if (!cache.ContainsKey(key)) { cache[key] = false; // temporarily mark the (state, string) pair as non-accepting to avoid cycles // check epsilon transitions var result = nfa.EpsilonTransitions(state).Any(nextState => nfa.Accepts(input, nextState, cache)); // check transitions using the first letter of input if (input.Length > 0) { var firstLetter = input[0]; var remainingInput = input.Substring(1); var transitions = nfa.Transitions(state).GetValueOrDefault(firstLetter); if (transitions != null) { result = result || transitions.Any(nextState => nfa.Accepts(remainingInput, nextState, cache)); } } cache[key] = result; } return(cache.GetValueOrDefault(key)); }
private static Util.HashableHashSet <IState> EpsilonClosure(INfa <Symbol> nfa, Util.HashableHashSet <IState> states) { Util.HashableHashSet <IState> closure = new Util.HashableHashSet <IState>(); Queue <IState> q = new Queue <IState>(); foreach (IState state in states) { closure.Add(state); q.Enqueue(state); } while (q.Count != 0) { IState state = q.Dequeue(); foreach (IState neighbour in nfa.EpsilonTransitions(state)) { if (!closure.Contains(neighbour)) { closure.Add(neighbour); q.Enqueue(neighbour); } } } return(closure); }
private static HashSet <Symbol> GetAlphabet(INfa <Symbol> nfa) { HashSet <Symbol> alphabet = new HashSet <Symbol>(); Queue <IState> q = new Queue <IState>(); IState state = nfa.StartingState(); Util.HashableHashSet <IState> visited = new Util.HashableHashSet <IState>(); q.Enqueue(state); visited.Add(state); while (q.Count != 0) { state = q.Dequeue(); IReadOnlyDictionary <Symbol, IReadOnlyCollection <IState> > edges = nfa.Transitions(state); foreach (Symbol key in edges.Keys) { alphabet.Add(key); foreach (IState neighbour in edges[key]) { if (!visited.Contains(neighbour)) { visited.Add(neighbour); q.Enqueue(neighbour); } } } foreach (IState neighbour in nfa.EpsilonTransitions(state)) { if (!visited.Contains(neighbour)) { visited.Add(neighbour); q.Enqueue(neighbour); } } } return(alphabet); }
private int ConstructStates(Dictionary <IState, int> stateIds, INfa <Symbol> nfa, IState state) { if (stateIds.ContainsKey(state)) { return(stateIds[state]); } int stateId = stateIds.Count; stateIds[state] = stateId; this.epsilonTransitions.Add(null); this.transitions.Add(null); this.isAccepting.Add(nfa.IsAccepting(state)); this.epsilonTransitions[stateId] = nfa.EpsilonTransitions(state).Select(target => new ValueState <int>(this.ConstructStates(stateIds, nfa, target)) as IState).ToList(); this.transitions[stateId] = nfa.Transitions(state) .ToDictionary( keySelector: kv => kv.Key, elementSelector: kv => kv.Value.Select(target => new ValueState <int>(this.ConstructStates(stateIds, nfa, target))).ToList() as IReadOnlyCollection <IState>); return(stateId); }