/// <summary> /// Creates 3 example NDFA. /// </summary> public static void CreateExampleNDFA() { // With epsilon Automata <string> exmapleNDFA1 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaExample1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaExample1", "ndfaExample1Pic"); Console.WriteLine($"\nExample NDFA1 is a dfa = {exmapleNDFA1.IsDFA()}"); // EClosure test Console.WriteLine($"NDFA1 eClosure should be = A,B,C,E,F,H,M,O,Q,S From state S\n " + $"Result = {String.Join(",",exmapleNDFA1.EClosure("S").OrderBy(q => q).ToList())}\n"); Console.WriteLine($"NDFA1 eClosure should be = C,E,H From state C\n " + $"Result = {String.Join(",", exmapleNDFA1.EClosure("C").OrderBy(q => q).ToList())}\n"); Automata <string> exmapleNDFA2 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaExample2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaExample2", "ndfaExample2Pic"); Console.WriteLine($"\nExample NDFA2 is a dfa = {exmapleNDFA2.IsDFA()}"); Automata <string> exmapleNDFA3 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaExample3"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaExample3", "ndfaExample3Pic"); Console.WriteLine($"\nExample NDFA3 is a dfa = {exmapleNDFA3.IsDFA()}"); // With epsilon Automata <string> exmapleNDFA4 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaExample4"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaExample4", "ndfaExample4Pic"); Console.WriteLine($"\nExample NDFA4 is a dfa = {exmapleNDFA4.IsDFA()}"); // EClosure test Console.WriteLine($"NDFA4 eClosure should be = B,C \n " + $"Result = {String.Join(",", exmapleNDFA4.EClosure("B").OrderBy(q => q).ToList())}\n"); }
/// <summary> /// Creates the example ndfa to dfa. /// </summary> public static void CreateExampleNDFAToDFA() { // Aftekenlijst Opdracht 5 Creating pic of the ndfa1 -> toDfa + graphfile and new pic Automata <string> ndfaToDfa1 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaToDfaExample1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaToDfaExample1", "ndfaToDfaExample1Pic"); Automata <string> Dfa1 = NdfaToDfaConverter.ConvertToDFA(ndfaToDfa1); Dfa1.GenerateGraphFile("ndfaToDfaExample1Result"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaToDfaExample1Result", "ndfaToDfaExample1ResultPic"); // Aftekenlijst Opdracht 5 Creating pic of the ndfa2 -> toDfa + graphfile and new pic DOESNT work Automata <string> ndfaToDfa2 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaToDfaExample2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaToDfaExample2", "ndfaToDfaExample2Pic"); Automata <string> Dfa2 = NdfaToDfaConverter.ConvertToDFA(ndfaToDfa2); Dfa2.GenerateGraphFile("ndfaToDfaExample2Result"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaToDfaExample2Result", "ndfaToDfaExample2ResultPic"); // NDFA without epsilon Automata <string> ndfaToDfa3 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\ndfaExample3"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaExample3", "ndfaExample3Pic"); Automata <string> Dfa3 = NdfaToDfaConverter.ConvertToDFA(ndfaToDfa3); Dfa3.GenerateGraphFile("ndfaToDfaExample3Result"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ndfaToDfaExample3Result", "ndfaToDfaExample3ResultPic"); }
/// <summary> /// Creates the example thompson construction. /// </summary> public static void CreateExampleThompsonConstruction() { // regex : (aa)*(aa)+ string regex1 = "(aa)*(aa)+"; RegExpression expression1 = new RegExpression(regex1); Automata <string> ndfa1 = ThompsonConstruction.RegExpToNDFA(expression1); ndfa1.GenerateGraphFile("ThompsonNDFA1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ThompsonNDFA1", "ThompsonNDFA1Pic"); //// regex : a(a|b)* string regex2 = "a(a|b)*"; RegExpression expression2 = new RegExpression(regex2); Automata <string> ndfa2 = ThompsonConstruction.RegExpToNDFA(expression2); ndfa2.GenerateGraphFile("ThompsonNDFA2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ThompsonNDFA2", "ThompsonNDFA2Pic"); // regex : a*(aa+|(ba))* (abba|baab|bbbb)+ string regex3 = "a*(aa+|(ba))* (abba|baab|bbbb)+"; RegExpression expression3 = new RegExpression(regex3); Automata <string> ndfa3 = ThompsonConstruction.RegExpToNDFA(expression3); ndfa3.GenerateGraphFile("ThompsonNDFA3"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\ThompsonNDFA3", "ThompsonNDFA3Pic"); }
// is a NDFA public static Automata <string> GetExampleSlide14Week2() { char[] alphabet = { 'a', 'b' }; Automata <string> m = new Automata <string>(alphabet); m.AddTransition(new Transition <string>("A", 'a', "C")); m.AddTransition(new Transition <string>("A", 'b', "B")); m.AddTransition(new Transition <string>("A", 'c', "C")); m.AddTransition(new Transition <string>("B", 'b', "C")); m.AddTransition(new Transition <string>("B", "C")); m.AddTransition(new Transition <string>("C", 'a', "D")); m.AddTransition(new Transition <string>("C", 'a', "E")); m.AddTransition(new Transition <string>("C", 'b', "D")); m.AddTransition(new Transition <string>("D", 'a', "B")); m.AddTransition(new Transition <string>("D", 'a', "C")); m.AddTransition(new Transition <string>("E", 'a')); m.AddTransition(new Transition <string>("E", "D")); m.DefineAsStartState("A"); m.DefineAsFinalState("C"); m.DefineAsFinalState("E"); return(m); }
/// <summary> /// Converts the regexpress units. /// </summary> /// <param name="regExp">The reg exp.</param> /// <param name="ndfa">The ndfa.</param> /// <param name="stateCounter">The state counter.</param> /// <param name="leftState">State of the left.</param> /// <param name="rightState">State of the right.</param> public static void Convert(RegExpression regExp, ref Automata <string> ndfa, ref int stateCounter, int leftState, int rightState) { switch (regExp.o) { case RegExpression.Operator.PLUS: Plus(regExp, ref ndfa, ref stateCounter, leftState, rightState); break; case RegExpression.Operator.STAR: Star(regExp, ref ndfa, ref stateCounter, leftState, rightState); break; case RegExpression.Operator.OR: Or(regExp, ref ndfa, ref stateCounter, leftState, rightState); break; case RegExpression.Operator.DOT: Dot(regExp, ref ndfa, ref stateCounter, leftState, rightState); break; case RegExpression.Operator.ONE: One(regExp, ref ndfa, ref stateCounter, leftState, rightState); break; } }
/// <summary> /// Ones the specified reg exp. /// </summary> /// <param name="regExp">The reg exp.</param> /// <param name="automaat">The automaat.</param> /// <param name="stateCounter">The state counter.</param> /// <param name="leftState">State of the left.</param> /// <param name="rightState">State of the right.</param> public static void One(RegExpression regExp, ref Automata <string> automaat, ref int stateCounter, int leftState, int rightState) { char[] characters = regExp.terminals.ToCharArray(); if (characters.Length == 1) { // Create 1 letter transition automaat.AddTransition( new Transition <string>(leftState.ToString(), characters[0], rightState.ToString())); } else { // Create transition for multiple letters automaat.AddTransition( new Transition <string>(leftState.ToString(), characters[0], stateCounter.ToString())); int i = 1; while (i < characters.Length - 1) { automaat.AddTransition(new Transition <string>(stateCounter.ToString(), characters[i], (stateCounter + 1).ToString())); stateCounter++; i++; } automaat.AddTransition( new Transition <string>(stateCounter.ToString(), characters[i], rightState.ToString())); stateCounter++; } }
/// <summary> /// Minimizes the dfa by reverse -> ToDFA -> reverse -> toDFA. /// </summary> /// <param name="dfa">The dfa.</param> /// <returns></returns> public static Automata <string> MinimizeDfa(Automata <string> dfa) { dfa.ReverseAutomata(); dfa = ConvertToDFA(dfa); dfa.ReverseAutomata(); return(ConvertToDFA(dfa)); }
// is a DFA public static Automata <string> GetExampleSlide5Week2() { char[] alphabet = { 'a', 'b' }; Automata <string> m = new Automata <string>(alphabet); m.AddTransition(new Transition <string>("q0", 'a', "q1")); m.AddTransition(new Transition <string>("q0", 'b', "q4")); m.AddTransition(new Transition <string>("q1", 'a', "q4")); m.AddTransition(new Transition <string>("q1", 'b', "q2")); m.AddTransition(new Transition <string>("q2", 'a', "q3")); m.AddTransition(new Transition <string>("q2", 'b', "q4")); m.AddTransition(new Transition <string>("q3", 'a', "q1")); m.AddTransition(new Transition <string>("q3", 'b', "q2")); m.AddTransition(new Transition <string>("q4", 'a')); m.AddTransition(new Transition <string>("q4", 'b')); m.DefineAsStartState("q0"); m.DefineAsFinalState("q2"); m.DefineAsFinalState("q3"); return(m); }
/// <summary> /// Renames the states and transitions states. /// </summary> public static Automata <string> RenameStates(Automata <string> dfa) { // key = old name value = new name Dictionary <string, string> dictionay = new Dictionary <string, string>(); int index = 0; // Link shorter name to each state foreach (string s in dfa.states) { if (s != "Fuik") { dictionay.Add(s, $"q{index}"); index++; } } // Rename the states SortedSet <string> newStates = new SortedSet <string>(); foreach (string state in dfa.states) { if (state != "Fuik") { newStates.Add(dictionay[state]); } } dfa.states = newStates; // Rename start states SortedSet <string> newStartStates = new SortedSet <string>(); foreach (string startState in dfa.startStates) { newStartStates.Add(dictionay[startState]); } dfa.startStates = newStartStates; // Rename end states SortedSet <string> newEndStates = new SortedSet <string>(); foreach (string endState in dfa.endStates) { newEndStates.Add(dictionay[endState]); } dfa.endStates = newEndStates; // Rename trans states HashSet <Transition <string> > newTransitions = new HashSet <Transition <string> >(); foreach (Transition <string> oldTransition in dfa.transitions) { newTransitions.Add(new Transition <string>(oldTransition.GetFromState() == "Fuik" ? oldTransition.GetFromState() : dictionay[oldTransition.GetFromState()], oldTransition.GetSymbol(), oldTransition.GetToState() == "Fuik" ? oldTransition.GetToState() : dictionay[oldTransition.GetToState()])); } dfa.transitions = newTransitions; return(dfa); }
/// <summary> /// Converts . in the regex /// </summary> /// <param name="regExp">The reg exp.</param> /// <param name="automaat">The automaat.</param> /// <param name="stateCounter">The state counter.</param> /// <param name="leftState">State of the left.</param> /// <param name="rightState">State of the right.</param> public static void Dot(RegExpression regExp, ref Automata <string> automaat, ref int stateCounter, int leftState, int rightState) { int midState = stateCounter; stateCounter++; Convert(regExp.left, ref automaat, ref stateCounter, leftState, midState); Convert(regExp.right, ref automaat, ref stateCounter, midState, rightState); }
/// <summary> /// Reads the file and set objects and returns an automata. /// </summary> /// <param name="fileName">Name of the file.</param> public static Automata <string> ReadGraphFile(string fileName) { List <string> endStates = new List <string>(); List <string> startStates = new List <string>(); List <Transition <string> > transitions = new List <Transition <string> >(); SortedSet <char> alphabet = new SortedSet <char>(); // Open file string[] lines = System.IO.File.ReadAllLines(fileName + ".dot"); // Read lines foreach (string line in lines) { // If endstate if (line.Contains("doublecircle")) { endStates.Add(line.Split('"')[1]); } // Transitions if (line.Contains("->")) { // If normal transition or starttransition if (line.Contains("label")) { string[] l = line.Split('"'); // l1 is from l5 is symbol l3 is tostate transitions.Add(new Transition <string>(l[1], Convert.ToChar(l[5]), l[3])); alphabet.Add(Convert.ToChar(l[5])); } else { string[] l = line.Split('"'); startStates.Add(l[3]); } } } // Create automata Automata <string> m = new Automata <string>(alphabet); foreach (Transition <string> t in transitions) { m.AddTransition(t); } foreach (string end in endStates) { m.DefineAsFinalState(end); } foreach (string start in startStates) { m.DefineAsStartState(start); } return(m); }
/// <summary> /// Converts the state. /// </summary> /// <param name="currentState">State of the current.</param> /// <param name="dfa">The dfa.</param> /// <param name="ndfa">The ndfa.</param> private static void ConvertState(string currentState, ref Automata <string> dfa, ref Automata <string> ndfa) { // If state is already done just return if (dfa.GetTransitions(currentState).Count == dfa.GetAlphabet().Count) { return; } // Split states string[] states = currentState.Split('_'); // Go through all symbols foreach (char symbol in dfa.GetAlphabet()) { // Check if already has a route if (HasExistingRoutes(currentState, symbol, dfa)) { return; } int AmountOfCorrectRoutes = CheckAvailableRoutes(states, symbol, ndfa); string toState = ""; // Add transitions to the fuik if (AmountOfCorrectRoutes == 0) { dfa.AddTransition(new Transition <string>(currentState, symbol, "Fuik")); } else { bool isFinalState = GenerateToState(ref toState, states, symbol, ndfa); dfa.AddTransition(new Transition <string>(currentState, symbol, toState)); // Define final states if (ndfa.endStates.Contains(currentState)) { dfa.DefineAsFinalState(currentState); } if (isFinalState) { dfa.DefineAsFinalState(toState); } // Check if its not a loop transition. if (currentState != toState) { ConvertState(toState, ref dfa, ref ndfa); } } } }
/// <summary> /// Determines whether there is a transition with the current state and the give symbol in the dfa /// </summary> /// <param name="currentState">State of the current.</param> /// <param name="symbol">The symbol.</param> /// <param name="dfa">The dfa.</param> /// <returns> /// <c>true</c> if [has existing routes] [the specified current state]; otherwise, <c>false</c>. /// </returns> private static bool HasExistingRoutes(string currentState, char symbol, Automata <string> dfa) { List <Transition <string> > trans = dfa.GetTransitions(currentState); foreach (Transition <string> t in trans) { if (t.GetSymbol() == symbol) { return(true); } } return(false); }
/// <summary> /// Converts + in the regex /// </summary> /// <param name="regExp">The reg exp.</param> /// <param name="automaat">The automaat.</param> /// <param name="stateCounter">The state counter.</param> /// <param name="leftState">State of the left.</param> /// <param name="rightState">State of the right.</param> public static void Plus(RegExpression regExp, ref Automata <string> automaat, ref int stateCounter, int leftState, int rightState) { int stateTwo = stateCounter; int stateThree = stateCounter + 1; stateCounter = stateCounter + 2; // Create epsilon transitions automaat.AddTransition(new Transition <string>(leftState.ToString(), '$', stateTwo.ToString())); automaat.AddTransition(new Transition <string>(stateThree.ToString(), '$', stateTwo.ToString())); automaat.AddTransition(new Transition <string>(stateThree.ToString(), '$', rightState.ToString())); // Convert the middle part Convert(regExp.left, ref automaat, ref stateCounter, stateTwo, stateThree); }
/// <summary> /// Checks how many routes havent been taken if result is 0 it means it has to go to a fuik. /// </summary> /// <param name="states">The states.</param> /// <param name="symbol">The symbol.</param> /// <param name="ndfa">The ndfa.</param> /// <returns></returns> private static int CheckAvailableRoutes(string[] states, char symbol, Automata <string> ndfa) { int AmountOfCorrectRoutes = 0; foreach (string state in states) { var debugVar = ndfa.GetTransitions(state); if (ndfa.GetTransitions(state).Count(t => t.GetSymbol() == symbol) > AmountOfCorrectRoutes) { AmountOfCorrectRoutes = ndfa.GetTransitions(state).Count(t => t.GetSymbol() == symbol); } } return(AmountOfCorrectRoutes); }
/// <summary> /// Converts regular expression to NDFA. /// </summary> /// <param name="regExpression">The reg expression.</param> /// <returns></returns> public static Automata <string> RegExpToNDFA(RegExpression regExpression) { Automata <string> ndfa = new Automata <string>(); ndfa.DefineAsStartState("0"); ndfa.DefineAsFinalState("1"); int stateCounter = 2; Convert(regExpression, ref ndfa, ref stateCounter, 0, 1); ndfa.symbols = new SortedSet <char>(ndfa.transitions.Distinct().Select(e => e.GetSymbol()).ToList()); // Remove epsilons ndfa.symbols.Remove('$'); return(ndfa); }
/// <summary> /// Converts | in the regex /// </summary> /// <param name="regExp">The reg exp.</param> /// <param name="automaat">The automaat.</param> /// <param name="stateCounter">The state counter.</param> /// <param name="leftState">State of the left.</param> /// <param name="rightState">State of the right.</param> public static void Or(RegExpression regExp, ref Automata <string> automaat, ref int stateCounter, int leftState, int rightState) { int state2 = stateCounter; int state3 = stateCounter + 1; int state4 = stateCounter + 2; int state5 = stateCounter + 3; stateCounter = stateCounter + 4; // Create epsilon transitions automaat.AddTransition(new Transition <string>(leftState.ToString(), '$', state2.ToString())); automaat.AddTransition(new Transition <string>(leftState.ToString(), '$', state4.ToString())); automaat.AddTransition(new Transition <string>(state3.ToString(), '$', rightState.ToString())); automaat.AddTransition(new Transition <string>(state5.ToString(), '$', rightState.ToString())); // Convert the middle part of both middle parts Convert(regExp.left, ref automaat, ref stateCounter, state2, state3); Convert(regExp.right, ref automaat, ref stateCounter, state4, state5); }
/// <summary> /// Creates 2 DFA and minimize them /// </summary> public static void CreateExampleMinimizeDfa() { // Creating pic of the dfa1 -> minimize dfa and create graphfile and pic Automata <string> DFAToMin1 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\dfaToMinExample1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\dfaToMinExample1", "dfaToMinExample1Pic"); Automata <string> MinDFA1 = NdfaToDfaConverter.RenameStates(NdfaToDfaConverter.MinimizeDfa(DFAToMin1)); MinDFA1.GenerateGraphFile("MinDfaExample1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\MinDfaExample1", "MinDfaExample1Pic"); // Aftekenlijst opdracht 6 Creating pic of the dfa2 -> minimize dfa and create graphfile and pic Automata <string> DFAToMin2 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\dfaToMinExample2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\dfaToMinExample2", "dfaToMinExample2Pic"); Automata <string> MinDFA2 = NdfaToDfaConverter.RenameStates(NdfaToDfaConverter.MinimizeDfa(DFAToMin2)); MinDFA2.GenerateGraphFile("MinDfaExample2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\MinDfaExample2", "MinDfaExample2Pic"); }
/// <summary> /// Finalises the conversion by removing the _ part from each state. /// </summary> /// <param name="dfa">The merged.</param> /// <returns></returns> private static Automata <string> RemoveStateSeperators(Automata <string> dfa) { Automata <string> finaleDFA = new Automata <string>(dfa.symbols); foreach (Transition <string> trans in dfa.transitions) { finaleDFA.AddTransition(new Transition <string>(trans.GetFromState().Replace("_", string.Empty), trans.GetSymbol(), trans.GetToState().Replace("_", string.Empty))); } foreach (string startState in dfa.startStates) { finaleDFA.DefineAsStartState(startState.Replace("_", string.Empty)); } foreach (string endState in dfa.endStates) { finaleDFA.DefineAsFinalState(endState.Replace("_", string.Empty)); } return(finaleDFA); }
/// <summary> /// Creates 3 example DFA. /// </summary> public static void CreateExampleDFA() { Automata <string> exmapleDFA1 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\dfaExample1"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\dfaExample1", "dfaExample1Pic"); Console.WriteLine($"Example DFA1 is a dfa = {exmapleDFA1.IsDFA()}\n\n"); Console.WriteLine($"DFA1 Word: abaa Should be accepted Accepted: {exmapleDFA1.Accept("abaa",true)}"); Console.WriteLine($"DFA1 Word: abba Shouldn't be accepted Accepted: {exmapleDFA1.Accept("abba", true)}"); // 2A GetAcceptedLanguage Console.WriteLine($"\n\nLanguage for DFA1 \n"); Console.WriteLine(String.Join(",", exmapleDFA1.GetLanguage(4).OrderBy(x => x))); // 2B GetNotAcceptedLanguage Console.WriteLine($"\n\nNot Language for DFA1\n"); Console.WriteLine(String.Join(",", exmapleDFA1.GetNotLanguage(4).OrderBy(x => x))); Automata <string> exmapleDFA2 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\dfaExample2"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\dfaExample2", "dfaExample2Pic"); Console.WriteLine($"\n\nExample DFA2 is a dfa = {exmapleDFA2.IsDFA()}"); Console.WriteLine($"DFA2 Word: abab Should be accepted Accepted: {exmapleDFA2.Accept("abab", true)}"); Console.WriteLine($"DFA2 Word: ababa Shouldn't be accepted Accepted: {exmapleDFA2.Accept("ababa", true)}"); Console.WriteLine($"\n\nLanguage for DFA2 \n"); Console.WriteLine(String.Join(",", exmapleDFA2.GetLanguage(4).OrderBy(x => x))); Console.WriteLine($"\n\nNot Language for DFA2\n"); Console.WriteLine(String.Join(",", exmapleDFA2.GetNotLanguage(4).OrderBy(x => x))); Automata <string> exmapleDFA3 = TestAutomata.ReadGraphFile(@".\..\..\graphviz\dotfiles\dfaExample3"); FileDotEngine.Run(@".\..\..\graphviz\dotfiles\dfaExample3", "dfaExample3Pic"); Console.WriteLine($"\n\nExample DFA2 is a dfa = {exmapleDFA3.IsDFA()}"); Console.WriteLine($"DFA3 Word: bbbba Should be accepted Accepted: {exmapleDFA3.Accept("bbbba", true)}"); Console.WriteLine($"DFA4 Word: aaaba Shouldn't be accepted Accepted: {exmapleDFA3.Accept("aaaba", true)}"); }
public static Automata <string> ConvertToDFA(Automata <string> ndfa) { SortedSet <char> dfaAlphabet = ndfa.GetAlphabet(); dfaAlphabet.Remove('$'); Automata <string> dfa = new Automata <string>(dfaAlphabet); string combinedStartState = ""; SortedSet <string> completeStartState = new SortedSet <string>(); bool isFinalState = false; // Create list of startstates (startstates + reachable states via EClosure) foreach (string startState in ndfa.startStates) { List <string> reachableStates = ndfa.EClosure(startState); // split each reachable state up in indivual parts if its a combination of states foreach (string s in reachableStates) { string[] states = s.Split('_'); completeStartState.UnionWith(states); } } // Create a the complete startstate by seperating all the reachable "startstates" with a _ foreach (string s in completeStartState) { combinedStartState += s + "_"; if (ndfa.endStates.Contains(s)) // If 1 of these states is a endstate the combined startstate is an endstate { isFinalState = true; } } //trim last "_" off of string combinedStartState = combinedStartState.TrimEnd('_'); // Start if the conversion to DFA ConvertState(combinedStartState, ref dfa, ref ndfa); // Define the only combined startstate dfa.DefineAsStartState(combinedStartState); if (isFinalState) { dfa.DefineAsFinalState(combinedStartState); } // Create all transitions for each symbol to the fuik itself if (dfa.states.Contains("Fuik")) { foreach (char symbol in dfa.GetAlphabet()) { dfa.AddTransition(new Transition <string>("Fuik", symbol, "Fuik")); } } // Do final stuff //return RemoveStateSeperators(dfa); return(RenameStates(RemoveStateSeperators(dfa))); }
private static bool GenerateToState(ref string toState, string[] states, char symbol, Automata <string> ndfa) { bool isFinalState = false; SortedSet <string> newStates = new SortedSet <string>(); foreach (string state in states) { // Get the transitions of the NDFA List <Transition <string> > trans = ndfa.GetTransitions(state); // Possible error with getting to states with eClosure foreach (Transition <string> t in trans) { if (t.GetSymbol() == symbol) { // TODO remove for debugging onlu //var ep = ndfa.EClosure(t.GetFromState()); //var ep2 = ndfa.EClosure(t.GetToState()); newStates.UnionWith(ndfa.EClosure(t.GetToState())); } } } foreach (string subState in newStates) { toState += subState + "_"; if (ndfa.endStates.Contains(subState)) { isFinalState = true; } } toState = toState.TrimEnd('_'); return(isFinalState); }