public static IReadOnlyCollection <IState> GetAllStates <TLabel, Symbol>(this IDfa <TLabel, Symbol> dfa) { var visited = new HashSet <IState>(); var queue = new Queue <IState>(); queue.Enqueue(dfa.StartingState()); visited.Add(dfa.StartingState()); while (queue.Count > 0) { var s = queue.Dequeue(); var transitions = dfa.Transitions(s); foreach (var nextState in transitions.Values) { if (!visited.Contains(nextState)) { queue.Enqueue(nextState); visited.Add(nextState); } } } return(visited); }
private static HashSet <IState> ReachableStates(IDfa <TLabel, Symbol> dfa) { var reachedStates = new HashSet <IState>(); var queue = new Queue <IState>(); queue.Enqueue(dfa.StartingState()); reachedStates.Add(dfa.StartingState()); while (queue.Count > 0) { IState state = queue.Dequeue(); foreach (KeyValuePair <Symbol, IState> transition in dfa.Transitions(state)) { if (!reachedStates.Contains(transition.Value)) { reachedStates.Add(transition.Value); queue.Enqueue(transition.Value); } } } return(reachedStates); }
private static TLabel GetTargetLabel <TLabel>(IDfa <TLabel, char> dfa, string s, TLabel defaultLabel) { var state = dfa.StartingState(); foreach (var ch in s) { var transitions = dfa.Transitions(state); if (!transitions.ContainsKey(ch)) { return(defaultLabel); } state = transitions[ch]; } return(dfa.Label(state)); }
public static bool AreEquivalent(IDfa <TLabel, Symbol> firstDfa, IDfa <TLabel, Symbol> secondDfa) { var reached = new HashSet <Tuple <IState, IState> >(); var queue = new Queue <Tuple <IState, IState> >(); queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState())); reached.Add(queue.Peek()); while (queue.Count > 0) { var(firstState, secondState) = queue.Dequeue(); if (!firstDfa.Label(firstState).Equals(secondDfa.Label(secondState))) { return(false); } var firstStateTransitions = firstDfa.Transitions(firstState); var secondStateTransitions = secondDfa.Transitions(secondState); if (!firstStateTransitions.Count.Equals(secondStateTransitions.Count)) { return(false); } foreach (var(c, firstNextState) in firstStateTransitions) { if (!secondStateTransitions.ContainsKey(c)) { return(false); } var secondNextState = secondStateTransitions[c]; var pair = Tuple.Create(firstNextState, secondNextState); if (!reached.Contains(pair)) { reached.Add(pair); queue.Enqueue(pair); } } } return(true); }
private static HashSet <IState> ReachableStates <TLabel>(IDfa <TLabel, char> dfa) { var reachedStates = new HashSet <IState>(); var queue = new Queue <IState>(new[] { dfa.StartingState() }); while (queue.Count > 0) { var state = queue.Dequeue(); foreach (var(_, value) in dfa.Transitions(state)) { if (!reachedStates.Contains(value)) { reachedStates.Add(value); queue.Enqueue(value); } } } return(reachedStates); }
private static void CheckAutomatonEquivalence <TLabel>(IDfa <TLabel, char> firstDfa, IDfa <TLabel, char> secondDfa) { var reached = new HashSet <Tuple <IState, IState> >(); var queue = new Queue <Tuple <IState, IState> >(); queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState())); reached.Add(queue.Peek()); while (queue.Count > 0) { var(firstState, secondState) = queue.Dequeue(); Assert.AreEqual(firstDfa.Label(firstState), secondDfa.Label(secondState), "Labels should be equal"); var firstStateTransitions = firstDfa.Transitions(firstState); var secondStateTransitions = secondDfa.Transitions(secondState); var firstTransitionCount = firstStateTransitions.Count; var secondTransitionCount = secondStateTransitions.Count; Assert.AreEqual( firstTransitionCount, secondTransitionCount, $"States {firstState} and {secondState} have different number of transitions: {firstTransitionCount} != {secondTransitionCount}"); foreach (var(c, firstNextState) in firstStateTransitions) { Assert.IsTrue( secondStateTransitions.ContainsKey(c), $"States have different sets of transitions, {secondTransitionCount} : {string.Join(",", firstStateTransitions.Select((x, y) => ((int)x.Key).ToString()).ToList())}"); var secondNextState = secondStateTransitions[c]; var pair = Tuple.Create(firstNextState, secondNextState); if (!reached.Contains(pair)) { reached.Add(pair); queue.Enqueue(pair); } } } }