public static void One(RegExp regExp, ref Automaat <string> automaat, ref int stateCounter, int leftState, int rightState) { char[] characters = regExp.Terminals.ToCharArray(); if (characters.Length == 1) { automaat.AddTransition( new Transition <string>(leftState.ToString(), characters[0], rightState.ToString())); } else { 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++; } }
private static Dictionary <char, string> SetupMerge(Automaat <string> dfaA, Automaat <string> dfaB) { Dictionary <char, string> completeMergedState = new Dictionary <char, string>(); foreach (string startState in dfaA.StartStates) { if (!completeMergedState.ContainsKey('A')) { completeMergedState.Add('A', startState + "_"); } else { completeMergedState['A'] = completeMergedState['A'] + startState + "_"; } } foreach (string startState in dfaB.StartStates) { if (!completeMergedState.ContainsKey('B')) { completeMergedState.Add('B', startState + "_"); } else { completeMergedState['B'] = completeMergedState['B'] + startState + "_"; } } completeMergedState['A'] = completeMergedState['A'].TrimEnd('_'); completeMergedState['B'] = completeMergedState['B'].TrimEnd('_'); return(completeMergedState); }
private static Automaat <string> RetrieveDfaFromPartitions(SortedSet <Partition> partitions, SortedSet <char> symbols) { Automaat <string> automaat = new Automaat <string>(symbols); foreach (Partition p in partitions) { if (p.IsFinal) { automaat.DefineAsFinalState(p.Identifier.ToString()); } if (p.IsStart) { automaat.DefineAsStartState(p.Identifier.ToString()); } foreach (KeyValuePair <string, Row> row in p.Rows) { foreach (KeyValuePair <char, string> innerRow in row.Value.InnerRows) { string toState = ""; foreach (Partition p2 in partitions) { if (p2.ContainsState(innerRow.Value)) { toState = p2.Identifier.ToString(); break; } } automaat.AddTransition(new Transition <string>(p.Identifier.ToString(), innerRow.Key, toState)); } } } return(automaat); }
public static void Convert(RegExp regExp, ref Automaat <string> automaat, ref int stateCounter, int leftState, int rightState) { switch (regExp.Operator) { case RegExp.OperatorEnum.Plus: Plus(regExp, ref automaat, ref stateCounter, leftState, rightState); break; case RegExp.OperatorEnum.Star: Star(regExp, ref automaat, ref stateCounter, leftState, rightState); break; case RegExp.OperatorEnum.Or: Or(regExp, ref automaat, ref stateCounter, leftState, rightState); break; case RegExp.OperatorEnum.Dot: Dot(regExp, ref automaat, ref stateCounter, leftState, rightState); break; case RegExp.OperatorEnum.One: One(regExp, ref automaat, ref stateCounter, leftState, rightState); break; } }
public static void Dot(RegExp regExp, ref Automaat <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); }
public static Automaat <string> OptimizeDfa(Automaat <string> dfa) { //Automaat<string> one = Reverse(dfa); //Automaat<string> two = Convert(one); //Automaat<string> three = Reverse(two); //Automaat<string> four = Convert(three); //return four; return(Convert(Reverse(Convert(Reverse(dfa))))); }
private static void contains(DfaGenerateValue param, ref Automaat <string> dfa) { char[] chars = param.Parameter.ToCharArray(); int stateCounter = 0; dfa.DefineAsStartState(stateCounter.ToString()); foreach (char c in chars) { dfa.AddTransition(new Transition <string>(stateCounter.ToString(), c, (stateCounter + 1).ToString())); stateCounter = dfa.States.Count - 1; } dfa.DefineAsFinalState(stateCounter.ToString()); //Hardcopy states List <string> ogStates = new List <string>(); foreach (string state in dfa.States) { ogStates.Add(state); } for (int i = 0; i < ogStates.Count; i++) { string state = ogStates[i]; List <Transition <string> > trans = dfa.GetTransition(state); SortedSet <char> routesPresent = new SortedSet <char>(); foreach (Transition <string> t in trans) { routesPresent.Add(t.Symbol); } foreach (char letter in dfa.Symbols) { if (!routesPresent.Contains(letter) && !dfa.FinalStates.Contains(state)) { int stateToReturnTo = backTrackForWorkingRoute(chars, letter); dfa.AddTransition(new Transition <string>(state, letter, ogStates[stateToReturnTo])); } } } foreach (char c in dfa.Symbols) { foreach (string finalstate in dfa.FinalStates) { dfa.AddTransition(new Transition <string>(stateCounter.ToString(), c, stateCounter.ToString())); } } }
private static void beginsWith(DfaGenerateValue param, ref Automaat <string> dfa) { char[] chars = param.Parameter.ToCharArray(); int stateCounter = 0; dfa.DefineAsStartState(stateCounter.ToString()); foreach (char c in chars) { dfa.AddTransition(new Transition <string>(stateCounter.ToString(), c, (stateCounter + 1).ToString())); stateCounter = dfa.States.Count - 1; } dfa.DefineAsFinalState(stateCounter.ToString()); foreach (char c in dfa.Symbols) { dfa.AddTransition(new Transition <string>(stateCounter.ToString(), c, stateCounter.ToString())); } //Hardcopy states SortedSet <string> ogStates = new SortedSet <string>(); foreach (string state in dfa.States) { ogStates.Add(state); } foreach (string state in ogStates) { List <Transition <string> > trans = dfa.GetTransition(state); SortedSet <char> routesPresent = new SortedSet <char>(); foreach (Transition <string> t in trans) { routesPresent.Add(t.Symbol); } foreach (char letter in dfa.Symbols) { if (!routesPresent.Contains(letter)) { dfa.AddTransition(new Transition <string>(state, letter, "F")); } } } if (dfa.States.Contains("F")) { foreach (char letter in dfa.Symbols) { dfa.AddTransition(new Transition <string>("F", letter, "F")); } } }
public static Automaat <string> MinimizeDfa(Automaat <string> automaat) { SortedSet <Partition> partitions = new SortedSet <Partition>(); Partition nonFinals = new Partition('A'); Partition finals = new Partition('B'); // Setup first step of minimalisation (ready given Automaat for the recursion method SortedSet <string> states = automaat.States; foreach (string state in states) { List <Transition <string> > trans = automaat.GetTransition(state); Row row = new Row(); foreach (Transition <string> t in trans) { row.AddRoute(t.Symbol, t.ToState); } if (automaat.FinalStates.Contains(state)) { finals.AddRow(state, row); } else { nonFinals.AddRow(state, row); } } partitions.Add(nonFinals); partitions.Add(finals); // Enter minimizing recursion partitions = MinimizePartitions(partitions); // Define start and final states foreach (Partition p in partitions) { foreach (string finalState in automaat.FinalStates) { if (p.ContainsState(finalState)) { p.IsFinal = true; } } foreach (string startState in automaat.StartStates) { if (p.ContainsState(startState)) { p.IsStart = true; } } } return(RetrieveDfaFromPartitions(partitions, automaat.Symbols)); }
public static void Plus(RegExp regExp, ref Automaat <string> automaat, ref int stateCounter, int leftState, int rightState) { int stateTwo = stateCounter; int stateThree = stateCounter + 1; stateCounter = stateCounter + 2; 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(regExp.Left, ref automaat, ref stateCounter, stateTwo, stateThree); }
public static void Execute(RegExp regExp) { // Convert regex to ndfa Console.WriteLine(); Console.WriteLine("----- Converting regex to ndfa -----"); Automaat <string> ndfa = ThompsonConstruction.ConvertRegExp(regExp); foreach (Transition <string> transition in ndfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(ndfa, "ndfa"); Console.WriteLine("Image saved as ndfa.jpg"); // Convert ndfa to dfa Console.WriteLine(); Console.WriteLine("----- Converting ndfa to dfa -----"); Automaat <string> dfa = NdfaToDfaConverter.Convert(ndfa); foreach (Transition <string> transition in dfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(dfa, "dfa"); Console.WriteLine("Image saved as dfa.jpg"); // Optimizing dfa Brzozowski Console.WriteLine(); Console.WriteLine("----- Optimizing dfa: Brzozowski's algorithm -----"); Automaat <string> brzozowskiDfa = NdfaToDfaConverter.OptimizeDfa(dfa); foreach (Transition <string> transition in brzozowskiDfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(brzozowskiDfa, "BrzozowskiDfa"); Console.WriteLine("Image saved as BrzozowskiDfa.jpg"); // Optimize dfa Hopcroft Console.WriteLine(); Console.WriteLine("----- Optimizing dfa: Hopcroft's algorithm -----"); Automaat <string> hopcroftDfa = HopcroftAlgorithm.MinimizeDfa(dfa); foreach (Transition <string> transition in hopcroftDfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(hopcroftDfa, "HopcroftDfa"); Console.WriteLine("Image saved as HopcroftDfa.jpg"); }
private static void ConvertState(string currentState, ref Automaat <string> dfa, ref Automaat <string> ndfa) { //If this state is already completely processed, return to avoid stackoverflow exception if (dfa.GetTransition(currentState).Count == ndfa.Symbols.Count) { return; } //split given state for comparison string[] states = currentState.Split('_'); //Loop through all symbols aka all the necessary routes foreach (char symbol in ndfa.Symbols) { //checks if this symbol already has a route in the new DFA if (CheckExistingRouteForChar(currentState, symbol, dfa)) { return; } int correctAmountOfRoutes = CheckAvailableRoutes(states, symbol, ndfa); //the TOSTATE of the to be added implementation string toState = ""; if (correctAmountOfRoutes == 0) { dfa.AddTransition(new Transition <string>(currentState, symbol, "F")); } else { bool isFinalState = GenerateToState(ref toState, states, symbol, ndfa); dfa.AddTransition(new Transition <string>(currentState, symbol, toState)); //Checks if currentState is should be final aswell (could be done better) if (ndfa.FinalStates.Contains(currentState)) { dfa.DefineAsFinalState(currentState); } if (isFinalState) { dfa.DefineAsFinalState(toState); } //checks if its not a loop to itself if (currentState != toState) { ConvertState(toState, ref dfa, ref ndfa); } } } }
public static Automaat <string> Reverse(Automaat <string> automaat) { Automaat <string> reverseAutomaat = new Automaat <string>(automaat.Symbols); foreach (Transition <string> transition in automaat.Transitions) { reverseAutomaat.AddTransition( new Transition <string>(transition.ToState, transition.Symbol, transition.FromState)); } reverseAutomaat.StartStates = automaat.FinalStates; reverseAutomaat.FinalStates = automaat.StartStates; return(reverseAutomaat); }
public static Automaat <string> ConvertRegExp(RegExp regExp) { Automaat <string> automaat = new Automaat <string>(); automaat.DefineAsStartState("0"); automaat.DefineAsFinalState("1"); int stateCounter = 2; Convert(regExp, ref automaat, ref stateCounter, 0, 1); automaat.Symbols = new SortedSet <char>(automaat.Transitions.Distinct().Select(e => e.Symbol).ToList()); //Epsilon should not be in alphabet automaat.Symbols.Remove('$'); return(automaat); }
public Automaat <string> Concatenation(Automaat <string> dfaA, Automaat <string> dfaB) { SortedSet <char> mergedAlphabet = dfaA.Symbols; mergedAlphabet.UnionWith(dfaB.Symbols); Automaat <string> merged = new Automaat <string>(mergedAlphabet); Dictionary <char, string> completeMergedState = SetupMerge(dfaA, dfaB); AddMergedState(completeMergedState, ref merged, dfaA, dfaB, MergeType.Concatenation); // Add new state to merged, work recursively from there return(finaliseMerge(merged)); }
public static void Or(RegExp regExp, ref Automaat <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; 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(regExp.Left, ref automaat, ref stateCounter, state2, state3); Convert(regExp.Right, ref automaat, ref stateCounter, state4, state5); }
public static Automaat <string> Convert(Automaat <string> ndfa) { Automaat <string> dfa = new Automaat <string>(ndfa.Symbols); string combinedStartState = ""; SortedSet <string> completeStartState = new SortedSet <string>(); bool isFinalState = false; // Loop through all the available start states from the ndfa and create a list with them + their epsilon-linked states foreach (string startState in ndfa.StartStates) { RetrieveEpsilonIncludedState(startState, ndfa, ref completeStartState); } //Turn sortedset into a string with all its states foreach (string s in completeStartState) { combinedStartState += s + "_"; if (ndfa.FinalStates.Contains(s)) { isFinalState = true; } } //trim last "_" off of string combinedStartState = combinedStartState.TrimEnd('_'); //Start conversion ConvertState(combinedStartState, ref dfa, ref ndfa); // Define combinedStartState as one and only start state in dfa dfa.DefineAsStartState(combinedStartState); if (isFinalState) { dfa.DefineAsFinalState(combinedStartState); } // Add a symbol loop to the failstate if one is created during conversion. if (dfa.States.Contains("F")) { foreach (char route in dfa.Symbols) { dfa.AddTransition(new Transition <string>("F", route, "F")); } } return(finaliseConversion(dfa)); }
private static int CheckAvailableRoutes(string[] states, char symbol, Automaat <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 Automaat <string> GenerateDfa(DfaGenerateValue param, char[] symbols) { Automaat <string> dfa = new Automaat <string>(symbols); if (param.Parameter == "") { return(null); } ///Check alphabet and parameter foreach (char c in param.Parameter.ToCharArray()) { if (!dfa.Symbols.Contains(c)) { return(null); } } switch (param.Type) { case GeneratorType.BeginsWith: beginsWith(param, ref dfa); break; case GeneratorType.Contains: contains(param, ref dfa); break; case GeneratorType.EndsWith: endsWith(param, ref dfa); break; } if (param.IsNot) { return(Not(dfa)); } else { return(dfa); } }
public static Automaat <string> Not(Automaat <string> automaat) { Automaat <string> notAutomaat = new Automaat <string>(automaat.Symbols); //save way of copying transitions notAutomaat.StartStates = automaat.StartStates; foreach (Transition <string> t in automaat.Transitions) { notAutomaat.AddTransition(t); } foreach (string state in notAutomaat.States) { if (!automaat.FinalStates.Contains(state)) { notAutomaat.DefineAsFinalState(state); } } return(notAutomaat); }
public static void PrintGraph(Automaat <string> data, string filename) { string toPrint = ""; toPrint += "digraph{"; toPrint += " "; toPrint += "{ node[style = invis, shape = none, label = \" \", width = 0, height = 0] SSS }"; toPrint += " "; toPrint += "node [shape = doublecircle];"; ISet <Transition <string> > transitions = data.Transitions; SortedSet <string> finalStates = data.FinalStates; SortedSet <string> startStates = data.StartStates; foreach (string t in finalStates) { toPrint += " " + ("S" + t) + " "; } toPrint += "; "; toPrint += " "; toPrint += "node [shape = circle];"; foreach (string state in startStates) { toPrint += " " + ("SSS") + "-> " + ("S" + state); } foreach (Transition <string> t in transitions) { toPrint += " " + ("S" + t.FromState) + " -> " + ("S" + t.ToState) + " " + "[ label = " + "\"" + t.Symbol + "\"" + " ];"; } toPrint += " }"; Console.WriteLine(toPrint); GenerateGraphFile(toPrint, filename); }
private static void RetrieveEpsilonIncludedState(string state, Automaat <string> auto, ref SortedSet <string> subStateList) { //Add given state to the given substatelist subStateList.Add(state); //retrieve the list of transitions from the given state List <Transition <string> > trans = auto.GetTransition(state); //Loop through all the transitions in search of epsilon routes. If a epsilon route is found that is not yet included in the list the route and its subsequent epsilon routes- //Will be added to substatelist through recursion. foreach (Transition <string> t in trans) { if (t.Symbol == '$' && !subStateList.Contains(t.ToState)) { RetrieveEpsilonIncludedState(t.ToState, auto, ref subStateList); } } /////Handy should we ever need to remove duplicates from an array without the use of sortedset<> //string[] individualSubStates = (completeState.Split('_')).Distinct().ToArray(); }
private static Automaat <string> finaliseMerge(Automaat <string> merged) { Automaat <string> finalisedMerge = new Automaat <string>(merged.Symbols); foreach (Transition <string> t in merged.Transitions) { finalisedMerge.AddTransition(new Transition <string>(t.FromState.Replace("_", String.Empty), t.Symbol, t.ToState.Replace("_", String.Empty))); } foreach (string startState in merged.StartStates) { finalisedMerge.DefineAsStartState(startState.Replace("_", String.Empty)); } foreach (string finalState in merged.FinalStates) { finalisedMerge.DefineAsFinalState(finalState.Replace("_", String.Empty)); } return(finalisedMerge); }
private static void ConstructDfa() { Console.WriteLine("Please enter DFA alphabet"); string alphabet = Console.ReadLine(); Console.WriteLine("DFA should:"); Console.WriteLine("Select option"); Console.WriteLine("1: Begin with"); Console.WriteLine("2: Not begin with"); Console.WriteLine("3: No begin with rule"); ConsoleKeyInfo optionInfo = Console.ReadKey(); char beginWithOption = optionInfo.KeyChar; Console.WriteLine(""); if (!ValidDfaOption(beginWithOption)) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } Console.WriteLine("Enter line"); string beginWith = Console.ReadLine(); Console.WriteLine("Select option"); Console.WriteLine("1: Contain"); Console.WriteLine("2: Not contain"); Console.WriteLine("3: No contain rule"); optionInfo = Console.ReadKey(); char containOption = optionInfo.KeyChar; Console.WriteLine(""); if (!ValidDfaOption(containOption)) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } Console.WriteLine("Enter line"); string contain = Console.ReadLine(); Console.WriteLine("Select option"); Console.WriteLine("1: End with"); Console.WriteLine("2: Not end with"); Console.WriteLine("3: No end with rule"); optionInfo = Console.ReadKey(); char endWithOption = optionInfo.KeyChar; Console.WriteLine(""); if (!ValidDfaOption(endWithOption)) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } Console.WriteLine("Enter line"); string endWith = Console.ReadLine(); Automaat <string> .DfaGenerateValue param1; Automaat <string> .DfaGenerateValue param2; Automaat <string> .DfaGenerateValue param3; Automaat <string> part1 = null; Automaat <string> part2 = null; Automaat <string> part3 = null; List <Automaat <string> > setupParts = new List <Automaat <string> >(); if (beginWith != "" && beginWithOption != '3') { if (beginWithOption == '1') { param1 = new Automaat <string> .DfaGenerateValue { Parameter = beginWith, IsNot = false, Type = Automaat <string> .GeneratorType.BeginsWith }; part1 = Automaat <string> .GenerateDfa(param1, alphabet.ToCharArray()); } if (beginWithOption == '2') { param1 = new Automaat <string> .DfaGenerateValue { Parameter = beginWith, IsNot = true, Type = Automaat <string> .GeneratorType.BeginsWith }; part1 = Automaat <string> .GenerateDfa(param1, alphabet.ToCharArray()); } if (part1 == null) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } setupParts.Add(part1); } if (contain != "" && containOption != '3') { if (containOption == '1') { param2 = new Automaat <string> .DfaGenerateValue { Parameter = contain, IsNot = false, Type = Automaat <string> .GeneratorType.Contains }; part2 = Automaat <string> .GenerateDfa(param2, alphabet.ToCharArray()); } if (containOption == '2') { param2 = new Automaat <string> .DfaGenerateValue { Parameter = contain, IsNot = true, Type = Automaat <string> .GeneratorType.Contains }; part2 = Automaat <string> .GenerateDfa(param2, alphabet.ToCharArray()); } if (part2 == null) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } setupParts.Add(part2); } if (endWith != "" && beginWithOption != '3') { if (endWithOption == '1') { param3 = new Automaat <string> .DfaGenerateValue { Parameter = endWith, IsNot = false, Type = Automaat <string> .GeneratorType.EndsWith }; part3 = Automaat <string> .GenerateDfa(param3, alphabet.ToCharArray()); } if (beginWithOption == '2') { param3 = new Automaat <string> .DfaGenerateValue { Parameter = endWith, IsNot = true, Type = Automaat <string> .GeneratorType.EndsWith }; part3 = Automaat <string> .GenerateDfa(param3, alphabet.ToCharArray()); } if (part3 == null) { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); return; } setupParts.Add(part3); } ; ; Automaat <string> toUse = null; ; if (setupParts.Count == 1) { toUse = setupParts[0]; } else if (setupParts.Count == 2) { toUse = Automaat <string> .Union(setupParts[0], setupParts[1]); } else if (setupParts.Count == 3) { Automaat <string> takeOne = Automaat <string> .Union(setupParts[0], setupParts[1]); Automaat <string> takeTwo = Automaat <string> .Union(takeOne, setupParts[2]); toUse = takeTwo; } if (toUse != null) { Console.WriteLine("----- DFA generated -----"); foreach (Transition <string> transition in toUse.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(toUse, "DFA"); Console.WriteLine("Image saved as DFA.jpg"); Console.WriteLine(); Console.WriteLine("----- Optimizing custom DFA: Brzozowski's algorithm -----"); Automaat <string> brzozowskiDfa = NdfaToDfaConverter.OptimizeDfa(toUse); foreach (Transition <string> transition in brzozowskiDfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(brzozowskiDfa, "BrzozowskiDFA"); Console.WriteLine("Image saved as BrzozowskiDFA.jpg"); // Optimize dfa Hopcroft Console.WriteLine(); Console.WriteLine("----- Optimizing custom DFA: Hopcroft's algorithm -----"); Automaat <string> hopcroftDfa = HopcroftAlgorithm.MinimizeDfa(toUse); foreach (Transition <string> transition in hopcroftDfa.Transitions) { Console.WriteLine(transition.ToString()); } Console.Write("Amount of states in hopcroft DFA: "); Console.WriteLine(hopcroftDfa.States.Count); Console.WriteLine("Printing image"); GraphVizParser.PrintGraph(hopcroftDfa, "HopcroftDFA"); Console.WriteLine("Image saved as HopcroftDFA.jpg"); if (hopcroftDfa.States.Count > 25) { Console.WriteLine("[Warning] This hopcroft dfa has more than 25 states."); Console.WriteLine("Due to char(ASCII) limitations, parsing issues could arise with printing this dfa correctly to an image"); Console.WriteLine("This is a third-party library (Graphviz) related issue"); Console.WriteLine("The above shown list of transitions from this hopcroft dfa ARE STILL CORRECT however"); } } else { Console.WriteLine("Invalid/Incorrect parameters entered, try again"); } //Automaat<string> takeOne = Automaat<string>.Union(part1, part2); //Automaat<string> takeTwo = Automaat<string>.Union(takeOne, part3); //GraphVizParser.PrintGraph(toUse, "customDfa"); }
//Fills toState string with correct TOSTATE, returns true or false whether or not this new TOSTATE should be a final state private static bool GenerateToState(ref string toState, string[] states, char symbol, Automaat <string> ndfa) { //boolean that will save whether this new TOSTATE needs to be a finalstate bool isFinalState = false; //Set of all the substates that need to be combined. this set does also include all states reached through epsilon routes SortedSet <string> newStates = new SortedSet <string>(); //Loop through all the substates foreach (string state in states) { //ndfa transitions for state List <Transition <string> > trans = ndfa.GetTransition(state); //This loop goes through all the aforementioned transitions //to see if there are routes with the correct symbol that need to be added to the new TOSTATE foreach (Transition <string> t in trans) { if (t.Symbol == symbol) { RetrieveEpsilonIncludedState(t.ToState, ndfa, ref newStates); //DEPRECATED, does not work if finalstate is reached through epsilon routes //Check if this state is final, if one of the substates for the new TOSTATE is final, TOSTATE becomes final as a whole. //if (ndfa.FinalStates.Contains(t.ToState)) //{ // isFinalState = true; //} } } } //combines substates into one string (TOSTATE) foreach (string subState in newStates) { toState += subState + "_"; if (ndfa.FinalStates.Contains(subState)) { isFinalState = true; } } toState = toState.TrimEnd('_'); return(isFinalState); }
private static void AddMergedState(Dictionary <char, string> prevMergedState, ref Automaat <string> merged, Automaat <string> dfaA, Automaat <string> dfaB, MergeType type) { // string[] states = prevMergedState.Split('_'); // Add prev int countFinal = 0; int countStart = 0; string completePrevMergedState = ""; foreach (KeyValuePair <char, string> entry in prevMergedState) { completePrevMergedState += entry.Value + "_"; if (entry.Key == 'A') { if (dfaA.FinalStates.Contains(entry.Value)) { countFinal++; } if (dfaA.StartStates.Contains(entry.Value)) { countStart++; } } else if (entry.Key == 'B') { if (dfaB.FinalStates.Contains(entry.Value)) { countFinal++; } if (dfaB.StartStates.Contains(entry.Value)) { countStart++; } } } completePrevMergedState = completePrevMergedState.TrimEnd('_'); if (type == MergeType.Union && countFinal == prevMergedState.Count) { merged.DefineAsFinalState(completePrevMergedState); } else if (type == MergeType.Concatenation && countFinal >= 1) { merged.DefineAsFinalState(completePrevMergedState); } if (type == MergeType.Union && countStart == prevMergedState.Count) { merged.DefineAsStartState(completePrevMergedState); } else if (type == MergeType.Concatenation && countStart >= 1) { merged.DefineAsStartState(completePrevMergedState); } if (merged.GetTransition(completePrevMergedState).Count == merged.Symbols.Count) { return; } foreach (char symbol in merged.Symbols) { Dictionary <char, string> newMergedState = new Dictionary <char, string>(); // This could break though if (CheckExistingRouteForChar(completePrevMergedState, symbol, merged)) { return; } foreach (KeyValuePair <char, string> entry in prevMergedState) { if (entry.Key == 'A') { CollectRoutesFromDfa(entry, symbol, dfaA, ref newMergedState); } else if (entry.Key == 'B') { CollectRoutesFromDfa(entry, symbol, dfaB, ref newMergedState); } } string completeNewMergedState = ""; foreach (KeyValuePair <char, string> entry in newMergedState) { completeNewMergedState += entry.Value + "_"; } completeNewMergedState = completeNewMergedState.TrimEnd('_'); merged.AddTransition(new Transition <string>(completePrevMergedState, symbol, completeNewMergedState)); AddMergedState(newMergedState, ref merged, dfaA, dfaB, type); } }
private static void CollectRoutesFromDfa(KeyValuePair <char, string> entry, char symbol, Automaat <string> source, ref Dictionary <char, string> newMergedState) { string[] states = entry.Value.Split('_'); foreach (string state in states) { List <Transition <string> > trans = source.GetTransition(state); foreach (Transition <string> t in trans) { if (t.Symbol == symbol) { if (!newMergedState.ContainsKey(entry.Key)) { newMergedState.Add(entry.Key, t.ToState + "_"); } else { newMergedState[entry.Key] = newMergedState[entry.Key] + t.ToState + "_"; } } } ///TEST THIS if (newMergedState.ContainsKey(entry.Key)) { newMergedState[entry.Key] = newMergedState[entry.Key].TrimEnd('_'); } } }
private static bool CheckExistingRouteForChar(string currentState, char symbol, Automaat <string> dfa) { List <Transition <string> > currentTrans = dfa.GetTransition(currentState); foreach (Transition <string> t in currentTrans) { if (t.Symbol == symbol) { return(true); } } return(false); }