📄 dfa.java
字号:
int last = l_backward[anchorL]; l_forward[last] = index; l_forward[index] = anchorL; l_backward[index] = last; l_backward[anchorL] = index; index++; } } B_i++; } // end of setup L // start of "real" algorithm // int step = 0; // System.out.println("max_steps = "+(n*numInput)); // while L not empty while (l_forward[anchorL] != anchorL) { // System.out.println("step : "+(step++)); // printL(l_forward, l_backward, anchorL); // pick and delete (B_j, a) in L: // pick int B_j_a = l_forward[anchorL]; // delete l_forward[anchorL] = l_forward[B_j_a]; l_backward[l_forward[anchorL]] = anchorL; l_forward[B_j_a] = 0; // take B_j_a = (B_j-b0)*numInput+c apart into (B_j, a) int B_j = b0 + B_j_a / numInput; int a = B_j_a % numInput; // printL(l_forward, l_backward, anchorL); // System.out.println("picked ("+B_j+","+a+")"); // printL(l_forward, l_backward, anchorL); // determine splittings of all blocks wrt (B_j, a) // i.e. D = inv_delta(B_j,a) numD = 0; int s = b_forward[B_j]; while (s != B_j) { // System.out.println("splitting wrt. state "+s); int t = inv_delta[s][a]; // System.out.println("inv_delta chunk "+t); while (inv_delta_set[t] != -1) { // System.out.println("D+= state "+inv_delta_set[t]); D[numD++] = inv_delta_set[t++]; } s = b_forward[s]; } // clear the twin list numSplit = 0; // System.out.println("splitting blocks according to D"); // clear SD and twins (only those B_i that occur in D) for (int indexD = 0; indexD < numD; indexD++) { // for each s in D s = D[indexD]; B_i = block[s]; SD[B_i] = -1; twin[B_i] = 0; } // count how many states of each B_i occurring in D go with a into B_j // Actually we only check, if *all* t in B_i go with a into B_j. // In this case SD[B_i] == block[B_i] will hold. for (int indexD = 0; indexD < numD; indexD++) { // for each s in D s = D[indexD]; B_i = block[s]; // only count, if we haven't checked this block already if (SD[B_i] < 0) { SD[B_i] = 0; int t = b_forward[B_i]; while (t != B_i && (t != 0 || block[0] == B_j) && (t == 0 || block[table[t-1][a]+1] == B_j)) { SD[B_i]++; t = b_forward[t]; } } } // split each block according to D for (int indexD = 0; indexD < numD; indexD++) { // for each s in D s = D[indexD]; B_i = block[s]; // System.out.println("checking if block "+(B_i-b0)+" must be split because of state "+s); if (SD[B_i] != block[B_i]) { // System.out.println("state "+(s-1)+" must be moved"); int B_k = twin[B_i]; if (B_k == 0) { // no twin for B_i yet -> generate new block B_k, make it B_i's twin B_k = ++lastBlock; // System.out.println("creating block "+(B_k-n)); // printBlocks(block,b_forward,b_backward,lastBlock-1); b_forward[B_k] = B_k; b_backward[B_k] = B_k; twin[B_i] = B_k; // mark B_i as split twin[numSplit++] = B_i; } // move s from B_i to B_k // remove s from B_i b_forward[b_backward[s]] = b_forward[s]; b_backward[b_forward[s]] = b_backward[s]; // add s to B_k int last = b_backward[B_k]; b_forward[last] = s; b_forward[s] = B_k; b_backward[s] = last; b_backward[B_k] = s; block[s] = B_k; block[B_k]++; block[B_i]--; SD[B_i]--; // there is now one state less in B_i that goes with a into B_j // printBlocks(block, b_forward, b_backward, lastBlock); // System.out.println("finished move"); } } // of block splitting // printBlocks(block, b_forward, b_backward, lastBlock); // System.out.println("updating L"); // update L for (int indexTwin = 0; indexTwin < numSplit; indexTwin++) { B_i = twin[indexTwin]; int B_k = twin[B_i]; for (int c = 0; c < numInput; c++) { int B_i_c = (B_i-b0)*numInput+c; int B_k_c = (B_k-b0)*numInput+c; if (l_forward[B_i_c] > 0) { // (B_i,c) already in L --> put (B_k,c) in L int last = l_backward[anchorL]; l_backward[anchorL] = B_k_c; l_forward[last] = B_k_c; l_backward[B_k_c] = last; l_forward[B_k_c] = anchorL; } else { // put the smaller block in L if (block[B_i] <= block[B_k]) { int last = l_backward[anchorL]; l_backward[anchorL] = B_i_c; l_forward[last] = B_i_c; l_backward[B_i_c] = last; l_forward[B_i_c] = anchorL; } else { int last = l_backward[anchorL]; l_backward[anchorL] = B_k_c; l_forward[last] = B_k_c; l_backward[B_k_c] = last; l_forward[B_k_c] = anchorL; } } } } } // System.out.println("Result"); // printBlocks(block,b_forward,b_backward,lastBlock); /* System.out.println("Old minimization:"); boolean [] [] equiv = old_minimize(); boolean error = false; for (int i = 1; i < equiv.length; i++) { for (int j = 0; j < equiv[i].length; j++) { if (equiv[i][j] != (block[i+1] == block[j+1])) { System.out.println("error: equiv["+i+"]["+j+"] = "+equiv[i][j]+ ", block["+i+"] = "+block[i+1]+", block["+j+"] = "+block[j]); error = true; } } } if (error) System.exit(1); System.out.println("check"); */ // transform the transition table // trans[i] is the state j that will replace state i, i.e. // states i and j are equivalent int trans [] = new int [numStates]; // kill[i] is true iff state i is redundant and can be removed boolean kill [] = new boolean [numStates]; // move[i] is the amount line i has to be moved in the transition table // (because states j < i have been removed) int move [] = new int [numStates]; // fill arrays trans[] and kill[] (in O(n)) for (int b = b0+1; b <= lastBlock; b++) { // b0 contains the error state // get the state with smallest value in current block int s = b_forward[b]; int min_s = s; // there are no empty blocks! for (; s != b; s = b_forward[s]) if (min_s > s) min_s = s; // now fill trans[] and kill[] for this block // (and translate states back to partial DFA) min_s--; for (s = b_forward[b]-1; s != b-1; s = b_forward[s+1]-1) { trans[s] = min_s; kill[s] = s != min_s; } } // fill array move[] (in O(n)) int amount = 0; for (int i = 0; i < numStates; i++) { if ( kill[i] ) amount++; else move[i] = amount; } int i,j; // j is the index in the new transition table // the transition table is transformed in place (in O(c n)) for (i = 0, j = 0; i < numStates; i++) { // we only copy lines that have not been removed if ( !kill[i] ) { // translate the target states for (int c = 0; c < numInput; c++) { if ( table[i][c] >= 0 ) { table[j][c] = trans[ table[i][c] ]; table[j][c]-= move[ table[j][c] ]; } else { table[j][c] = table[i][c]; } } isFinal[j] = isFinal[i]; action[j] = action[i]; j++; } } numStates = j; // translate lexical states for (i = 0; i < entryState.length; i++) { entryState[i] = trans[ entryState[i] ]; entryState[i]-= move[ entryState[i] ]; } Out.println(numStates+" states in minimized DFA"); } public String toString(int [] a) { String r = "{"; int i; for (i = 0; i < a.length-1; i++) r += a[i]+","; return r+a[i]+"}"; } public void printBlocks(int [] b, int [] b_f, int [] b_b, int last) { Out.dump("block : "+toString(b)); Out.dump("b_forward : "+toString(b_f)); Out.dump("b_backward: "+toString(b_b)); Out.dump("lastBlock : "+last); final int n = numStates+1; for (int i = n; i <= last; i ++) { Out.dump("Block "+(i-n)+" (size "+b[i]+"):"); String line = "{"; int s = b_f[i]; while (s != i) { line = line+(s-1); int t = s; s = b_f[s]; if (s != i) { line = line+","; if (b[s] != i) Out.dump("consistency error for state "+(s-1)+" (block "+b[s]+")"); } if (b_b[s] != t) Out.dump("consistency error for b_back in state "+(s-1)+" (back = "+b_b[s]+", should be = "+t+")"); } Out.dump(line+"}"); } } public void printL(int [] l_f, int [] l_b, int anchor) { String l = "L = {"; int bc = l_f[anchor]; while (bc != anchor) { int b = bc / numInput; int c = bc % numInput; l+= "("+b+","+c+")"; int old_bc = bc; bc = l_f[bc]; if (bc != anchor) l+= ","; if (l_b[bc] != old_bc) Out.dump("consistency error for ("+b+","+c+")"); } Out.dump(l+"}"); } /** * Much simpler, but slower and less memory efficient minimization algorithm. * * @return the equivalence relation on states. */ public boolean [] [] old_minimize() { int i,j; char c; Out.print(numStates+" states before minimization, "); if (numStates == 0) { Out.error(ErrorMessages.ZERO_STATES); throw new GeneratorException(); } if (Options.no_minimize) { Out.println("minimization skipped."); return null; } // equiv[i][j] == true <=> state i and state j are equivalent boolean [] [] equiv = new boolean [numStates] []; // list[i][j] contains all pairs of states that have to be marked "not equivalent" // if states i and j are recognized to be not equivalent StatePairList [] [] list = new StatePairList [numStates] []; // construct a triangular matrix equiv[i][j] with j < i // and mark pairs (final state, not final state) as not equivalent for (i = 1; i < numStates; i++) { list[i] = new StatePairList[i]; equiv[i] = new boolean [i]; for (j = 0; j < i; j++) { // i and j are equivalent, iff : // i and j are both final and their actions are equivalent and have same pushback behaviour or // i and j are both not final if ( isFinal[i] && isFinal[j] ) equiv[i][j] = action[i].isEquiv(action[j]); else equiv[i][j] = !isFinal[j] && !isFinal[i]; } } for (i = 1; i < numStates; i++) { Out.debug("Testing state "+i); for (j = 0; j < i; j++) { if ( equiv[i][j] ) { for (c = 0; c < numInput; c++) { if (equiv[i][j]) { int p = table[i][c]; int q = table[j][c]; if (p < q) { int t = p; p = q; q = t; } if ( p >= 0 || q >= 0 ) { // Out.debug("Testing input '"+c+"' for ("+i+","+j+")"); // Out.debug("Target states are ("+p+","+q+")"); if ( p!=q && (p == -1 || q == -1 || !equiv[p][q]) ) { equiv[i][j] = false; if (list[i][j] != null) list[i][j].markAll(list,equiv); } // printTable(equiv); } // if (p >= 0) .. } // if (equiv[i][j] } // for (char c = 0; c < numInput .. // if i and j are still marked equivalent.. if ( equiv[i][j] ) { // Out.debug("("+i+","+j+") are still marked equivalent"); for (c = 0; c < numInput; c++) { int p = table[i][c]; int q = table[j][c]; if (p < q) { int t = p; p = q; q = t; } if (p != q && p >= 0 && q >= 0) { if ( list[p][q] == null ) { list[p][q] = new StatePairList(); } list[p][q].addPair(i,j); } } } else { // Out.debug("("+i+","+j+") are not equivalent"); } } // of first if (equiv[i][j]) } // of for j } // of for i // } // printTable(equiv); return equiv; } public void printInvDelta(int [] [] inv_delta, int [] inv_delta_set) { Out.dump("Inverse of transition table: "); for (int s = 0; s < numStates+1; s++) { Out.dump("State ["+(s-1)+"]"); for (int c = 0; c < numInput; c++) { String line = "With <"+c+"> in {"; int t = inv_delta[s][c]; while (inv_delta_set[t] != -1) { line += inv_delta_set[t++]-1; if (inv_delta_set[t] != -1) line += ","; } if (inv_delta_set[inv_delta[s][c]] != -1) Out.dump(line+"}"); } } } public void printTable(boolean [] [] equiv) { Out.dump("Equivalence table is : "); for (int i = 1; i < numStates; i++) { String line = i+" :"; for (int j = 0; j < i; j++) { if (equiv[i][j]) line+= " E"; else line+= " x"; } Out.dump(line); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -