static public Automata <String> dfaMutationTestL4() { char[] alphabet = { 'a', 'b' }; Automata <String> automata = new Automata <String>(alphabet); automata.AddTransition(new Transition <string>("A", "B", 'a')); automata.AddTransition(new Transition <string>("B", "D", 'b')); automata.AddTransition(new Transition <string>("D", "E", 'b')); automata.AddTransition(new Transition <string>("B", 'a')); automata.AddTransition(new Transition <string>("D", "B", 'a')); automata.AddTransition(new Transition <string>("A", "C", 'b')); automata.AddTransition(new Transition <string>("C", "F", 'b')); automata.AddTransition(new Transition <string>("F", "G", 'a')); automata.AddTransition(new Transition <string>("C", "B", 'a')); automata.AddTransition(new Transition <string>("F", "C", 'b')); automata.AddTransition(new Transition <string>("E", 'a')); automata.AddTransition(new Transition <string>("E", 'b')); automata.AddTransition(new Transition <string>("G", 'a')); automata.AddTransition(new Transition <string>("G", 'b')); automata.DefineAsStartState("A"); automata.DefineAsFinalState("E"); automata.DefineAsFinalState("G"); return(automata); }
/// <summary> /// Turns a <see cref="RegExp"/> into a <see cref="Automata{string}"/>, which is a NDFA. /// </summary> /// <param name="expressionToTranslate">The <see cref="RegExp"/> to translate.</param> /// <returns>A <see cref="Automata{string}"/>, which is a NDFA or null if there was a problem</returns> public Automata <string> GenerateNDFA(RegExp expressionToTranslate) { HashSet <char> alphabet = new HashSet <char>(); String regexAsString = expressionToTranslate.ToString(); foreach (char c in regexAsString) { if (IsUsableCharacter(c)) { alphabet.Add(c); } } ; ThompsonPart completeNdfaAsThompson = GenerateThompsonPart(regexAsString); if (completeNdfaAsThompson.Equals(new ThompsonPart())) { return(null); } Automata <string> NDFA = new Automata <string>(alphabet.ToArray()); foreach (Transition <string> thompsonTransition in completeNdfaAsThompson.transitions) { NDFA.AddTransition(thompsonTransition); } NDFA.DefineAsStartState(completeNdfaAsThompson.startState); NDFA.DefineAsFinalState(completeNdfaAsThompson.finalState); return(NDFA); }
static public Automata <String> getExampleSlide14Lesson2() { char[] alphabet = { 'a', 'b' }; Automata <String> automata = new Automata <String>(alphabet); automata.AddTransition(new Transition <String>("A", "C", 'a')); automata.AddTransition(new Transition <String>("A", "B", 'b')); automata.AddTransition(new Transition <String>("A", "C", 'b')); automata.AddTransition(new Transition <String>("B", "C", 'b')); automata.AddTransition(new Transition <String>("B", "C")); automata.AddTransition(new Transition <String>("C", "D", 'a')); automata.AddTransition(new Transition <String>("C", "E", 'a')); automata.AddTransition(new Transition <String>("C", "D", 'b')); automata.AddTransition(new Transition <String>("D", "B", 'a')); automata.AddTransition(new Transition <String>("D", "C", 'a')); automata.AddTransition(new Transition <String>("E", 'a')); automata.AddTransition(new Transition <String>("E", "D")); // only on start state in a dfa: automata.DefineAsStartState("A"); // two final states: automata.DefineAsFinalState("C"); automata.DefineAsFinalState("E"); return(automata); }
/// <summary> /// Turns a dfa into a form in which the original is not accepted. /// </summary> /// <param name="originalDfa">The dfa to "invert"</param> /// <returns>A dfa that is !the original dfa</returns> public Automata <T> NotDfa(Automata <T> originalDfa) { if (!originalDfa.IsDfa()) { throw new ArgumentException("Given automata is not a DFA."); } Automata <T> notDfa = new Automata <T>(originalDfa.Symbols); //Alles wat geen end state is word een end, en omgekeerd. //Filter all end states from all the states IEnumerable <T> newEndStates = originalDfa.States.Except(originalDfa.FinalStates); //Set everthing in the new dfa foreach (Transition <T> transition in originalDfa.Transitions) { notDfa.AddTransition(transition); } foreach (T startState in originalDfa.StartStates) { notDfa.DefineAsStartState(startState); } foreach (T finalState in newEndStates) { notDfa.DefineAsFinalState(finalState); } return(notDfa); }
private static void TestNDFAClass() { Automata <String> NDFA1 = TestAutomata.getExampleSlide8Lesson2(); Automata <String> NDFA2 = TestAutomata.getExampleSlide14Lesson2(); NDFA1.PrintTransitions(); Console.WriteLine("-----------------------------------------"); Console.WriteLine("NDFA1 is dfa? " + NDFA1.IsDfa()); Console.WriteLine("-----------------------------------------"); foreach (string state in NDFA1.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in NDFA1.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("String {0} is a {1} string for Auto1.", VALID_STRING_1, NDFA1.IsStringAcceptable(VALID_STRING_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto1.", INVALID_STRING_0, NDFA1.IsStringAcceptable(INVALID_STRING_0) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto1.", VALID_STRING_2, NDFA1.IsStringAcceptable(VALID_STRING_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto1.", INVALID_STRING_1, NDFA1.IsStringAcceptable(INVALID_STRING_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto1.", INVALID_STRING_2, NDFA1.IsStringAcceptable(INVALID_STRING_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto1.", INVALID_STRING_3, NDFA1.IsStringAcceptable(INVALID_STRING_3) ? "valid" : "invalid"); Console.WriteLine("-----------------------------------------"); Console.WriteLine("Generate a string of length 9. Resulting string = " + NDFA1.GenerateLanguageOfGivenLength(9)); Console.WriteLine("-----------------------------------------"); NDFA2.PrintTransitions(); Console.WriteLine("NDFA2 is dfa? " + NDFA2.IsDfa()); Console.WriteLine("-----------------------------------------"); }
static public Automata <String> dfaMutationTestL1() { char[] alphabet = { 'a', 'b' }; Automata <String> automata = new Automata <String>(alphabet); automata.AddTransition(new Transition <string>("A", "B", 'b')); automata.AddTransition(new Transition <string>("B", "C", 'a')); automata.AddTransition(new Transition <string>("C", "D", 'b')); automata.AddTransition(new Transition <string>("D", "E", 'a')); automata.AddTransition(new Transition <string>("E", "F", 'a')); automata.AddTransition(new Transition <string>("A", "G", 'a')); automata.AddTransition(new Transition <string>("B", "G", 'b')); automata.AddTransition(new Transition <string>("C", "G", 'a')); automata.AddTransition(new Transition <string>("D", "G", 'b')); automata.AddTransition(new Transition <string>("E", "G", 'b')); //End point shenenigans so testing goes a bit smoother automata.AddTransition(new Transition <string>("F", 'a')); automata.AddTransition(new Transition <string>("F", 'b')); automata.AddTransition(new Transition <string>("G", 'a')); automata.AddTransition(new Transition <string>("G", 'b')); automata.DefineAsStartState("A"); automata.DefineAsFinalState("F"); return(automata); }
/// <summary> /// Turns a dfa into a form in which the original is not accepted. /// </summary> /// <param name="originalDfa">The dfa to make a reverse of</param> /// <returns>A dfa that is a reverse of the original dfa</returns> public Automata <T> ReverseDfa(Automata <T> originalDfa) { if (!originalDfa.IsDfa()) { throw new ArgumentException("Given automata is not a DFA."); } Automata <T> reversedDfa = new Automata <T>(originalDfa.Symbols); //Every transition is swapped as follows: new transition(original end state, symbol, original start state) foreach (Transition <T> transition in originalDfa.Transitions) { reversedDfa.AddTransition(new Transition <T>(transition.ToState, transition.FromState, transition.Identifier)); } //All start states become end states foreach (T startState in originalDfa.StartStates) { reversedDfa.DefineAsFinalState(startState); } //All end states become start states foreach (T endState in originalDfa.FinalStates) { reversedDfa.DefineAsStartState(endState); } return(reversedDfa); }
public void WriteToGVFile <T>(Automata <T> automata, string filename, string path, bool leftRight = false) where T : IComparable { Dictionary <T, int> stateNumbers = new Dictionary <T, int>(); int i = 1; foreach (T state in automata.States) { stateNumbers.Add(state, i); i++; } using (StreamWriter writer = new StreamWriter($"{path}{filename}.gv")) { //start writer.WriteLine($"digraph {filename} {{ "); if (leftRight) { writer.WriteLine("rankdir=LR;"); } //labels writer.WriteLine(@"NOTHING [label="""", shape=none]"); foreach (KeyValuePair <T, int> state in stateNumbers) { if (automata.StartStates.Contains(state.Key)) { writer.WriteLine($@"{state.Value} [label=""{state.Key.ToString()}"", shape=ellipse, style=filled, color=lightblue]"); } else if (automata.FinalStates.Contains(state.Key)) { writer.WriteLine($@"{state.Value} [label=""{state.Key.ToString()}"", shape=ellipse, peripheries=2, style=filled, color=yellowgreen]"); } else { writer.WriteLine($@"{state.Value} [label=""{state.Key.ToString()}"", shape=ellipse]"); } } writer.WriteLine(""); //transitions foreach (T start in automata.StartStates) { writer.WriteLine($@"NOTHING -> {stateNumbers.FirstOrDefault(x => x.Key.Equals(start)).Value}"); } foreach (Transition <T> transition in automata.Transitions) { int from = stateNumbers.FirstOrDefault(x => x.Key.Equals(transition.FromState)).Value; int to = stateNumbers.FirstOrDefault(x => x.Key.Equals(transition.ToState)).Value; char symbol = transition.Identifier; writer.WriteLine($@"{from} -> {to} [label=""{symbol}""]"); } writer.WriteLine("}"); } }
/// <summary> /// This makes sure only a single - will end up between states. /// </summary> /// <param name="dfaToRemap">The dfa to remap the states for</param> /// <returns>A re mapped version of the given automata</returns> private Automata <T> RemapStates(Automata <T> dfaToRemap) { Dictionary <T, T> stateMap = new Dictionary <T, T>(); for (int i = 0; i < dfaToRemap.States.Count; i++) { string newState = "q" + i; T newStateT = (T)Convert.ChangeType(newState, typeof(T)); stateMap.Add(dfaToRemap.States.ElementAt(i), newStateT); } Console.WriteLine("Now printing the remap dictionary:"); foreach (KeyValuePair <T, T> map in stateMap) { Console.WriteLine("Mapped {0} as {1}", map.Key, map.Value); } Console.WriteLine("-----------------------------------------"); Automata <T> remappedDfa = new Automata <T>(dfaToRemap.Symbols); foreach (Transition <T> transition in dfaToRemap.Transitions) { remappedDfa.AddTransition(new Transition <T>(stateMap[transition.FromState], stateMap[transition.ToState], transition.Identifier)); } foreach (T startState in dfaToRemap.StartStates) { remappedDfa.DefineAsStartState(stateMap[startState]); } foreach (T finalState in dfaToRemap.FinalStates) { remappedDfa.DefineAsFinalState(stateMap[finalState]); } return(remappedDfa); }
/// <summary> /// Generates the dfa for the given dictionary of states /// </summary> private void GenerateDFA() { dfa = new Automata <T>(ndfa.Symbols); //Start building the DFA as normal, with the state names being the combined states to be reached in one string, with a - as delimiter. //Starting with the start state, foreach symbol create two string builder objects, build up the string in the state + - format //Create a transition with the symbol and the states. //Should we reach an empty collection, create the $ state, and for each symbol in the alphabet make a transition to this state //Begin with the start state and all transitions List <Transition <T> > dfaStart = GenerateDfaStart(); //Keep track of states that we still need to visit HashSet <T> statesToTraverse = new HashSet <T>(); foreach (Transition <T> transition in dfaStart) { dfa.AddTransition(transition); if (!transition.FromState.Equals(transition.ToState)) { statesToTraverse.Add(transition.ToState); } } //Sets all the transitions for the following states GenerateOtherTransitions(statesToTraverse); //After that, for all states check if it's a start state or end state. MarkStatesAsStartOrEnd(); }
static public Automata <String> getExampleSlide8Lesson2() { char[] alphabet = { 'a', 'b' }; Automata <String> automata = new Automata <string>(alphabet); automata.AddTransition(new Transition <String>("q0", "q1", 'a')); automata.AddTransition(new Transition <String>("q0", "q4", 'b')); automata.AddTransition(new Transition <String>("q1", "q4", 'a')); automata.AddTransition(new Transition <String>("q1", "q2", 'b')); automata.AddTransition(new Transition <String>("q2", "q3", 'a')); automata.AddTransition(new Transition <String>("q2", "q4", 'b')); automata.AddTransition(new Transition <String>("q3", "q1", 'a')); automata.AddTransition(new Transition <String>("q3", "q2", 'b')); // the error state, loops for a and b: automata.AddTransition(new Transition <String>("q4", 'a')); automata.AddTransition(new Transition <String>("q4", 'b')); // only on start state in a dfa: automata.DefineAsStartState("q0"); // two final states: automata.DefineAsFinalState("q2"); automata.DefineAsFinalState("q3"); return(automata); }
/// <summary> /// Combines two <see cref="Automata{T}"/> into a single automata if they are both dfa's /// </summary> /// <param name="firstDfa">The first dfa to use</param> /// <param name="secondDfa">The other dfa to use</param> /// <returns>A dfa that consists that takes the conditions for both dfa's into account</returns> public Automata <T> CombineAutomataAnd(Automata <T> firstDfa, Automata <T> secondDfa) { if (!firstDfa.IsDfa() || !secondDfa.IsDfa()) { throw new ArgumentException("One of the given automata is not a dfa"); } IEnumerable <char> combinedAlphabet = firstDfa.Symbols.Union(secondDfa.Symbols); Automata <T> combinedDfa = new Automata <T>(combinedAlphabet.ToArray()); startStatesForDfa.Clear(); combinedTransitionsMap.Clear(); //Read the starting states SetStartStatesForAndOrOr(firstDfa, secondDfa); //Gather all states that follow MapReachableStatesForGivenDFA(firstDfa, secondDfa); //Generate the dfa, starting with the start states (no really sherlock) GenerateCombinedDfa(combinedDfa, startStatesForDfa); //Set start states foreach (T startState in startStatesForDfa) { combinedDfa.DefineAsStartState(startState); } //And end state, for the and it is a combination. So if is is a F and E, G then the endstates should contain F and either E or G. //So generate the end state by combining them in the same way as the start states, and then check if the dfa has the state. List <T> endStates = new List <T>(); foreach (T firstEnd in firstDfa.FinalStates) { string firstAsString = firstEnd.ToString(); foreach (T secondEnd in secondDfa.FinalStates) { string secondAsString = secondEnd.ToString(); string newState = firstAsString + "-" + secondAsString; T newStateT = (T)Convert.ChangeType(newState, typeof(T)); endStates.Add(newStateT); } } foreach (T endState in endStates) { foreach (T state in combinedDfa.States) { if (state.Equals(endState)) { combinedDfa.DefineAsFinalState(endState); } } } return(combinedDfa); }
/// <summary> /// Minimize a dfa by using Brozozowski's algorithm /// </summary> /// <param name="dfaToMinimize">The dfa to minimize.</param> /// <returns>The minimal dfa.</returns> public Automata <T> MinimizeUsingBrzozowski(Automata <T> dfaToMinimize) { Automata <T> reversedDfa = mutator.ReverseDfa(dfaToMinimize); Automata <T> remappedDfa = RemapStates(reversedDfa); Automata <T> firstPassDfa = transformer.TransformNdfaIntoDfa(remappedDfa); Automata <T> reversedFirstPass = mutator.ReverseDfa(firstPassDfa); Automata <T> remappedPass = RemapStates(reversedFirstPass); Automata <T> minimalDfa = transformer.TransformNdfaIntoDfa(remappedPass); return(minimalDfa); }
/// <summary> /// Check to see if an dfa already contains a state. /// </summary> /// <param name="dfa">The dfa to check.</param> /// <param name="state">The state to search for.</param> /// <returns>A boolean that is true if the state has been found</returns> private bool DfaContainsStateCombinedDfa(Automata <T> dfa, T state) { bool dfaContainsState = false; foreach (T dfaState in dfa.States) { if (dfaState.Equals(state)) { dfaContainsState = true; break; } } return(dfaContainsState); }
private static void TestRegExAndThompson() { RegExpTest ret = new RegExpTest(); ret.testLanguage(); ret.testToString(); RegExp regExp1 = new RegExp("baa"); RegExp regExp2 = new RegExp("aba"); RegExp regExp3 = new RegExp("bb"); RegExp oneOrTwo = regExp1.Or(regExp2); RegExp orStar = oneOrTwo.Star(); RegExp orStarDotThree = orStar.Dot(regExp3); RegExp orStarDotThreePlus = orStarDotThree.Plus(); Console.WriteLine("-----------------------------------------"); Console.WriteLine("And conversion by use of the thompson construction:"); Console.WriteLine("-----------------------------------------"); ThompsonConstruction thompson = new ThompsonConstruction(); Automata <string> thompsonNDFA = thompson.GenerateNDFA(orStarDotThreePlus); Console.WriteLine("thompsonNDFA is dfa? " + thompsonNDFA.IsDfa()); Console.WriteLine("-----------------------------------------"); thompsonNDFA.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in thompsonNDFA.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in thompsonNDFA.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("String {0} is a {1} string for Auto3.", THOMPSON_TEST_1, thompsonNDFA.IsStringAcceptable(THOMPSON_TEST_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto3.", THOMPSON_TEST_2, thompsonNDFA.IsStringAcceptable(THOMPSON_TEST_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for Auto3.", THOMPSON_TEST_3, thompsonNDFA.IsStringAcceptable(THOMPSON_TEST_3) ? "valid" : "invalid"); Console.WriteLine("-----------------------------------------"); }
/// <summary> /// Sets up all start states for the combined dfa's /// </summary> /// <param name="firstDfa">The first dfa to use</param> /// <param name="secondDfa">The second dfa to use</param> private void SetStartStatesForAndOrOr(Automata <T> firstDfa, Automata <T> secondDfa) { List <T> startStates = new List <T>(); foreach (T firstState in firstDfa.StartStates) { string firstAsString = firstState.ToString(); foreach (T secondState in secondDfa.StartStates) { string secondAsString = secondState.ToString(); string newState = firstAsString + "-" + secondAsString; T newStateT = (T)Convert.ChangeType(newState, typeof(T)); startStates.Add(newStateT); } } startStatesForDfa = startStates; }
/// <summary> /// Maps all reachable states by their from state. This is the mapping process where A-A leads to A-B and B-A for example. /// </summary> /// <param name="firstDfa">The first dfa to use</param> /// <param name="secondDfa">The second dfa to use</param> private void MapReachableStatesForGivenDFA(Automata <T> firstDfa, Automata <T> secondDfa) { Dictionary <T, List <KeyValuePair <char, T> > > transtionMap = new Dictionary <T, List <KeyValuePair <char, T> > >(); IEnumerable <char> combinedSymbols = firstDfa.Symbols.Intersect(secondDfa.Symbols); foreach (T firstState in firstDfa.States) { string firstAsString = firstState.ToString(); foreach (T secondState in secondDfa.States) { string secondAsString = secondState.ToString(); string fromState = firstAsString + "-" + secondAsString; T fromStateT = (T)Convert.ChangeType(fromState, typeof(T)); List <KeyValuePair <char, T> > toStateBySymbol = new List <KeyValuePair <char, T> >(); foreach (char symbol in combinedSymbols) { //Both of these should be one transition due to one dfa, so using first is not a problem IEnumerable <Transition <T> > iFirstTransition = firstDfa.Transitions.Where(x => x.FromState.Equals(firstState) && x.Identifier == symbol); IEnumerable <Transition <T> > iSecondTransition = secondDfa.Transitions.Where(x => x.FromState.Equals(secondState) && x.Identifier == symbol); Transition <T> firstTransition = iFirstTransition.FirstOrDefault(); Transition <T> secondTransition = iSecondTransition.FirstOrDefault(); if (firstTransition == default(Transition <T>) || secondTransition == default(Transition <T>)) { throw new NullReferenceException("One of the transitions is it's default value."); } string toState = firstTransition.ToState.ToString() + "-" + secondTransition.ToState.ToString(); T toStateT = (T)Convert.ChangeType(toState, typeof(T)); toStateBySymbol.Add(new KeyValuePair <char, T>(symbol, toStateT)); } transtionMap.Add(fromStateT, toStateBySymbol); } } combinedTransitionsMap = transtionMap; }
/// <summary> /// Traverses the <see cref="Dictionary{TKey, TValue}"/> to generate a dfa. This recursively happen untill there are no more states to traverse. /// </summary> /// <param name="combinedDfa">The combined dfa, modified and passed every loop.</param> /// <param name="statesToTraverse">The next states to traverse.</param> private void GenerateCombinedDfa(Automata <T> combinedDfa, List <T> statesToTraverse) { List <T> statesToTraverseNext = new List <T>(); //Add all the new transitions to the combined dfa. foreach (T state in statesToTraverse) { List <KeyValuePair <char, T> > transitionsFromThisState = combinedTransitionsMap[state]; foreach (KeyValuePair <char, T> symbolAndToState in transitionsFromThisState) { if (DfaContainsStateCombinedDfa(combinedDfa, symbolAndToState.Value)) { combinedDfa.AddTransition(new Transition <T>(state, symbolAndToState.Value, symbolAndToState.Key)); continue; } //Skip this state if it is already in the dfa. But do add a transition if (state.Equals(symbolAndToState.Value)) { combinedDfa.AddTransition(new Transition <T>(state, symbolAndToState.Key)); } else { combinedDfa.AddTransition(new Transition <T>(state, symbolAndToState.Value, symbolAndToState.Key)); statesToTraverseNext.Add(symbolAndToState.Value); } } } //And a zero means that we have reached the end. if (statesToTraverseNext.Count <= 0) { return; } else { GenerateCombinedDfa(combinedDfa, statesToTraverseNext); } }
/// <summary> /// Turns the given <see cref="Automata{T}"/> ndfa into it's dfa. /// </summary> /// <param name="ndfaToTransform">the <see cref="Automata{T}"/> representing the ndfa</param> /// <returns>The <see cref="Automata{T}"/> dfa that can be build from the given ndfa</returns> public Automata <T> TransformNdfaIntoDfa(Automata <T> ndfaToTransform) { if (ndfaToTransform.IsDfa()) { Console.WriteLine("Given NDFA is actually a DFA."); return(ndfaToTransform); } ndfa = ndfaToTransform; //Determine the states to go to with a and b, including empty transitions. reachableStates = GetAllReachableStatesByFromState(); //Build the automata GenerateDFA(); //See if we actually have a DFA if (!dfa.IsDfa()) { Console.WriteLine("Diagram isn't a DFA."); return(new Automata <T>()); } return(dfa); }
/// <summary> /// Combines two <see cref="Automata{T}"/> into a single automata if they are both dfa's /// </summary> /// <param name="firstDfa">The first dfa to use</param> /// <param name="secondDfa">The other dfa to use</param> /// <returns>A dfa that consists that takes the conditions for both dfa's into account</returns> public Automata <T> CombinaAutomataOr(Automata <T> firstDfa, Automata <T> secondDfa) { if (!firstDfa.IsDfa() || !secondDfa.IsDfa()) { throw new ArgumentException("One of the given automata is not a dfa"); } IEnumerable <char> combinedAlphabet = firstDfa.Symbols.Union(secondDfa.Symbols); Automata <T> combinedDfa = new Automata <T>(combinedAlphabet.ToArray()); startStatesForDfa.Clear(); combinedTransitionsMap.Clear(); //Read the starting states SetStartStatesForAndOrOr(firstDfa, secondDfa); //Gather all states that follow MapReachableStatesForGivenDFA(firstDfa, secondDfa); //Generate the dfa, starting with the start states (no really sherlock) GenerateCombinedDfa(combinedDfa, startStatesForDfa); //Set start states foreach (T startState in startStatesForDfa) { combinedDfa.DefineAsStartState(startState); } //And end state, for the or it should contain one. So if is is a F and E, G then any state with a E, F or G is an end state. List <T> endStates = new List <T>(); endStates.AddRange(firstDfa.FinalStates); foreach (T state in secondDfa.FinalStates) { foreach (T endState in endStates) { if (!StatesAreEqual(state, endState)) { endStates.Add(state); break; } } } foreach (T state in combinedDfa.States) { string[] splitStates = state.ToString().Split('-'); List <T> separateStatesT = new List <T>(); foreach (string splitState in splitStates) { separateStatesT.Add((T)Convert.ChangeType(splitState, typeof(T))); } //Now check if any of the seperates states are in endStates (so if intersect leaves atleast one element) int elementsLeft = separateStatesT.Intersect(endStates).ToList().Count; if (elementsLeft > 0) { combinedDfa.DefineAsFinalState(state); } } return(combinedDfa); }
private static void TestMutationAndMinimalization() { Automata <string> L1 = TestAutomata.dfaMutationTestL1(); Automata <string> L4 = TestAutomata.dfaMutationTestL4(); Console.WriteLine("L1 is dfa? " + L1.IsDfa()); Console.WriteLine("-----------------------------------------"); L1.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in L1.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in L1.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("L4 is dfa? " + L4.IsDfa()); Console.WriteLine("-----------------------------------------"); L4.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in L4.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in L4.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); //Not L1 DfaMutation <string> dfaMutator = new DfaMutation <string>(); Automata <string> notL1 = dfaMutator.NotDfa(L1); foreach (string state in notL1.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in notL1.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); //Reverted L4 Automata <string> revertedL4 = dfaMutator.ReverseDfa(L4); Console.WriteLine("revertedL4 is dfa? " + revertedL4.IsDfa()); Console.WriteLine("-----------------------------------------"); revertedL4.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in revertedL4.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in revertedL4.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Automata <string> L1AndL4 = dfaMutator.CombineAutomataAnd(L1, L4); Console.WriteLine("L1AndL4 is dfa? " + L1AndL4.IsDfa()); Console.WriteLine("-----------------------------------------"); L1AndL4.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in L1AndL4.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in L1AndL4.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Automata <string> L1OrL4 = dfaMutator.CombinaAutomataOr(L1, L4); Console.WriteLine("L1OrL4 is dfa? " + L1OrL4.IsDfa()); Console.WriteLine("-----------------------------------------"); L1OrL4.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in L1OrL4.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in L1OrL4.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Minimizer <string> minimizer = new Minimizer <string>(); Automata <string> L1AndL4Minimal = minimizer.MinimizeUsingBrzozowski(L1AndL4); Console.WriteLine("L1AndL4Minimal is dfa? " + L1AndL4Minimal.IsDfa()); Console.WriteLine("-----------------------------------------"); L1AndL4Minimal.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in L1AndL4Minimal.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in L1AndL4Minimal.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); }
private static void TestNdfaToDfa() { Automata <string> testNdfa = TestAutomata.ndfaToDfaTest(); Console.WriteLine("testNdfa is dfa? " + testNdfa.IsDfa()); Console.WriteLine("-----------------------------------------"); testNdfa.PrintTransitions(); Console.WriteLine("-----------------------------------------"); Console.WriteLine("StartStatesIn NDFA: "); foreach (string startState in testNdfa.StartStates) { Console.WriteLine(startState); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("EndStates NDFA: "); foreach (string endState in testNdfa.FinalStates) { Console.WriteLine(endState); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_VALID_1, testNdfa.IsStringAcceptable(NDFA_TO_DFA_VALID_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_VALID_2, testNdfa.IsStringAcceptable(NDFA_TO_DFA_VALID_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_VALID_3, testNdfa.IsStringAcceptable(NDFA_TO_DFA_VALID_3) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_VALID_4, testNdfa.IsStringAcceptable(NDFA_TO_DFA_VALID_4) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_INVALID_1, testNdfa.IsStringAcceptable(NDFA_TO_DFA_INVALID_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_INVALID_2, testNdfa.IsStringAcceptable(NDFA_TO_DFA_INVALID_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfa.", NDFA_TO_DFA_INVALID_3, testNdfa.IsStringAcceptable(NDFA_TO_DFA_INVALID_3) ? "valid" : "invalid"); Console.WriteLine("-----------------------------------------"); NdfaToDfa <string> converter = new NdfaToDfa <string>(); Automata <string> testNdfaDFA = converter.TransformNdfaIntoDfa(testNdfa); Console.WriteLine("testNdfaDFA is dfa? " + testNdfaDFA.IsDfa()); Console.WriteLine("-----------------------------------------"); testNdfaDFA.PrintTransitions(); Console.WriteLine("-----------------------------------------"); foreach (string state in testNdfaDFA.StartStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); foreach (string state in testNdfaDFA.FinalStates) { Console.WriteLine(state); } Console.WriteLine("-----------------------------------------"); Console.WriteLine("And the same strings as befor in the DFA:"); Console.WriteLine(); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_VALID_1, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_VALID_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_VALID_2, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_VALID_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_VALID_3, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_VALID_3) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_VALID_4, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_VALID_4) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_INVALID_1, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_INVALID_1) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_INVALID_2, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_INVALID_2) ? "valid" : "invalid"); Console.WriteLine("String {0} is a {1} string for testNdfaDFA.", NDFA_TO_DFA_INVALID_3, testNdfaDFA.IsStringAcceptable(NDFA_TO_DFA_INVALID_3) ? "valid" : "invalid"); Console.WriteLine("-----------------------------------------"); }