Advertisement
honey_the_codewitch

minimize typescript

Nov 1st, 2024 (edited)
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. private static _minimize(a: fa, progress: faProgress) : fa {
  2.     // TODO: This doesn't work
  3.     let prog: number = 0;
  4.     if(progress===null) {
  5.         progress = new faProgress();
  6.     }
  7.     progress.report(prog);
  8.     a=a.toDfa(progress);
  9.     const tr: faTransition[] = a.transitions;
  10.     if(tr.length==1) {
  11.         const t: faTransition = tr[0];
  12.         if(t.to=== a && t.min==0&&t.max==0x10ffff) {
  13.             return a;
  14.         }
  15.     }
  16.     a.totalize();
  17.     ++prog;progress.report(prog);
  18.     const cl: fa[] = a.fillClosure();
  19.     const states: fa[] = new Array<fa>();
  20.     let mtag: number = 0;
  21.     for(const q of cl) {
  22.         q._minimizationTag = mtag;
  23.         states.push(q);
  24.         ++mtag;
  25.     }
  26.     let pp: number[] = [];
  27.     for(let ic: number = cl.length,i=0;i<ic;++i) {
  28.         const ffa: fa=cl[i];
  29.         pp.push(0);
  30.         for(const t of ffa.transitions) {
  31.             pp.push(t.min);
  32.             if(t.max<0x10ffff) {
  33.                 pp.push(t.max+1);
  34.             }
  35.         }
  36.     }
  37.     const sigma: number[] = new Array<number>();
  38.     for(let i = 0;i<pp.length;++i) {
  39.         sigma.push(pp[i]);
  40.     }
  41.     sigma.sort();
  42.  
  43.     // initialize the data structures
  44.     const reverse : fa[][][] = new Array<Array<Array<fa>>>();
  45.     for(const s of states) {
  46.         const arr: fa[][] = new Array<Array<fa>>(sigma.length);
  47.         arr.fill(null,0,arr.length-1);
  48.         reverse.push(arr);
  49.     }
  50.     ++prog;progress.report(prog);
  51.     const reverseNonempty: boolean[][] = Array<Array<boolean>>();//[states.length,sigma.length];
  52.     for(let i: number = 0;i<states.length;++i) {
  53.         const arr: boolean[] = new Array<boolean>(sigma.length);
  54.         arr.fill(false,0,arr.length-1);
  55.         reverseNonempty.push(arr);
  56.     }
  57.     const partition: fa[][] = new Array<Array<fa>>(states.length);
  58.     partition.fill(null,0,partition.length-1);
  59.     ++prog;progress.report(prog);
  60.     const block: number[] = new Array<number>(states.length);
  61.     const active: _FList[][] = new Array<Array<_FList>>(); // [states.length,sigma.length];
  62.     for(let i: number = 0;i<states.length;++i) {
  63.         const arr: _FList[] = new Array<_FList>(sigma.length);
  64.         arr.fill(null,0,arr.length-1);
  65.         active.push(arr);
  66.     }
  67.     const active2: _FListNode[][] = new Array<Array<_FListNode>>()//[states.length,sigma.length];
  68.     for(let i: number = 0;i<states.length;++i) {
  69.         const arr: _FListNode[] = new Array<_FListNode>(sigma.length);
  70.         arr.fill(null,0,arr.length-1);
  71.         active2.push(arr);
  72.     }
  73.     const pending: _FKeyPair[] = new Array<_FKeyPair>();
  74.     const pending2: boolean[][] = Array<Array<boolean>>();//[sigma.length,states.length];
  75.     for(let i: number = 0;i<sigma.length;++i) {
  76.         const arr : boolean[] = new Array<boolean>(states.length);
  77.         arr.fill(false,0,arr.length-1);
  78.         pending2.push(arr);
  79.     }
  80.     let split: fa[] = new Array<fa>();
  81.     const split2: boolean[] = new Array<boolean>(states.length);
  82.     split2.fill(false,0,split2.length-1);
  83.     let refine: number[] = new Array<number>();
  84.     const refine2: boolean[] = new Array<boolean>(states.length);
  85.     split2.fill(false,0,refine2.length-1);
  86.     const splitBlock: fa[][] = new Array<Array<fa>>(states.length);
  87.     splitBlock.fill(null,0,splitBlock.length-1);
  88.     ++prog;progress.report(prog);
  89.     for(let q: number = 0;q<states.length;++q) {
  90.         splitBlock[q]= new Array<fa>();
  91.         partition[q]=new Array<fa>();
  92.         for(let x: number = 0;x<sigma.length;++x) {
  93.             reverse[q][x]=new Array<fa>();
  94.             active[q][x]=new _FList();
  95.         }
  96.     }
  97.     // Find the initial partition and reverse edges
  98.     for(const qq of states) {
  99.         const j: number = qq.isAccepting()? 0: 1;
  100.         partition[j].push(qq);
  101.         block[qq._minimizationTag]=j;
  102.         for(let x: number = 0;x<sigma.length;++x) {
  103.             const y: number = sigma[x];
  104.             const p: fa = qq._step(y);
  105.             const pn: number = p._minimizationTag;
  106.             if(reverse[pn] !==null && reverse[pn][x]!==null) {
  107.                 reverse[pn][x].push(qq);
  108.             }
  109.             reverseNonempty[pn][x]=true;
  110.         }
  111.         ++prog;progress.report(prog);
  112.     }
  113.     // initialize the active sets
  114.     for(let j: number = 0;j<=1;++j) {
  115.         for(let x: number = 0;x<sigma.length;++x) {
  116.             const part: fa[] = partition[j];
  117.             for(const qq of part) {
  118.                 if (reverseNonempty[qq._minimizationTag][x]===true) {
  119.                     active2[qq._minimizationTag][x]=active[j][x].add(qq);
  120.                 }
  121.             }
  122.         }
  123.         ++prog;progress.report(prog);
  124.     }
  125.     // initialize pending
  126.     for(let x: number = 0; x<sigma.length;++x) {
  127.         const a0: number = active[0][x].count;
  128.         const a1: number = active[1][x].count;
  129.         const j: number = a0<=a1?0:1;
  130.         pending.push(new _FKeyPair(j,x));
  131.         pending2[x][j]=true;
  132.     }
  133.     // process pending until fixed point
  134.     let k: number = 2;
  135.     while(pending.length>0) {
  136.         const ip: _FKeyPair = pending.shift();
  137.         const p: number = ip.key;
  138.         const x: number = ip.value;
  139.         pending2[x][p]=false;
  140.         for(let m: _FListNode = active[p][x].first;m!==null;m=m.next) {
  141.             for(const s of reverse[m.state._minimizationTag][x]) {
  142.                 if(!split2[s._minimizationTag]) {
  143.                     split2[s._minimizationTag]=true;
  144.                     split.push(s);
  145.                     const j: number = block[s._minimizationTag];
  146.                     splitBlock[j].push(s);
  147.                     if(refine2[j]!==true) {
  148.                         refine2[j]=true;
  149.                         refine.push(j);
  150.                     }
  151.                 }
  152.             }
  153.         }
  154.         ++prog;progress.report(prog);
  155.         // refine blocks
  156.         for(const j of refine) {
  157.             if(splitBlock[j].length<partition[j].length) {
  158.                 let b1: Array<fa> = partition[j];
  159.                 let b2: Array<fa> = partition[k];
  160.                 const e: Array<fa> = splitBlock[j];
  161.                 for(const s of e) {
  162.                     partition[j] = b1 = b1.splice(b1.indexOf(s),1);
  163.                     b2.push(s);
  164.                     block[s._minimizationTag]=k;
  165.                     for(let c: number = 0;c<sigma.length;++c) {
  166.                         const sn: _FListNode = active2[s._minimizationTag][c];
  167.                         if(sn!==null && sn.stateList===active[j][c]) {
  168.                             sn.remove();
  169.                             active2[s._minimizationTag][c]=active[k][c].add(s);
  170.                         }
  171.                     }
  172.                 }
  173.                 // update pending
  174.                 for(let c:number = 0;c<sigma.length;++c) {
  175.                     const aj: number = active[j][c].count;
  176.                     const ak: number = active[k][c].count;
  177.                     if(!pending2[c][j] && 0<aj&&aj<=ak) {
  178.                         pending2[c][j]=true;
  179.                         pending.push(new _FKeyPair(j,c));
  180.                     } else {
  181.                         pending2[c][k]=true;
  182.                         pending.push(new _FKeyPair(k,c));
  183.                     }
  184.                 }
  185.                 ++k;
  186.             }
  187.             const sbj: Array<fa> = splitBlock[j];
  188.             for(const s of sbj) {
  189.                 split2[s._minimizationTag]=false;
  190.             }
  191.             refine2[j]=false;
  192.             splitBlock[j].length=0;
  193.             ++prog;progress.report(prog);
  194.        
  195.         }
  196.         split.length=0;
  197.         refine.length=0;
  198.     }
  199.     ++prog;progress.report(prog);
  200.     // make a new state for each equiv class, set initial state
  201.     const newstates : fa[] = new Array<fa>();
  202.     for(let n: number = 0; n<k;++n) {
  203.         const s: fa = new fa();
  204.         s.isDeterministic = true;
  205.         newstates.push(s);
  206.         const pn: Array<fa> = partition[n];
  207.         for(const q of pn) {
  208.             if(q === a) {
  209.                 a = s;
  210.             }
  211.             s.id = q.id;
  212.             s.acceptSymbol = q.acceptSymbol;
  213.             s._minimizationTag = q._minimizationTag;
  214.             q._minimizationTag = n;
  215.         }
  216.         ++prog;progress.report(prog);
  217.     }
  218.     // build transitions and set acceptance
  219.     for(const s of newstates) {
  220.         const st: fa = states[s._minimizationTag];
  221.         s.acceptSymbol = st.acceptSymbol;
  222.         for(const t of st.transitions) {
  223.             s.transitions.push(new faTransition(newstates[t.to._minimizationTag],t.min,t.max));
  224.         }
  225.         ++prog;progress.report(prog);
  226.     }
  227.     // remove dead transitions
  228.     for(const ffa of a.fillClosure()) {
  229.         const itrns: faTransition[] = new Array<faTransition>(...ffa.transitions)
  230.         ffa.transitions = new Array<faTransition>();
  231.         for(const trns of itrns) {
  232.             if(!trns.to.isTrap()) {
  233.                 ffa.transitions.push(trns);
  234.             }
  235.         }
  236.     }
  237.     return a;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement