static void Main(string[] args) { FSATransitionFunction transition = new FSATransitionFunction(); transition.Add(1, 'a', 3); transition.Add(1, Symbols.Epsilon, 3); transition.Add(2, 'a', 1, 2); transition.Add(2, 'c', 3); transition.Add(3, 'b', 1, 2); FiniteStateAutomaton automaton = new FiniteStateAutomaton( AutomatonHelper.CreateStates(3), new HashSet <char>(new [] { 'a', 'b', 'c' }), transition, "1", AutomatonHelper.CreateFinalStates(3)); Console.WriteLine(automaton.IsWordInLanguage("ab")); FiniteStateAutomaton dfa = (FiniteStateAutomaton)automaton.CreateDeterministicAutomaton(); Console.WriteLine(dfa.IsDeterministic(true)); Game1 game = new Game1(); game.Run(); }
public override Automaton <StateSymbolPair, HashSet <State> > CreateDeterministicAutomaton() { //return if we're already deterministic. if (IsDeterministic()) { return(new FiniteStateAutomaton(this)); } FSATransitionFunction map = new FSATransitionFunction(); //ep-closure HashSet <State> startStates = GetStatesAccessibleFrom(StartState, Symbols.Epsilon); Stack <HashSet <State> > statesToVisit = new Stack <HashSet <State> >(); List <HashSet <State> > newStates = new List <HashSet <State> >(); statesToVisit.Push(startStates); newStates.Add(startStates); HashSet <State> finalStates = new HashSet <State>(); //consider the case our start state(s) are final if (startStates.Intersect(FinalStates).Count() != 0) { Console.WriteLine("Start state(s) are final; adding.."); finalStates.Add(AutomatonHelper.CreateSetOfStates(startStates)); } while (statesToVisit.Count > 0) { HashSet <State> stateSet = statesToVisit.Pop(); //consider each symbol in our alphabet; the transition from S => S is going to be the union of every possible accessible state foreach (Symbol symbol in Alphabet) { //if the map contains this key, then we've already visited this state - don't do it again if (!map.ContainsKey(new StateSymbolPair(AutomatonHelper.CreateSetOfStates(stateSet), symbol))) { HashSet <State> closure = new HashSet <State>(); foreach (State state in stateSet) { closure.UnionWith(GetStatesAccessibleFrom(state, symbol)); } Console.WriteLine("From state {0}, on input {2}, the states are {1}", AutomatonHelper.CreateSetOfStates(stateSet), AutomatonHelper.CreateSetOfStates(closure), symbol); HashSet <State> stateToAdd = new HashSet <State>() { closure.Count == 0 ? AutomatonHelper.CreateSetOfStates( Symbols.ErrorState.ToString()) : AutomatonHelper.CreateSetOfStates(closure) }; //so now closure is every possible state reachable from some symbol. If it's empty, it's the error state Console.WriteLine("Adding transition from state {0} on symbol {1}", AutomatonHelper.CreateSetOfStates(stateSet), symbol); map.Add(new StateSymbolPair(AutomatonHelper.CreateSetOfStates(stateSet), symbol), stateToAdd); //keep a track of the sets we have newStates.Add(stateToAdd); //if we have a final state, the set of states is final if (closure.Intersect(FinalStates).Count() != 0) { finalStates.Add(AutomatonHelper.CreateSetOfStates(closure)); } //now we need to visit this set of states and find where it goes if (closure.Count != 0) { statesToVisit.Push(closure); } } } } HashSet <State> states = new HashSet <State>(); //the set of states is the unique keys in the mapping foreach (var state in map.Keys.GroupBy(k => k.State)) { states.Add(state.Key); } //the final states are any of the 'new' states which contain a final state return(new FiniteStateAutomaton(states, Alphabet, map, AutomatonHelper.CreateSetOfStates(startStates), finalStates)); }
public static void Add(this Dictionary <StateSymbolPair, HashSet <State> > dict, int startState, char input, params int[] moveTo) { dict.Add(new StateSymbolPair(startState.ToString(), input), AutomatonHelper.CreateFinalStates(moveTo)); }