//Static method for NDFA -> DFA public static DFA <string> toDFA(NDFA <string> ndfa) { DFA <string> dfa = new DFA <string>(ndfa.symbols); string combinedName = ""; SortedSet <string> completeStartState = new SortedSet <string>(); foreach (string startState in ndfa.startStates) { eClosure(startState, ndfa, ref completeStartState); } foreach (string s in completeStartState) { combinedName += s + "_"; } combinedName = combinedName.TrimEnd('_'); Convert(combinedName, ref dfa, ref ndfa); dfa.addStartState(combinedName); if (dfa.states.Contains("F")) { foreach (char route in dfa.symbols) { dfa.addTransition(new Transition <string>("F", route, "F")); } } return(dfa); }
//Used Ref for pointer use and prevent overflows... private static bool deltaE(ref string toState, string[] states, char symbol, NDFA <string> ndfa) { bool isFinalState = false; SortedSet <string> newStates = new SortedSet <string>(); foreach (string state in states) { List <Transition <string> > trans = ndfa.GetTransition(state); foreach (Transition <string> t in trans) { if (t.symbol == symbol) { eClosure(t.toState, ndfa, ref newStates); if (ndfa.finalStates.Contains(t.toState)) { isFinalState = true; } } } } foreach (string subState in newStates) { toState += subState + "_"; } toState = toState.TrimEnd('_'); return(isFinalState); }
public static NDFA <String> getTestNDFA52() { char[] alphabet = { 'a', 'b' }; NDFA <string> m = new NDFA <string>(alphabet); m.addTransition(new Transition <String>("A", 'a', "C")); m.addTransition(new Transition <String>("A", 'b', "C")); m.addTransition(new Transition <String>("A", 'b', "B")); m.addTransition(new Transition <String>("B", '$', "C")); m.addTransition(new Transition <String>("B", 'b', "C")); m.addTransition(new Transition <String>("C", 'a', "D")); m.addTransition(new Transition <String>("C", 'b', "D")); m.addTransition(new Transition <String>("D", 'a', "C")); m.addTransition(new Transition <String>("D", 'a', "B")); m.addTransition(new Transition <String>("C", 'a', "E")); m.addTransition(new Transition <String>("E", '$', "D")); m.addTransition(new Transition <String>("E", 'b', "E")); m.addStartState("A"); m.addFinalState("C"); m.addFinalState("E"); return(m); }
public static NDFA <String> getExample1() { char[] alphabet = { 'a', 'b' }; NDFA <String> m = new NDFA <String>(alphabet); m.addTransition(new Transition <String>("q0", '$', "q1")); m.addTransition(new Transition <String>("q0", '$', "q2")); m.addTransition(new Transition <String>("q1", 'b', "q3")); m.addTransition(new Transition <String>("q1", '$', "q5")); m.addTransition(new Transition <String>("q3", 'b', "q4")); m.addTransition(new Transition <String>("q2", 'a', "q5")); m.addTransition(new Transition <String>("q2", '$', "q6")); m.addTransition(new Transition <String>("q5", 'a', "q6")); m.addTransition(new Transition <String>("q4", '$', "q7")); m.addTransition(new Transition <String>("q6", '$', "q7")); // only on start state in a dfa: m.addStartState("q0"); // two final states: m.addFinalState("q7"); m.addFinalState("q3"); return(m); }
public static DFA <String> getTestNDFA00() { char[] alphabet = { 'a', 'b' }; NDFA <string> m = new NDFA <string>(alphabet); m.addTransition(new Transition <string>("0", '$', "1")); m.addTransition(new Transition <string>("0", '$', "7")); m.addTransition(new Transition <string>("1", '$', "2")); m.addTransition(new Transition <string>("1", '$', "4")); m.addTransition(new Transition <string>("2", 'a', "3")); m.addTransition(new Transition <string>("3", '$', "6")); m.addTransition(new Transition <string>("4", 'b', "5")); m.addTransition(new Transition <string>("5", '$', "6")); m.addTransition(new Transition <string>("6", '$', "7")); m.addTransition(new Transition <string>("6", '$', "1")); m.addTransition(new Transition <string>("7", 'a', "8")); m.addTransition(new Transition <string>("8", 'b', "9")); m.addTransition(new Transition <string>("9", 'b', "10")); m.addStartState("0"); m.addFinalState("10"); DFA <string> epsilonDFA = NDFA <string> .toDFA(m); return(epsilonDFA); }
//Used Ref for pointer use and prevent overflows... private static void eClosure(string state, NDFA <string> ndfa, ref SortedSet <string> subStateList) { subStateList.Add(state); List <Transition <string> > trans = ndfa.GetTransition(state); foreach (Transition <string> t in trans) { if (t.symbol == '$' && !subStateList.Contains(t.toState)) { eClosure(t.toState, ndfa, ref subStateList); } } }
public bool Equals(NDFA <T> other) { if (other == null) { return(false); } else if (this.symbols == other.symbols && this.transitions == other.transitions && this.startStates == other.startStates && this.finalStates == other.finalStates) { return(true); } else { return(false); } }
//Used Ref for pointer use and prevent overflows... private static void Convert(string inputState, ref DFA <String> dfa, ref NDFA <String> ndfa) { if (dfa.GetTransition(inputState).Count == ndfa.symbols.Length) { return; } string[] states = inputState.Split('_'); foreach (char symbol in ndfa.symbols) { if (CheckExistingRouteForChar(inputState, symbol, dfa)) { return; } int correctAmountOfRoutes = CheckAvailableRoutes(states, symbol, ndfa); string toState = ""; if (correctAmountOfRoutes == 0) { dfa.addTransition(new Transition <string>(inputState, symbol, "F")); } else { bool isFinalState = deltaE(ref toState, states, symbol, ndfa); dfa.addTransition(new Transition <string>(inputState, symbol, toState)); if (ndfa.finalStates.Contains(inputState)) { dfa.addFinalState(inputState); } if (isFinalState) { dfa.addFinalState(toState); } if (inputState != toState) { Convert(toState, ref dfa, ref ndfa); } } } }
public static DFA <string> toDFA(NDFA <string> ndfa) { DFA <string> dfa = new DFA <string>(ndfa.symbols); foreach (string startState in ndfa.states) { ConvertAutomata(startState, ref dfa, ref ndfa); dfa.addStartState(startState); } if (dfa.states.Contains("F")) { foreach (char route in dfa.symbols) { dfa.addTransition(new Transition <string>("F", route, "F")); } } return(dfa); }
private static int CheckAvailableRoutes(string[] states, char symbol, NDFA <string> ndfa) { //array which shows how many possible routes there are for each sub-state int[] possibleRoutesPerState = new int[states.Length]; // value that shows the amount of routes the ndfa has for all the substates combined. int correctAmountOfRoutes = 0; //reads ndfa for possible routes, saves maximum amount of accessible routes to correctAmountOfRoutes foreach (string state in states) { if (ndfa.GetTransition(state).Count(transition => transition.symbol == symbol) > correctAmountOfRoutes) { correctAmountOfRoutes = ndfa.GetTransition(state).Count(transition => transition.symbol == symbol); } } return(correctAmountOfRoutes); }
public static NDFA <String> getMinimizeExample() { char[] alphabet = { 'a', 'b' }; NDFA <String> m = new NDFA <String>(alphabet); m.addTransition(new Transition <String>("q0", 'a', "q1")); m.addTransition(new Transition <String>("q0", 'b', "q2")); m.addTransition(new Transition <String>("q1", 'a', "q0")); m.addTransition(new Transition <String>("q1", 'b')); m.addTransition(new Transition <String>("q2", 'a', "q0")); m.addTransition(new Transition <String>("q2", 'b')); // only one start state in a dfa: m.addStartState("q0"); // two final states: m.addFinalState("q1"); m.addFinalState("q2"); return(m); }
private static void ConvertAutomata(string currentState, ref DFA <string> dfa, ref NDFA <string> ndfa) { if (dfa.GetTransition(currentState).Count == ndfa.symbols.Length) { return; } string[] states = currentState.Split('_'); foreach (char symbol in ndfa.symbols) { List <Transition <string> > currentTrans = dfa.GetTransition(currentState); foreach (Transition <string> t in currentTrans) { if (t.symbol == symbol) { return; } } int[] counts = new int[states.Length]; for (int i = 0; i < states.Length; i++) { counts[i] = ndfa.GetTransition(states[i]).Count(transition => transition.symbol == symbol); } int amountOfRoutes = 0; foreach (int i in counts) { if (i > amountOfRoutes) { amountOfRoutes = i; } } if (amountOfRoutes == 0) { dfa.addTransition(new Transition <string>(currentState, symbol, "F")); } string toState = ""; bool isFinalState = false; SortedSet <String> newState = new SortedSet <string>(); if (amountOfRoutes >= 1) { foreach (string state in states) { List <Transition <string> > trans = ndfa.GetTransition(state); foreach (Transition <string> t in trans) { if (t.symbol == symbol) { newState.Add(t.toState); if (ndfa.finalStates.Contains(t.toState)) { isFinalState = true; } } } } foreach (string subState in newState) { toState += subState; toState += "_"; } if (newState.Count >= 1) { toState = toState.TrimEnd('_'); } dfa.addTransition(new Transition <string>(currentState, symbol, toState)); if (ndfa.finalStates.Contains(currentState)) { dfa.addFinalState(currentState); } if (isFinalState) { dfa.addFinalState(toState); } if (currentState != toState) { ConvertAutomata(toState, ref dfa, ref ndfa); } } } }