예제 #1
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);
        }
예제 #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);
        }
예제 #3
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();
        }
예제 #4
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);
        }
        /// <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);
        }
        /// <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);
        }
        /// <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);
            }
        }
예제 #8
0
        static public Automata <String> ndfaToDfaTest()
        {
            char[]            alphabet = { 'a', 'b' };
            Automata <String> automata = new Automata <String>(alphabet);

            automata.AddTransition(new Transition <string>("A", "B", 'a'));
            automata.AddTransition(new Transition <string>("A", "C", 'b'));
            automata.AddTransition(new Transition <string>("B", "D", 'a'));
            automata.AddTransition(new Transition <string>("C", "B", 'b'));
            automata.AddTransition(new Transition <string>("C", "D"));
            automata.AddTransition(new Transition <string>("D", "A", 'b'));
            automata.AddTransition(new Transition <string>("D", "E", 'a'));
            automata.AddTransition(new Transition <string>("E", "C"));
            automata.AddTransition(new Transition <string>("E", "F", 'a'));

            automata.DefineAsStartState("A");
            automata.DefineAsFinalState("F");

            return(automata);
        }
예제 #9
0
        /// <summary>
        /// Uses the given dictionary and the given list of states to get more transitions
        /// </summary>
        /// <param name="statesToLoopThrough">The states to loop through</param>
        /// <returns></returns>
        private void GenerateOtherTransitions(HashSet <T> statesToLoopThrough)
        {
            List <Transition <T> > transitions          = new List <Transition <T> >();
            HashSet <T>            statesToTraverseNext = new HashSet <T>();

            foreach (T currentStateLoopingThrough in statesToLoopThrough)
            {
                if (currentStateLoopingThrough.Equals(emptyStateT))
                {
                    foreach (char symbol in ndfa.Symbols)
                    {
                        transitions.Add(new Transition <T>(emptyStateT, symbol));
                    }
                    continue;
                }

                //For the state (which may be a composite) get all single states
                string[] splitStates  = currentStateLoopingThrough.ToString().Split('-');
                List <T> splitStatesT = new List <T>(); //List of all states contained in this state
                foreach (string stateAsString in splitStates)
                {
                    T stateT = (T)Convert.ChangeType(stateAsString, typeof(T));
                    splitStatesT.Add(stateT);
                }

                foreach (char symbol in ndfa.Symbols)
                {
                    HashSet <T> reachableStatesWithThisSymbol = new HashSet <T>();
                    foreach (T stateToLookFor in splitStatesT)
                    {
                        //Then gather all states this can go to
                        HashSet <T> statesReachedByGivenState = reachableStates[stateToLookFor].Find(x => x.Key == symbol).Value; //Find the states reached with this state-symbol combination
                        foreach (T foundState in statesReachedByGivenState)
                        {
                            reachableStatesWithThisSymbol.Add(foundState);
                        }
                    }

                    //For which the collection forms a single to state
                    StringBuilder toState = new StringBuilder();
                    if (reachableStatesWithThisSymbol.Count == 0)
                    {
                        toState.Append("$");
                    }                                                                     //Create the empty to state
                    else
                    {
                        foreach (T reachableState in reachableStatesWithThisSymbol)
                        {
                            //Append to the string
                            toState.Append(reachableState.ToString() + '-');
                        }

                        //And remove last
                        toState.Remove(toState.Length - 1, 1);
                    }

                    T toStateT = (T)Convert.ChangeType(toState.ToString(), typeof(T));

                    if (StatesAreEqual(currentStateLoopingThrough, toStateT))
                    {
                        //Should the toState and the current state be equal, we can point to ourself
                        transitions.Add(new Transition <T>(currentStateLoopingThrough, symbol));
                    }
                    else
                    {
                        //Which then gives us the transition of:
                        //state as the from state,
                        //The collection as the to state
                        //And the symbol as the identifier
                        statesToTraverseNext.Add(toStateT);
                        transitions.Add(new Transition <T>(currentStateLoopingThrough, toStateT, symbol));
                    }
                }
            }

            foreach (Transition <T> transition in transitions)
            {
                dfa.AddTransition(transition);
            }

            //Check if there still are states left to traverse, which we haven't traversed yet
            HashSet <T> statesAlreadyTraversed = new HashSet <T>();

            foreach (Transition <T> transition in dfa.Transitions)
            {
                statesAlreadyTraversed.Add(transition.FromState);
            }

            //Quick filter all states that happen to be the exact same (for example, C-D-E might be in the to traverse and the already traversed as the same string)
            statesToTraverseNext = new HashSet <T>(statesToTraverseNext.Except(statesAlreadyTraversed));

            //Since this method adds states anyway, only continue if we still need to traverse states.
            if (statesToTraverseNext.Count > 0)
            {
                GenerateOtherTransitions(statesToTraverseNext);
            }
        }
예제 #10
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);
        }
예제 #11
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);
        }