Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }
Example #5
0
        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("-----------------------------------------");
        }
Example #6
0
        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("}");
            }
        }
Example #9
0
        /// <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);
        }
Example #10
0
        /// <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();
        }
Example #11
0
        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);
        }
Example #13
0
        /// <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);
        }
Example #15
0
        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);
            }
        }
Example #19
0
        /// <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);
        }
Example #21
0
        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("-----------------------------------------");
        }
Example #22
0
        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("-----------------------------------------");
        }