static void Main()
        {
            Console.WriteLine("1. DFSA 'A' Generation.");
            DFSadj dfsA = new DFSadj();

            Console.WriteLine("\n2. Depth of DFSA 'A'.");
            Console.WriteLine("  - Number of States in 'A': " + dfsA.states.Count);
            Console.WriteLine("  - Depth of 'A': " + dfsA.GetDepth());

            Console.WriteLine("\n3. DFSA 'A' Minimisation.");
            DFSadj dfsM = dfsA.GetMinimalDFSadj();

            Console.WriteLine("\n4. Depth of DFSA 'M'.");
            Console.WriteLine("  - Number of States in 'M': " + dfsM.states.Count);
            Console.WriteLine("  - Depth of 'M': " + dfsM.GetDepth());

            Console.WriteLine("\n5. Generating 100 random strings [Accept/Reject]");


            Console.WriteLine("\n6. Strongly Connected Components in DFSA 'M':");
            dfsM.GetSCCs();
            Console.WriteLine("  - Number of Strongly Connected Components in 'M': " + dfsM.SCCs.Count);
            dfsM.MaxminCC();
            Console.WriteLine("  - Number of States in the largest SCC: " + dfsM.maxSCC);
            Console.WriteLine("  - Number of States in the smallest SCC: " + dfsM.minSCC);
        }
Example #2
0
        public DFSadj GetMinimalDFSadj()
        {
            //States are divided into accepting states and rejecting states
            HashSet <int> acceptingStates = new HashSet <int>();
            HashSet <int> rejectingStates = new HashSet <int>();

            foreach (State state in states)
            {
                // If the current state could be reached
                if (adjState[state.stateID])
                {
                    // Current state = accepting state
                    if (state.finalState)
                    {
                        // Added int the set of accepting states.
                        acceptingStates.Add(state.stateID);
                    }
                    else
                    {
                        // Else it's added in the set of rejecting states
                        rejectingStates.Add(state.stateID);
                    }
                }
            }

            // The hashsetP := {F, Q \ F}
            HashSet <HashSet <int> > hashSetP = new HashSet <HashSet <int> >(HashSet <int> .CreateSetComparer());

            hashSetP.Add(acceptingStates);
            hashSetP.Add(rejectingStates);

            // The hashsetW := {F}
            HashSet <HashSet <int> > hashSetW = new HashSet <HashSet <int> >(HashSet <int> .CreateSetComparer());

            hashSetW.Add(acceptingStates);

            // whilst hashSetW is not empty
            while (hashSetW.Count != 0)
            {
                // a hashset A is removed from hashset W
                HashSet <int> hashSetA = hashSetW.ElementAt(0);
                hashSetW.Remove(hashSetA);

                // for each c in Σ do
                for (int ii = 0; ii < adj.GetLength(1); ii++)
                {
                    // All the transitions c which lead to state a, are stored in hashset X
                    HashSet <int> hashSetX = new HashSet <int>();
                    foreach (State state in states)
                    {
                        if (adjState[state.stateID])
                        {
                            if (hashSetA.Contains(adj[state.stateID, ii]))
                            {
                                hashSetX.Add(state.stateID);
                            }
                        }
                    }

                    // When X Intercetion Y and Y set difference X is non empty, in P is hashsetY.
                    HashSet <HashSet <int> > Pcopy = new HashSet <HashSet <int> >(hashSetP, HashSet <int> .CreateSetComparer());
                    foreach (HashSet <int> setInP in Pcopy)
                    {
                        HashSet <int> hashSetY = new HashSet <int>(setInP);

                        HashSet <int> intersection = new HashSet <int>(hashSetX);
                        intersection.IntersectWith(hashSetY);

                        HashSet <int> difference = new HashSet <int>(hashSetY);
                        difference.ExceptWith(hashSetX);

                        if (intersection.Count > 0 && difference.Count > 0)
                        {
                            // hashsetY is replaced in hashsetp by the 2 sets:  X ∩ Y & Y \ X
                            hashSetP.Remove(hashSetY);
                            hashSetP.Add(intersection);
                            hashSetP.Add(difference);

                            // if hashsetY is in hashetW
                            if (hashSetW.Contains(hashSetY))
                            {
                                // hashsetY is replaced in hashsetW by the 2 sets:  X ∩ Y & Y \ X
                                hashSetW.Remove(hashSetY);
                                hashSetW.Add(intersection);
                                hashSetW.Add(difference);
                            }
                            else
                            {
                                // else
                                // if |X ∩ Y| <= |Y \ X|
                                if (intersection.Count <= difference.Count)
                                {
                                    // X ∩ Y is added to hashsetW
                                    hashSetW.Add(intersection);
                                }
                                else
                                {
                                    // else
                                    // Y \ X is added to hashsetW
                                    hashSetW.Add(difference);
                                }
                            }
                        }
                    }
                }
            }

            // DFSadj M
            DFSadj dfsaM = new DFSadj(hashSetP.Count);

            // So that the elements have a fixed order, the hashsetP was changed into a list.
            List <HashSet <int> > arrayP = new List <HashSet <int> >(hashSetP);

            // Iterating throughout the list P
            int i = 0;

            for (int k = 0; k < arrayP.Count; k++)
            {
                HashSet <int> setInP = arrayP[k];
                // A new state is cleared for each element
                State state = new State();

                // An id is assigned to the state
                state.stateID = i;

                // if the start state of DFSadj A is contained
                if (setInP.Contains(startStateID))
                {
                    // the state is set as start state in DFSadj M
                    dfsaM.startStateID = i;
                }

                // if the states are final states, the set represting the partion
                // is set as an accepting state
                // Else, the state is set as a rejecting state.
                if (setInP.Count > 0 && states[0].finalState)
                {
                    state.finalState = true;
                }
                else
                {
                    state.finalState = false;
                }

                // the states in this partition of DFSadj A, are checked were they go to.
                int oldA = -1, oldB = -1;
                for (int j = 0; j < states.Count; j++)
                {
                    // When the state is found, the transitions are stored.
                    if (setInP.Contains(states[j].stateID))
                    {
                        oldA = adj[j, 0];
                        oldB = adj[j, 1];
                        break;
                    }
                }

                // when it is known which states a and b lead to in DFSadj A, make these transitions to show where transitions a and be had led to, from the current state.
                for (int j = 0; j < arrayP.Count; j++)
                {
                    if (arrayP[j].Contains(oldA))
                    {
                        dfsaM.adj[i, 0] = j;
                    }

                    if (arrayP[j].Contains(oldB))
                    {
                        dfsaM.adj[i, 1] = j;
                    }
                }

                dfsaM.states.Add(state);

                i++;
            }

            return(dfsaM);
        }