internal static Automaton PopulateDFAWithXAndEpsilonTransitionsNaive(this Automaton automaton) { bool changes = true; while (changes) { changes = AddEpsilonStatesForXXSubPaths(automaton); // Look for paths (RRR/SS) foreach (var startState in automaton.States) { // Now look for S * X^alpha * S states var SSreachabilityDictionary = automaton.GetStatesReachableFromStateWithSymbol(startState, Constants.RegularLanguage.S, useEpsilonStatesFromInitial: false, useEpsilonStatesAtEnd: true) .ToDictionary((s) => s, (s) => ReachabilityStatus.Even()) .ApplyXTransitionToReachabilityDictionary(automaton) .ApplySOrRTransitionToReachabilityDictionary(automaton, Constants.RegularLanguage.S, false); foreach (var(finalState, reachability) in SSreachabilityDictionary) { if (AddTransitionsFromReachabilityStatus(automaton, startState, finalState, reachability)) { changes = true; } } // Add R * X^alpha1 * R * X^alpha2 * R var RRRreachabilityDictionary = automaton.GetStatesReachableFromStateWithSymbol(startState, Constants.RegularLanguage.R, useEpsilonStatesFromInitial: false, useEpsilonStatesAtEnd: true) .ToDictionary((s) => s, (s) => ReachabilityStatus.Even()) .ApplyXTransitionToReachabilityDictionary(automaton) .ApplySOrRTransitionToReachabilityDictionary(automaton, Constants.RegularLanguage.R, true) .ApplyXTransitionToReachabilityDictionary(automaton) .ApplySOrRTransitionToReachabilityDictionary(automaton, Constants.RegularLanguage.R, false); foreach (var(finalState, reachability) in RRRreachabilityDictionary) { if (AddTransitionsFromReachabilityStatus(automaton, startState, finalState, reachability)) { changes = true; } } } } return(automaton); }
private Dictionary <int, ReachabilityStatus> ApplyTransitionToReachabilityDictionary(Dictionary <int, ReachabilityStatus> reachabilityDictionary, char symbol, bool includeEpsilon) { var newReachabilityDictionary = new Dictionary <int, ReachabilityStatus>(); foreach (var reachbilityLookup in reachabilityDictionary) { IEnumerable <KeyValuePair <int, ReachabilityStatus> > reachableStates = null !; if (includeEpsilon) { reachableStates = _outgoingTransitionLookup[reachbilityLookup.Key].GetTransitionDictionary(symbol); } else { reachableStates = _automaton.TransitionMatrix.GetStates(reachbilityLookup.Key, symbol).Select(s => KeyValuePair.Create(s, ReachabilityStatus.Even())); } foreach (var state in reachableStates) { var newReachability = state.Value.Times(reachbilityLookup.Value); if (!newReachabilityDictionary.TryGetValue(state.Key, out var newStatereachabilityStatus)) { newStatereachabilityStatus = new ReachabilityStatus(); newReachabilityDictionary[state.Key] = newStatereachabilityStatus; } newStatereachabilityStatus.EvenReachable |= newReachability.EvenReachable; newStatereachabilityStatus.OddReachable |= newReachability.OddReachable; } } return(newReachabilityDictionary); }