Advertisement
kartikkukreja

NFA to DFA conversion

Apr 18th, 2013
3,983
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.10 KB | None | 0 0
  1. /*
  2.  * Author : Kartik Kukreja
  3.  * Description :    Program to convert a given NFA to the corresponding DFA.
  4.             It reads in the NFA from "NFA.txt" and writes out the corresponding DFA to "DFA.txt".
  5.  
  6.             "NFA.txt" must have the following format:
  7.                 N M
  8.                 F a1 a2 ... af
  9.                 T
  10.                 s1 y1 T1 t1 t2 ... tt1
  11.                 s2 y2 T2 t1 t2 ... tt2
  12.                  :
  13.                  :
  14.             Here,   N -> No. of states (states are numbered 0 ... N-1), 0 is the start state
  15.                 M -> Size of input alphabet (input symbols are
  16.                     numbered 1 ... M and 0 is reserved for epsilon)
  17.                 F -> No. of final states, followed by F states ( 0 <= ai <= N-1)
  18.                 T -> No. of transitions, followed by T lines
  19.                 si -> Previous state ( 0 <= si <= N-1)
  20.                 yi -> Input symbol or epsilon ( 0 <= yi <= M)
  21.                 Ti -> No. of states the NFA moves from si on input yi, followed by Ti states
  22.  
  23.             "DFA.txt" will have the following format:
  24.                 N M
  25.                 F a1 a2 ... af
  26.                 s1 y1 t1
  27.                 s2 y2 y2
  28.                 :
  29.                 :
  30.             Here,   N -> No. of states in the DFA (states are numbered 0 ... N-1), 0 is the start state
  31.                 M -> Size of input alphabet (input symbols are numbered 1 ... M)
  32.                 F -> No. of final states followed by F states ( 0 <= ai <= N-1)
  33.                 si -> Previous state
  34.                 yi -> Input symbol
  35.                 ti -> Next state
  36.             Each line until the end of file contains one transition ( si yi ti )
  37.  */
  38.  
  39.  
  40. #include <cstdio>
  41. #include <fstream>
  42. #include <iostream>
  43. #include <bitset>
  44. #include <vector>
  45. #include <cstring>
  46. #include <cstdlib>
  47. #include <algorithm>
  48. #include <queue>
  49. #include <set>
  50. #define MAX_NFA_STATES 10
  51. #define MAX_ALPHABET_SIZE 10
  52. using namespace std;
  53.  
  54. // Representation of an NFA state
  55. class NFAstate {
  56.     public:
  57.         int transitions[MAX_ALPHABET_SIZE][MAX_NFA_STATES];
  58.         NFAstate()  {
  59.             for(int i=0; i<MAX_ALPHABET_SIZE; i++)
  60.                 for(int j=0; j<MAX_NFA_STATES; j++)
  61.                     transitions[i][j] = -1;
  62.         }
  63. } *NFAstates;
  64.  
  65. // Representation of a DFA state
  66. struct DFAstate {
  67.     bool finalState;
  68.     bitset<MAX_NFA_STATES> constituentNFAstates;
  69.     bitset<MAX_NFA_STATES> transitions[MAX_ALPHABET_SIZE];
  70.     int symbolicTransitions[MAX_ALPHABET_SIZE];
  71. };
  72.  
  73. set <int> NFA_finalStates;
  74. vector <int> DFA_finalStates;
  75. vector <DFAstate*> DFAstates;
  76. queue <int> incompleteDFAstates;
  77. int N, M;   // N -> No. of stattes, M -> Size of input alphabet
  78.  
  79. // finds the epsilon closure of the NFA state "state" and stores it into "closure"
  80. void epsilonClosure(int state, bitset<MAX_NFA_STATES> &closure )    {
  81.     for(int i=0; i<N && NFAstates[state].transitions[0][i] != -1; i++)
  82.         if(closure[NFAstates[state].transitions[0][i]] == 0)    {
  83.             closure[NFAstates[state].transitions[0][i]] = 1;
  84.             epsilonClosure(NFAstates[state].transitions[0][i], closure);
  85.         }
  86. }
  87.  
  88. // finds the epsilon closure of a set of NFA states "state" and stores it into "closure"
  89. void epsilonClosure(bitset<MAX_NFA_STATES> state, bitset<MAX_NFA_STATES> &closure) {
  90.     for(int i=0; i<N; i++)
  91.         if(state[i] == 1)
  92.             epsilonClosure(i, closure);
  93. }
  94.  
  95. // returns a bitset representing the set of states the NFA could be in after moving
  96. // from state X on input symbol A
  97. void NFAmove(int X, int A, bitset<MAX_NFA_STATES> &Y)   {
  98.     for(int i=0; i<N && NFAstates[X].transitions[A][i] != -1; i++)
  99.         Y[NFAstates[X].transitions[A][i]] = 1;
  100. }
  101.  
  102. // returns a bitset representing the set of states the NFA could be in after moving
  103. // from the set of states X on input symbol A
  104. void NFAmove(bitset<MAX_NFA_STATES> X, int A, bitset<MAX_NFA_STATES> &Y)   {
  105.     for(int i=0; i<N; i++)
  106.         if(X[i] == 1)
  107.             NFAmove(i, A, Y);
  108. }
  109.  
  110. int main()  {
  111.     int i, j, X, Y, A, T, F, D;
  112.  
  113.     // read in the underlying NFA
  114.     ifstream fin("NFA.txt");
  115.     fin >> N >> M;
  116.     NFAstates = new NFAstate[N];
  117.     fin >> F;
  118.     for(i=0; i<F; i++)    {
  119.         fin >> X;
  120.         NFA_finalStates.insert(X);
  121.     }
  122.     fin >> T;
  123.     while(T--)   {
  124.         fin >> X >> A >> Y;
  125.         for(i=0; i<Y; i++)  {
  126.             fin >> j;
  127.             NFAstates[X].transitions[A][i] = j;
  128.         }
  129.     }
  130.     fin.close();
  131.  
  132.     // construct the corresponding DFA
  133.     D = 1;
  134.     DFAstates.push_back(new DFAstate);
  135.     DFAstates[0]->constituentNFAstates[0] = 1;
  136.     epsilonClosure(0, DFAstates[0]->constituentNFAstates);
  137.     for(j=0; j<N; j++)
  138.         if(DFAstates[0]->constituentNFAstates[j] == 1 && NFA_finalStates.find(j) != NFA_finalStates.end())  {
  139.             DFAstates[0]->finalState = true; DFA_finalStates.push_back(0); break;
  140.         }
  141.     incompleteDFAstates.push(0);
  142.     while(!incompleteDFAstates.empty()) {
  143.         X = incompleteDFAstates.front(); incompleteDFAstates.pop();
  144.         for(i=1; i<=M; i++)  {
  145.             NFAmove(DFAstates[X]->constituentNFAstates, i, DFAstates[X]->transitions[i]);
  146.             epsilonClosure(DFAstates[X]->transitions[i], DFAstates[X]->transitions[i]);
  147.             for(j=0; j<D; j++)
  148.                 if(DFAstates[X]->transitions[i] == DFAstates[j]->constituentNFAstates)  {
  149.                    DFAstates[X]->symbolicTransitions[i] = j;    break;
  150.                 }
  151.             if(j == D)   {
  152.                 DFAstates[X]->symbolicTransitions[i] = D;
  153.                 DFAstates.push_back(new DFAstate);
  154.                 DFAstates[D]->constituentNFAstates = DFAstates[X]->transitions[i];
  155.                 for(j=0; j<N; j++)
  156.                     if(DFAstates[D]->constituentNFAstates[j] == 1 && NFA_finalStates.find(j) != NFA_finalStates.end())  {
  157.                         DFAstates[D]->finalState = true; DFA_finalStates.push_back(D); break;
  158.                     }
  159.                 incompleteDFAstates.push(D);
  160.                 D++;
  161.             }
  162.         }
  163.     }
  164.  
  165.     // write out the corresponding DFA
  166.     ofstream fout("DFA.txt");
  167.     fout << D << " " << M << "\n" << DFA_finalStates.size();
  168.     for(vector<int>::iterator it=DFA_finalStates.begin(); it!=DFA_finalStates.end(); it++)
  169.         fout << " " << *it;
  170.     fout << "\n";
  171.     for(i=0; i<D; i++)  {
  172.         for(j=1; j<=M; j++)
  173.             fout << i << " " << j << " " << DFAstates[i]->symbolicTransitions[j] << "\n";
  174.     }
  175.     fout.close();
  176.  
  177.     return 0;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement