예제 #1
0
            public void CountsOnlyOneFinal()
            {
                var m1Start = new GraphState () {
                    IsFinal = true
                };
                var secondFinal = new GraphState () {
                    IsFinal = true
                };
                var thirdFinal = new GraphState () {
                    IsFinal = true
                };
                var m1 = new Graph () {
                    StartState = m1Start
                };

                var epsilonConnection1 = new GraphStateConnection {
                    Start = m1Start,
                    End = secondFinal,
                    ConnectedBy = Word.Epsilon
                };

                var epsilonConnection2 = new GraphStateConnection {
                    Start = secondFinal,
                    End = thirdFinal,
                    ConnectedBy = Word.Epsilon
                };

                m1.StartState.Out.Add (epsilonConnection1);
                secondFinal.Out.Add (epsilonConnection2);

                var finals = m1.FindFinalStates (m1.StartState);
                finals.Count.Should ().Be (3);
            }
예제 #2
0
        /// <summary>
        /// Performs the Union on two NDFA's. 
        /// </summary>
        /// <param name="m2">The NDFA to Union with.</param>
        /// <returns>>A new NDFA that is the union of the two graphs.</returns>
        public Graph Union(Graph m2)
        {
            var m = new Graph ();
            var m1 = this;

            //new start state
            m.StartState = new GraphState ();

            //new q0
            var newFinalState = new GraphState () {
                IsFinal = true
            };

            //connection from q0 to q1 over epsilon
            var q0Toq1 = new GraphStateConnection () {
                ConnectedBy = Word.Epsilon,
                Start = m.StartState,
                End = m1.StartState
            };

            //connection from q0 to q2
            var q0Toq2 = new GraphStateConnection () {
                ConnectedBy = Word.Epsilon,
                Start = m.StartState,
                End = m2.StartState
            };

            //attach states.
            m.StartState.Out.Add (q0Toq1);
            m.StartState.Out.Add (q0Toq2);

            var m1Finals = FindFinalStates (m1.StartState);
            var m2Finals = FindFinalStates (m2.StartState);

            foreach (var final in m1Finals) {
                final.IsFinal = false;
                var finalConnection = new GraphStateConnection () {
                    Start = final,
                    End = newFinalState,
                    ConnectedBy = Word.Epsilon
                };
                final.Out.Add (finalConnection);
            }

            foreach (var final in m2Finals) {
                final.IsFinal = false;
                var finalConnection = new GraphStateConnection () {
                    Start = final,
                    End = newFinalState,
                    ConnectedBy = Word.Epsilon
                };
                final.Out.Add (finalConnection);
            }

            //update the total state count
            m.StateCount = m1.StateCount + m2.StateCount + 2;
            if (updateStateNumber) {
                RenumberStates (m.StartState);
            }
            return m;
        }
예제 #3
0
        /// <summary>
        /// Concatinates two NDFA's.
        /// </summary>
        /// <param name="m1">The second NDFA to concatinate with.</param>
        /// <returns>The new graph that is this and m1 concatinated.</returns>
        public Graph Concat(Graph m1)
        {
            var m = new Graph ();
            var m2 = this;

            var m1FinalStates = m1.FindFinalStates (m1.StartState);

            foreach (var finalState in m1FinalStates) {
                //create a new connection to m2 initial state
                var m1FinalTom2Initial = new GraphStateConnection () {
                    Start = finalState,
                    End = m2.StartState,
                    ConnectedBy =
                        Word.Epsilon
                };

                //make the connection
                finalState.Out.Add (m1FinalTom2Initial);

                //kill m1 final states and leave m2 as finals for m
                finalState.IsFinal = false;
            }

            //update state count for new graph
            m.StartState = m1.StartState;
            m.StateCount = m1.StateCount + m2.StateCount;
            if (updateStateNumber) {
                RenumberStates (m.StartState);
            }
            return m;
        }
예제 #4
0
        /// <summary>
        /// Perfoms a Kleene operation on the graph.
        /// </summary>
        /// <returns>The new graph after the Kleene operation.</returns>
        public Graph Kleene()
        {
            var m = new Graph ();
            var m1 = this;

            var finals = FindFinalStates (m1.StartState);
            var oldInitial = m1.StartState;

            //create new init and final state.
            var newInitial = new GraphState (){
                IsFinal = true,
                StateNumber = m1.StateCount + 1
            };

            //create connection from new initial to the old initial through epsilon
            var initialEpsilonConnection = new GraphStateConnection {
                End = oldInitial,
                Start = newInitial,
                ConnectedBy = Word.Epsilon
            };

            //add the connection to the states.
            newInitial.Out.Add (initialEpsilonConnection);

            foreach (var finalState in finals) {
                //now create epsilon connections from final to original start state
                var finalToOldInitialConnection = new GraphStateConnection {
                    End = newInitial,
                    Start = finalState,
                    ConnectedBy = Word.Epsilon
                };

                finalState.IsFinal = false;

                //now connect them
                finalState.Out.Add(finalToOldInitialConnection);
            }

            //now attach the new init state to the graph
            m.StartState = newInitial;
            m.StateCount = m1.StateCount + 1;
            return m;
        }