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 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); }
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)); }
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); } } } }
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); }
//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 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 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); } }