00001 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #include <julius/julius.h>
00049 
00050 
00051 static NODE *get_best_from_stack(NODE **start, int *stacknum);
00052 static int put_to_stack(NODE *new, NODE **start, NODE **bottom, int *stacknum, int stacksize);
00053 static void put_all_in_stack(NODE **start, int *stacknum, WORD_INFO *winfo);
00054 static void free_all_nodes(NODE *node);
00055 static void put_hypo_woutput(NODE *hypo, WORD_INFO *winfo);
00056 static void put_hypo_wname(NODE *hypo, WORD_INFO *winfo);
00057 
00058 
00059 
00060 
00061 
00062 
00085 static NEXTWORD **
00086 nw_malloc(int *maxlen, NEXTWORD **root, int max)
00087 {
00088   NEXTWORD *nwtmp;
00089   NEXTWORD **nw;
00090   int i;
00091 
00092   nw = (NEXTWORD **)mymalloc(max * sizeof(NEXTWORD *));
00093   nwtmp = (NEXTWORD *)mymalloc(max * sizeof(NEXTWORD));
00094   for (i=0;i<max; i++) {
00095     nw[i] = &(nwtmp[i]);
00096   }
00097   *maxlen = max;
00098   *root = nwtmp;
00099   return nw;
00100 }
00101 
00117 static void
00118 nw_free(NEXTWORD **nw, NEXTWORD *root)
00119 {
00120   free(root);
00121   free(nw);
00122 }
00123 
00162 static NEXTWORD **
00163 nw_expand(NEXTWORD **nwold, int *maxlen, NEXTWORD **root, int num)
00164 {
00165   NEXTWORD *nwtmp;
00166   NEXTWORD **nw;
00167   int i;
00168   int nwmaxlen;
00169 
00170   nwmaxlen = *maxlen + num;
00171 
00172   nwtmp = (NEXTWORD *)myrealloc(*root, nwmaxlen * sizeof(NEXTWORD));
00173   nw = (NEXTWORD **)myrealloc(nwold, nwmaxlen * sizeof(NEXTWORD *));
00174   nw[0] = nwtmp;
00175   for (i=1;i<nwmaxlen; i++) {
00176     nw[i] = &(nwtmp[i]);
00177   }
00178   *maxlen = nwmaxlen;
00179   *root = nwtmp;
00180   return nw;
00181 }
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00208 static NODE *
00209 get_best_from_stack(NODE **start, int *stacknum)
00210 {
00211   NODE *tmp;
00212 
00213   
00214   tmp=(*start);
00215   if ((*start)!=NULL) {         
00216     (*start)=(*start)->next;
00217     if ((*start)!=NULL) (*start)->prev=NULL;
00218     (*stacknum)--;
00219     return(tmp);
00220   }
00221   else {
00222     return(NULL);
00223   }
00224 }
00225 
00252 static int
00253 can_put_to_stack(NODE *new, NODE **bottom, int *stacknum, int stacksize)
00254 {
00255   
00256   if ((*stacknum + 1) > stacksize && (*bottom)->score >= new->score) {
00257     
00258     return(-1);
00259   }
00260   return(0);
00261 }
00262 
00291 static int
00292 put_to_stack(NODE *new, NODE **start, NODE **bottom, int *stacknum, int stacksize)
00293 {
00294   NODE *tmp;
00295 
00296   
00297   (*stacknum)++;
00298 
00299   
00300   if ((*stacknum)>stacksize) {
00301     
00302     (*stacknum)--;
00303     if ((*bottom)->score < new->score) {
00304       
00305       tmp=(*bottom);
00306       (*bottom)->prev->next=NULL;
00307       (*bottom)=(*bottom)->prev;
00308       free_node(tmp);
00309     } else {
00310       
00311       free_node(new);
00312       return(-1);
00313     }
00314   }
00315 
00316   
00317   if ((*start)==NULL) {         
00318     
00319     (*start)=new;
00320     (*bottom)=new;
00321     new->next=NULL;
00322     new->prev=NULL;
00323     return(0);
00324   }
00325   if ((*start)->score <= new->score) {
00326     
00327     new->next = (*start);
00328     new->next->prev = new;
00329     (*start)=new;
00330     new->prev=NULL;
00331     return(0);
00332   }
00333   if ((*bottom)->score >= new->score) {
00334     
00335     new->prev = (*bottom);
00336     new->prev->next = new;
00337     (*bottom)=new;
00338     new->next=NULL;
00339     return(0);
00340   }
00341     
00342   
00343   if (((*start)->score + (*bottom)->score) / 2 > new->score) {
00344     
00345     tmp=(*bottom);
00346     while(tmp->score < new->score) tmp=tmp->prev;
00347     new->prev=tmp;
00348     new->next=tmp->next;
00349     tmp->next->prev=new;
00350     tmp->next=new;
00351   } else {
00352     
00353     tmp=(*start);
00354     while(tmp->score > new->score) tmp=tmp->next;
00355     new->next=tmp;
00356     new->prev=tmp->prev;
00357     tmp->prev->next=new;
00358     tmp->prev=new;
00359   }
00360   return(0);
00361 }
00362 
00379 static void
00380 put_all_in_stack(NODE **start, int *stacknum, WORD_INFO *winfo)
00381 {
00382   NODE *ntmp;
00383   
00384   jlog("DEBUG: hypotheses remained in global stack\n");
00385   while ((ntmp = get_best_from_stack(start, stacknum)) != NULL) {
00386     jlog("DEBUG: %3d: s=%f",*stacknum, ntmp->score);
00387     put_hypo_woutput(ntmp, winfo);
00388     free_node(ntmp);
00389   }
00390 }
00391 
00404 static void
00405 free_all_nodes(NODE *start)
00406 {
00407   NODE *tmp;
00408   NODE *next;
00409 
00410   tmp=start;
00411   while(tmp) {
00412     next=tmp->next;
00413     free_node(tmp);
00414     tmp=next;
00415   }
00416 }
00417 
00418 
00419 #ifdef CONFIDENCE_MEASURE
00420 
00421 
00422 
00423 
00424 
00425 
00426 #ifdef CM_SEARCH
00427 
00428 
00429 
00430 
00431 
00432 
00451 static void
00452 cm_init(StackDecode *sd, int wnum, LOGPROB cm_alpha
00453 #ifdef CM_MULTIPLE_ALPHA
00454         , cm_alpha_num
00455 #endif
00456         )
00457 {
00458   sd->l_stacksize = wnum;
00459   sd->l_start = sd->l_bottom = NULL;
00460   sd->l_stacknum = 0;
00461   sd->cm_alpha = cm_alpha;
00462 #ifdef CM_MULTIPLE_ALPHA
00463   if (sd->cmsumlist) {
00464     if (sd->cmsumlistlen < cm_alpha_num) {
00465       free(sd->cmsumlist);
00466       sd->cmsumlist = NULL;
00467     }
00468   }
00469   if (sd->cmsumlist == NULL) {
00470     sd->cmsumlist = (LOGPROB *)mymalloc(sizeof(LOGPROB) * cm_alpha_num);
00471     sd->cmsumlistlen = cm_alpha_num;
00472   }
00473 #endif    
00474 }
00475 
00490 static void
00491 cm_store(StackDecode *sd, NODE *new)
00492 {
00493   
00494   put_to_stack(new, &(sd->l_start), &(sd->l_bottom), &(sd->l_stacknum), sd->l_stacksize);
00495 }
00496 
00512 static void
00513 cm_sum_score(StackDecode *sd
00514 #ifdef CM_MULTIPLE_ALPHA
00515              , bgn, end, step
00516 #endif
00517 )
00518 {
00519   NODE *node;
00520   LOGPROB sum;
00521 #ifdef CM_MULTIPLE_ALPHA
00522   LOGPROB a;
00523   int j;
00524 #endif
00525 
00526   if (sd->l_start == NULL) return;      
00527   sd->cm_tmpbestscore = sd->l_start->score; 
00528 
00529 #ifdef CM_MULTIPLE_ALPHA
00530   for (j = 0, a = bgn; a <= end; a += step) {
00531     sum = 0.0;
00532     for(node = sd->l_start; node; node = node->next) {
00533       sum += pow(10, a * (node->score - sd->cm_tmpbestscore));
00534     }
00535     sd->cmsumlist[j++] = sum;   
00536   }
00537 #else
00538   sum = 0.0;
00539   for(node = sd->l_start; node; node = node->next) {
00540     sum += pow(10, sd->cm_alpha * (node->score - sd->cm_tmpbestscore));
00541   }
00542   sd->cm_tmpsum = sum;          
00543 #endif
00544 
00545 }
00546 
00563 static void
00564 cm_set_score(StackDecode *sd, NODE *node
00565 #ifdef CM_MULTIPLE_ALPHA
00566              , bgn, end, step
00567 #endif
00568              )
00569 {
00570 #ifdef CM_MULTIPLE_ALPHA
00571   int j;
00572   LOGPROB a;
00573 #endif
00574 
00575 #ifdef CM_MULTIPLE_ALPHA
00576   for (j = 0, a = bgn; a <= end; a += step) {
00577     node->cmscore[node->seqnum-1][j] = pow(10, a * (node->score - sd->cm_tmpbestscore)) / sd->cmsumlist[j];
00578     j++;
00579   }
00580 #else
00581   node->cmscore[node->seqnum-1] = pow(10, sd->cm_alpha * (node->score - sd->cm_tmpbestscore)) / sd->cm_tmpsum;
00582 #endif
00583 }
00584 
00601 static NODE *
00602 cm_get_node(StackDecode *sd)
00603 {
00604   return(get_best_from_stack(&(sd->l_start), &(sd->l_stacknum)));
00605 }
00606 
00607 #endif 
00608 
00609 #ifdef CM_NBEST
00610 
00611 
00612 
00613 
00614 
00634 static void
00635 cm_compute_from_nbest(StackDecode *sd, NODE *start, int stacknum, JCONF_SEARCH *jconf)
00636 {
00637   NODE *node;
00638   LOGPROB bestscore, sum, s;
00639   WORD_ID w;
00640   int i;
00641   LOGPROB cm_alpha;
00642   int j;
00643 
00644   
00645 #ifdef CM_MULTIPLE_ALPHA
00646   if (sd->cmsumlist) {
00647     if (sd->cmsumlistlen < jconf->annotate.cm_alpha_num) {
00648       free(sd->cmsumlist);
00649       sd->cmsumlist = NULL;
00650     }
00651   }
00652   if (sd->cmsumlist == NULL) {
00653     sd->cmsumlist = (LOGPROB *)mymalloc(sizeof(LOGPROB) * jconf->annotate.cm_alpha_num);
00654     sd->cmsumlistlen = cm_alpha_num;
00655   }
00656 #endif    
00657   if (sd->sentcm == NULL) {             
00658     sd->sentcm = (LOGPROB *)mymalloc(sizeof(LOGPROB)*stacknum);
00659     sd->sentnum = stacknum;
00660   } else if (sd->sentnum < stacknum) { 
00661     sd->sentcm = (LOGPROB *)myrealloc(sentcm, sizeof(LOGPROB)*stacknum);
00662     sd->sentnum = stacknum;
00663   }
00664   if (sd->wordcm == NULL) {
00665     sd->wordcm = (LOGPROB *)mymalloc(sizeof(LOGPROB) * winfo->num);
00666   }
00667   
00668   cm_alpha = jconf->annotate.cm_alpha;
00669 #ifdef CM_MULTIPLE_ALPHA
00670   for (j = 0, cm_alpha = jconf->annotate.cm_alpha_bgn; cm_alpha <= jconf->annotate.cm_alpha_end; cm_alpha += jconf->annotate.cm_alpha_step) {
00671 #endif
00672     
00673     for(w=0;w<winfo->num;w++) {
00674       sd->wordcm[w] = 0.0;
00675     }
00676     
00677     bestscore = start->score;
00678     
00679     sum = 0.0;
00680     for (node = start; node != NULL; node = node->next) {
00681       sum += pow(10, cm_alpha * (node->score - bestscore));
00682     }
00683     
00684     i = 0;
00685     for (node = start; node != NULL; node = node->next) {
00686       sd->sentcm[i] = pow(10, cm_alpha * (node->score - bestscore)) / sum;
00687       i++;
00688     }
00689     
00690     i = 0;
00691     for (node = start; node != NULL; node = node->next) {
00692       for (w=0;w<node->seqnum;w++) {
00693         sd->wordcm[node->seq[w]] += sd->sentcm[i];
00694       }
00695       i++;
00696     }
00697     
00698     for (node = start; node != NULL; node = node->next) {
00699       for (w=0;w<node->seqnum;w++) {
00700 #ifdef CM_MULTIPLE_ALPHA
00701         node->cmscore[w][j] = sd->wordcm[node->seq[w]];
00702 #else   
00703         node->cmscore[w] = sd->wordcm[node->seq[w]];
00704 #endif
00705       }
00706     }
00707 #ifdef CM_MULTIPLE_ALPHA
00708     j++;
00709   }
00710 #endif
00711 }
00712 
00713 #endif 
00714 
00715 #endif 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 
00727 
00728 
00729 
00730 
00731 
00732 
00733 
00734 
00748 static void
00749 wb_init(StackDecode *s)
00750 {
00751   int i;
00752   for(i=0;i<=MAXSEQNUM;i++) s->hypo_len_count[i] = 0;
00753   s->maximum_filled_length = -1;
00754 }
00755 
00782 static boolean
00783 wb_ok(StackDecode *s, NODE *now, int width)
00784 {
00785   if (now->seqnum <= s->maximum_filled_length) {
00786     
00787 
00788     return FALSE;
00789   } else {
00790     
00791 
00792     s->hypo_len_count[now->seqnum]++;
00793     if (s->hypo_len_count[now->seqnum] > width) {
00794       
00795 
00796 
00797       if (s->maximum_filled_length < now->seqnum) s->maximum_filled_length = now->seqnum;
00798     }
00799     return TRUE;
00800   }
00801 }
00802 
00803 #ifdef SCAN_BEAM
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00842 static void
00843 envl_init(StackDecode *s, int framenum)
00844 {
00845   int i;
00846   for(i=0;i<framenum;i++) s->framemaxscore[i] = LOG_ZERO;
00847 }
00848 
00865 static void
00866 envl_update(StackDecode *s, NODE *n, int framenum)
00867 {
00868   int t;
00869   for(t=framenum-1;t>=0;t--) {
00870     if (s->framemaxscore[t] < n->g[t]) s->framemaxscore[t] = n->g[t];
00871   }
00872 }
00873 #endif 
00874 
00875 
00876 
00877 
00878 
00879 
00903 void
00904 segment_set_last_nword(NODE *hypo, RecogProcess *r)
00905 {
00906   int i;
00907   WORD_ID w;
00908 
00909   if (r->sp_break_last_nword_allow_override) {
00910     for(i=0;i<hypo->seqnum;i++) {
00911       w = hypo->seq[i];
00912       if (w != r->sp_break_last_word
00913           && !is_sil(w, r)
00914           && !r->lm->winfo->is_transparent[w]
00915           ) {
00916         r->sp_break_last_nword = w;
00917         break;
00918       }
00919     }
00920 #ifdef SP_BREAK_DEBUG
00921     printf("sp_break_last_nword=%d[%s]\n", r->sp_break_last_nword, r->lm->winfo->woutput[r->sp_break_last_nword]);
00922 #endif
00923   } else {
00924     r->sp_break_last_nword = WORD_INVALID;
00925   }
00926 }
00927 
00928 
00929 
00930 
00931 
00932 
00947 static void
00948 put_hypo_woutput(NODE *hypo, WORD_INFO *winfo)
00949 {
00950   int i,w;
00951 
00952   if (hypo != NULL) {
00953     for (i=hypo->seqnum-1;i>=0;i--) {
00954       w = hypo->seq[i];
00955       jlog(" %s", winfo->woutput[w]);
00956     }
00957   }
00958   jlog("\n");  
00959 }
00960 
00975 static void
00976 put_hypo_wname(NODE *hypo, WORD_INFO *winfo)
00977 {
00978   int i,w;
00979 
00980   if (hypo != NULL) {
00981     for (i=hypo->seqnum-1;i>=0;i--) {
00982       w = hypo->seq[i];
00983       jlog(" %s", winfo->wname[w]);
00984     }
00985   }
00986   jlog("\n");  
00987 }
00988 
01001 static void
01002 store_result_pass2(NODE *hypo, RecogProcess *r)
01003 {
01004   int i;
01005   Sentence *s;
01006 
01007   s = &(r->result.sent[r->result.sentnum]);
01008 
01009   s->word_num = hypo->seqnum;
01010   for (i = 0; i < hypo->seqnum; i++) {
01011     s->word[i] = hypo->seq[hypo->seqnum - 1 - i];
01012   }
01013 #ifdef CONFIDENCE_MEASURE
01014   for (i = 0; i < hypo->seqnum; i++) {
01015     s->confidence[i] = hypo->cmscore[hypo->seqnum - 1 - i];
01016   }
01017 #endif
01018 
01019   s->score = hypo->score;
01020   s->score_lm = hypo->totallscore;
01021   s->score_am = hypo->score - hypo->totallscore;
01022   if (r->lmtype == LM_DFA) {
01023     
01024     
01025     if (multigram_get_all_num(r->lm) > 1) {
01026       s->gram_id = multigram_get_gram_from_category(r->lm->winfo->wton[hypo->seq[0]], r->lm);
01027     } else {
01028       s->gram_id = 0;
01029     }
01030   }
01031 
01032   r->result.sentnum++;
01033   
01034 }
01035 
01036 
01037 
01038 
01039 
01040 
01083 static void
01084 result_reorder_and_output(NODE **r_start, NODE **r_bottom, int *r_stacknum, int ncan, RecogProcess *r, HTK_Param *param)
01085 {
01086   NODE *now;
01087   int num;
01088 
01089 #ifdef CM_NBEST 
01090   
01091   cm_compute_from_nbest(&(r->pass2), *r_start, *r_stacknum, r->config);
01092 #endif
01093   num = 0;
01094   while ((now = get_best_from_stack(r_start,r_stacknum)) != NULL && num < ncan) {
01095     num++;
01096     
01097     store_result_pass2(now, r);
01098 
01099     
01100     
01101     if (r->lmtype == LM_PROB && r->config->successive.enabled && num == 1) segment_set_last_nword(now, r);
01102     
01103     if (r->config->annotate.align_result_word_flag) word_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r);
01104     if (r->config->annotate.align_result_phoneme_flag) phoneme_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r);
01105     if (r->config->annotate.align_result_state_flag) state_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r);
01106 
01107     free_node(now);
01108   }
01109   r->result.status = J_RESULT_STATUS_SUCCESS;
01110   
01111   if (now != NULL) free_node(now);
01112   free_all_nodes(*r_start);
01113 }  
01114 
01115 
01116 
01117 
01118 
01119 
01147 void
01148 wchmm_fbs(HTK_Param *param, RecogProcess *r, int cate_bgn, int cate_num)
01149 {
01150   
01151   
01152   int stacknum;                 
01153   NODE *start = NULL;           
01154   NODE *bottom = NULL;          
01155 
01156   
01157   
01158   static int r_stacksize;
01159   static int r_stacknum;
01160   static NODE *r_start = NULL;
01161   static NODE *r_bottom = NULL;
01162 
01163   
01164   
01165   static NEXTWORD fornoise; 
01166 
01167   NEXTWORD **nextword, *nwroot; 
01168   int maxnwnum;                 
01169   int nwnum;                    
01170   NODE *now, *new;              
01171   NODE *now_noise;             
01172   boolean now_noise_calced;
01173   boolean acc;
01174   int t;
01175   int w,i,j;
01176   LOGPROB last_score = LOG_ZERO;
01177   
01178   LOGPROB prev_score;
01179   WordGraph *wordgraph_root = NULL;
01180   boolean merged_p;
01181 #ifdef GRAPHOUT_DYNAMIC
01182   int dynamic_merged_num = 0;
01183   WordGraph *wtmp;
01184   LOGPROB lscore_prev;
01185 #endif
01186 #ifdef GRAPHOUT_SEARCH
01187   int terminate_search_num = 0;
01188 #endif
01189 
01190   
01191   int stacksize, ncan, maxhypo, peseqlen;
01192   static JCONF_SEARCH *jconf;
01193   static WORD_INFO *winfo;
01194   static NGRAM_INFO *ngram;
01195   static DFA_INFO *gdfa;
01196   static BACKTRELLIS *backtrellis;
01197   static StackDecode *dwrk;
01198 
01199   if (r->lmtype == LM_DFA) {
01200     if (debug2_flag) jlog("DEBUG: only words in these categories will be expanded: %d-%d\n", cate_bgn, cate_bgn + cate_num-1);
01201   }
01202 
01203   
01204 
01205 
01206 
01207 
01208   
01209   jconf = r->config;
01210   winfo = r->lm->winfo;
01211   if (r->lmtype == LM_PROB) {
01212     ngram = r->lm->ngram;
01213   } else if (r->lmtype == LM_DFA) {
01214     gdfa = r->lm->dfa;
01215   }
01216   backtrellis = r->backtrellis;
01217   dwrk = &(r->pass2);
01218 
01219   stacksize = jconf->pass2.stack_size;
01220   ncan = jconf->pass2.nbest;
01221   maxhypo = jconf->pass2.hypo_overflow;
01222   peseqlen = backtrellis->framelen;
01223 
01224   
01225   r->peseqlen = backtrellis->framelen;
01226   
01227   
01228   
01229   
01230   nextword = nw_malloc(&maxnwnum, &nwroot, winfo->num);
01231   
01232   
01233   malloc_wordtrellis(r);                
01234   
01235   
01236   start = bottom = NULL;
01237   stacknum = 0;
01238   
01239   
01240   r_stacksize = ncan;
01241   r_start = r_bottom = NULL;
01242   r_stacknum = 0;
01243 
01244   
01245   
01246   dwrk->popctr = 0;
01247   dwrk->genectr = 0;
01248   dwrk->pushctr = 0;
01249   dwrk->finishnum = 0;
01250   
01251 #ifdef CM_SEARCH
01252   
01253   cm_init(dwrk, winfo->num, jconf->annotate.cm_alpha
01254 #ifdef CM_MULTIPLE_ALPHA
01255           , jconf->annotate.cm_alpha_num
01256 #endif
01257           );
01258 #endif
01259 #ifdef SCAN_BEAM
01260   
01261   dwrk->framemaxscore = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
01262   envl_init(dwrk, peseqlen);
01263 #endif 
01264 
01265   
01266   result_sentence_malloc(r, jconf->output.output_hypo_maxnum);
01267 
01268   
01269   
01270   if (jconf->pass2.enveloped_bestfirst_width >= 0) wb_init(dwrk);
01271 
01272   if (jconf->graph.enabled) {
01273     wordgraph_init(r->wchmm);
01274   }
01275 
01276   
01277 
01278 
01279 
01280 
01281   
01282   if (r->lmtype == LM_PROB) {
01283     nwnum = ngram_firstwords(nextword, peseqlen, maxnwnum, r);
01284   } else if (r->lmtype == LM_DFA) {
01285     nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r);
01286     
01287     
01288 
01289     while (nwnum < 0) {
01290       nextword = nw_expand(nextword, &maxnwnum, &nwroot, winfo->num);
01291       nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r);
01292     }
01293   }
01294 
01295   if (debug2_flag) {
01296     jlog("DEBUG: %d words in wordtrellis as first hypothesis\n", nwnum);
01297   }
01298   
01299   
01300   for (w = 0; w < nwnum; w++) {
01301     if (r->lmtype == LM_DFA) {
01302       
01303       if (! (winfo->wton[nextword[w]->id] >= cate_bgn && winfo->wton[nextword[w]->id] < cate_bgn + cate_num)) {
01304         continue;
01305       }
01306     }
01307     
01308     new = newnode(r);
01309     start_word(new, nextword[w], param, r);
01310     if (r->lmtype == LM_DFA) {
01311       if (new->score <= LOG_ZERO) { 
01312         free_node(new);
01313         continue;
01314       }
01315     }
01316     dwrk->genectr++;
01317 #ifdef CM_SEARCH
01318     
01319     cm_store(dwrk, new);
01320 #else 
01321     
01322     if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01323       dwrk->current = new;
01324       
01325       if (jconf->graph.enabled) {
01326         new->prevgraph = NULL;
01327         new->lastcontext = NULL;
01328       }
01329       dwrk->pushctr++;
01330     }
01331 #endif
01332   }
01333 #ifdef CM_SEARCH
01334   
01335   cm_sum_score(dwrk
01336 #ifdef CM_MULTIPLE_ALPHA
01337                , jconf->annotate.cm_alpha_bgn
01338                , jconf->annotate.cm_alpha_end
01339                , jconf->annotate.cm_alpha_step
01340 #endif
01341                );
01342 
01343   
01344   while ((new = cm_get_node(dwrk)) != NULL) {
01345     cm_set_score(dwrk, new
01346 #ifdef CM_MULTIPLE_ALPHA
01347                  , jconf->annotate.cm_alpha_bgn
01348                  , jconf->annotate.cm_alpha_end
01349                  , jconf->annotate.cm_alpha_step
01350 #endif
01351                  );
01352 #ifdef CM_SEARCH_LIMIT
01353     if (new->cmscore[new->seqnum-1] < jconf->annotate.cm_cut_thres
01354 #ifdef CM_SEARCH_LIMIT_AFTER
01355         && dwrk->finishnum > 0
01356 #endif
01357         ) {
01358       free_node(new);
01359       continue;
01360     }
01361 #endif 
01362     
01363     if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01364       dwrk->current = new;
01365       
01366       if (r->graphout) {
01367         new->prevgraph = NULL;
01368         new->lastcontext = NULL;
01369       }
01370       dwrk->pushctr++;
01371     }
01372   }
01373 #endif
01374 
01375   if (debug2_flag) {
01376     jlog("DEBUG: %d pushed\n", dwrk->pushctr);
01377   }
01378   
01379   
01380   
01381   
01382 
01383   for (;;) {
01384 
01385     
01386     
01387 
01388 
01389 
01390 
01391 
01392     
01393     
01394 
01395 
01396 
01397 #ifdef DEBUG
01398     jlog("DEBUG: get one hypothesis\n");
01399 #endif
01400     now = get_best_from_stack(&start,&stacknum);
01401     if (now == NULL) {  
01402       jlog("WARNING: %02d %s: hypothesis stack exhausted, terminate search now\n", r->config->id, r->config->name);
01403       jlog("STAT: %02d %s: %d sentences have been found\n", r->config->id, r->config->name, dwrk->finishnum);
01404       break;
01405     }
01406     
01407     if (now->score <= LOG_ZERO) {
01408       free_node(now);
01409       continue;
01410     }
01411 
01412 
01413     
01414     if (r->graphout) {
01415       prev_score = now->score;
01416     }
01417 
01418     
01419     
01420     if (jconf->pass2.enveloped_bestfirst_width >= 0) {
01421       if (!wb_ok(dwrk, now, jconf->pass2.enveloped_bestfirst_width)) {
01422         
01423 
01424         
01425 
01426 
01427         if (debug2_flag) {
01428           jlog("DEBUG: popped but pruned by word envelope:");
01429           put_hypo_woutput(now, r->lm->winfo);
01430         }
01431         free_node(now);
01432         continue;
01433       }
01434     }
01435     
01436 #ifdef CM_SEARCH_LIMIT_POP
01437     if (now->cmscore[now->seqnum-1] < jconf->annotate.cm_cut_thres_pop) {
01438       free_node(now);
01439       continue;
01440     }
01441 #endif 
01442 
01443     dwrk->popctr++;
01444 
01445     
01446     
01447     if (debug2_flag) {
01448       jlog("DEBUG: --- pop %d:\n", dwrk->popctr);
01449       jlog("DEBUG:  "); put_hypo_woutput(now, r->lm->winfo);
01450       jlog("DEBUG:  "); put_hypo_wname(now, r->lm->winfo);
01451       jlog("DEBUG:  %d words, f=%f, g=%f\n", now->seqnum, now->score, now->g[now->bestt]);
01452       jlog("DEBUG:  last word on trellis: [%d-%d]\n", now->estimated_next_t + 1, now->bestt);
01453     }
01454 
01455     dwrk->current = now;
01456     
01457 
01458     if (r->graphout) {
01459 
01460 #ifdef GRAPHOUT_DYNAMIC
01461       
01462       wtmp = wordgraph_check_merge(now->prevgraph, &wordgraph_root, now->seq[now->seqnum-1], &merged_p, jconf);
01463       if (wtmp != NULL) {               
01464         dynamic_merged_num++;
01465 
01466         lscore_prev = (now->prevgraph) ? now->prevgraph->lscore_tmp : 0.0;
01467 
01468         if (now->prevgraph != NULL) {
01469           if (now->prevgraph->saved) {
01470             j_internal_error("wchmm_fbs: already saved??\n");
01471           }
01472           wordgraph_free(now->prevgraph);
01473         }
01474 
01475         if (now->lastcontext != NULL
01476             && now->lastcontext != wtmp 
01477             ) {
01478           wordgraph_check_and_add_leftword(now->lastcontext, wtmp, lscore_prev);
01479 #ifdef GRAPHOUT_SEARCH_CONSIDER_RIGHT
01480           if (merged_p) {
01481             if (wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev) == FALSE) {
01482               merged_p = TRUE;
01483             } else {
01484               merged_p = FALSE;
01485             }
01486           } else {
01487             wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev);
01488           }
01489 #else
01490           wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev);
01491 #endif    
01492         }
01493         
01494         now->prevgraph = wtmp;  
01495 
01496         
01497         
01498       } else {
01499         wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root);
01500       }
01501 #ifdef GRAPHOUT_SEARCH
01502       
01503       if (merged_p && now->endflag == FALSE
01504 #ifdef GRAPHOUT_SEARCH_DELAY_TERMINATION
01505           
01506 
01507           && (jconf->graph.graphout_search_delay == FALSE || dwrk->finishnum > 0)
01508 #endif
01509           ) {
01510         terminate_search_num++;
01511         free_node(now);
01512         continue;
01513       }
01514 #endif
01515 #else  
01516       
01517       wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root);
01518 #endif 
01519     }
01520 
01521     
01522     
01523     envl_update(dwrk, now, peseqlen);
01524 
01525     
01526 
01527 
01528 
01529 
01530 
01531 
01532 #ifdef DEBUG
01533     VERMES("endflag check\n");
01534 #endif
01535     
01536     if (now->endflag) {
01537       if (debug2_flag) {
01538         jlog("DEBUG:  This is a full sentence candidate\n");
01539       }
01540       
01541       if (now->score == last_score) {
01542         free_node(now);
01543         continue;
01544       } else {
01545         last_score = now->score;
01546       }
01547       
01548       dwrk->finishnum++;
01549       if (debug2_flag) {
01550         jlog("DEBUG:  %d-th sentence found\n", dwrk->finishnum);
01551       }
01552 
01553         
01554 
01555         
01556 
01557         put_to_stack(now, &r_start, &r_bottom, &r_stacknum, r_stacksize);
01558         
01559         
01560         if (dwrk->finishnum >= ncan) {
01561           break;
01562         } else {
01563           continue;
01564         }
01565       
01566     } 
01567 
01568     
01569     
01570 
01571 
01572 
01573 
01574 
01575 
01576 #ifdef DEBUG
01577     jlog("DEBUG: loop end check\n");
01578 #endif
01579     if (dwrk->popctr >= maxhypo) {
01580       jlog("WARNING: %02d %s: num of popped hypotheses reached the limit (%d)\n", r->config->id, r->config->name, maxhypo);
01581       
01582       
01583       if (debug2_flag) put_all_in_stack(&start, &stacknum, r->lm->winfo);
01584       free_node(now);
01585       break;                    
01586     }
01587     
01588     
01589     if (now->seqnum >= MAXSEQNUM) {
01590       jlog("ERROR: sentence length exceeded system limit ( > %d)\n", MAXSEQNUM);
01591       free_node(now);
01592       continue;
01593     }
01594 
01595 #ifndef GRAPHOUT_PRECISE_BOUNDARY
01596     if (r->graphout) {
01597       
01598       
01599       if(!jconf->am.ccd_flag) {
01600         now->tail_g_score = now->g[now->bestt];
01601       }
01602     }
01603 #endif
01604 
01605     
01606 
01607 
01608 
01609 #ifdef DEBUG
01610     jlog("DEBUG: scan_word\n");
01611 #endif
01612     scan_word(now, param, r);
01613     if (now->score < LOG_ZERO) { 
01614       jlog("WARNING: too low score, ignore: score=%f",now->score);
01615       put_hypo_woutput(now, r->lm->winfo);
01616       free_node(now);
01617       continue;
01618     }
01619 
01620     
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 
01629 #ifdef DEBUG
01630     jlog("DEBUG: accept check\n");
01631 #endif
01632 
01633     if (r->lmtype == LM_PROB) {
01634       acc = ngram_acceptable(now, r);
01635     } else if (r->lmtype == LM_DFA) {
01636       acc = dfa_acceptable(now, r);
01637     }
01638     if (acc && now->estimated_next_t <= 5) {
01639       new = newnode(r);
01640       
01641       
01642       last_next_word(now, new, param, r);
01643       if (debug2_flag) {
01644         jlog("DEBUG:  This is acceptable as a sentence candidate\n");
01645       }
01646       
01647       
01648       if (new->score <= LOG_ZERO) {
01649         if (debug2_flag) {
01650           jlog("DEBUG:  But invalid because Viterbi pass does not reach the 0th frame\n");
01651         }
01652         free_node(new);
01653         free_node(now);
01654         continue;
01655       }
01656       
01657       
01658       if (debug2_flag) {
01659         jlog("DEBUG  This hypo itself was pushed with final score=%f\n", new->score);
01660       }
01661       new->endflag = TRUE;
01662       if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01663         if (r->graphout) {
01664           if (new->score > LOG_ZERO) {
01665             new->lastcontext = now->prevgraph;
01666             new->prevgraph = wordgraph_assign(new->seq[new->seqnum-1],
01667                                               WORD_INVALID,
01668                                               (new->seqnum >= 2) ? new->seq[new->seqnum-2] : WORD_INVALID,
01669                                               0,
01670 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01671                                               
01672 #ifdef PASS2_STRICT_IWCD
01673                                               new->wordend_frame[0],
01674 #else
01675                                               now->wordend_frame[0],
01676 #endif
01677 #else
01678                                               now->bestt,
01679 #endif
01680                                               new->score,
01681                                               prev_score,
01682                                               now->g[0],
01683 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01684 #ifdef PASS2_STRICT_IWCD
01685                                               new->wordend_gscore[0],
01686 #else
01687                                               now->wordend_gscore[0],
01688 #endif
01689 #else
01690                                               now->tail_g_score,
01691 #endif
01692                                               now->lscore,
01693 #ifdef CM_SEARCH
01694                                               new->cmscore[new->seqnum-1],
01695 #else
01696                                               LOG_ZERO,
01697 #endif
01698                                               r
01699                                               );
01700           } else {
01701             new->lastcontext = now->lastcontext;
01702             new->prevgraph = now->prevgraph;
01703           }
01704         } 
01705       } 
01706       
01707       
01708     }
01709     
01710     
01711 
01712 
01713 
01714 
01715 
01716 
01717 
01718     
01719 
01720 
01721 
01722 
01723 
01724 
01725 
01726 
01727 #ifdef DEBUG
01728     jlog("DEBUG: get next words\n");
01729 #endif
01730     if (r->lmtype == LM_PROB) {
01731       nwnum = ngram_nextwords(now, nextword, maxnwnum, r);
01732     } else if (r->lmtype == LM_DFA) {
01733       nwnum = dfa_nextwords(now, nextword, maxnwnum, r);
01734       
01735       
01736 
01737       while (nwnum < 0) {
01738         nextword = nw_expand(nextword, &maxnwnum, &nwroot, winfo->num);
01739         nwnum = dfa_nextwords(now, nextword, maxnwnum, r);
01740       }
01741     }
01742     if (debug2_flag) {
01743       jlog("DEBUG:  %d words extracted from wordtrellis\n", nwnum);
01744     }
01745 
01746     
01747 
01748 
01749     
01750 
01751 
01752 
01753 #ifdef DEBUG
01754     jlog("DEBUG: generate hypo\n");
01755 #endif
01756 
01757     if (r->lmtype == LM_DFA) {
01758       now_noise_calced = FALSE; 
01759     }
01760     i = dwrk->pushctr;          
01761 
01762 #ifdef CM_SEARCH
01763     
01764     cm_init(dwrk, winfo->num, jconf->annotate.cm_alpha
01765 #ifdef CM_MULTIPLE_ALPHA
01766             , jconf->annotate.cm_alpha_num
01767 #endif
01768             );
01769 #endif
01770 
01771     
01772     for (w = 0; w < nwnum; w++) {
01773       if (r->lmtype == LM_DFA) {
01774         
01775         if (! (winfo->wton[nextword[w]->id] >= cate_bgn && winfo->wton[nextword[w]->id] < cate_bgn + cate_num)) {
01776           continue;
01777         }
01778       }
01779       new = newnode(r);
01780 
01781       if (r->lmtype == LM_DFA) {
01782 
01783         if (nextword[w]->can_insert_sp == TRUE) {
01784           
01785           
01786           
01787           if (now_noise_calced == FALSE) {
01788             
01789             
01790 
01791             fornoise.id = gdfa->sp_id;
01792             now_noise = newnode(r);
01793             cpy_node(now_noise, now);
01794 #if 0
01795             now_noise_tmp = newnode(r);
01796             next_word(now, now_noise_tmp, &fornoise, param, r);
01797             scan_word(now_noise_tmp, param, r);
01798             for(t=0;t<peseqlen;t++) {
01799               now_noise->g[t] = max(now_noise_tmp->g[t], now->g[t]);
01800             }
01801             free_node(now_noise_tmp);
01802 #else
01803             
01804             
01805             if (jconf->pass2.looktrellis_flag) {
01806               if(!dfa_look_around(&fornoise, now, r)){
01807                 free_node(now_noise);
01808                 free_node(new);
01809                 continue;
01810               }
01811             }
01812             
01813             
01814             
01815 
01816             
01817 
01818             next_word(now, now_noise, &fornoise, param, r);
01819             scan_word(now_noise, param, r);
01820             for(t=0;t<peseqlen;t++) {
01821               now_noise->g[t] = max(now_noise->g[t], now->g[t]);
01822             }
01823             
01824 
01825             
01826 
01827             now_noise->seqnum--;
01828 #endif
01829             now_noise_calced = TRUE;
01830           }
01831           
01832           
01833           
01834           if (jconf->pass2.looktrellis_flag) {
01835             if(!dfa_look_around(nextword[w], now_noise, r)){
01836               free_node(new);
01837               continue;
01838             }
01839           }
01840           
01841           
01842           
01843           
01844           next_word(now_noise, new, nextword[w], param, r);
01845           
01846         } else {
01847           
01848           
01849           
01850           if (jconf->pass2.looktrellis_flag) {
01851             if(!dfa_look_around(nextword[w], now, r)){
01852               free_node(new);
01853               continue;
01854             }
01855           }
01856           
01857           
01858           
01859           
01860           next_word(now, new, nextword[w], param, r);
01861           
01862         }
01863       }
01864 
01865       if (r->lmtype == LM_PROB) {
01866 
01867         
01868 
01869         
01870 
01871         next_word(now, new, nextword[w], param, r);
01872 
01873       }
01874 
01875       if (new->score <= LOG_ZERO) { 
01876         free_node(new);
01877         continue;
01878       }
01879         
01880       dwrk->genectr++;
01881 
01882 #ifdef CM_SEARCH
01883       
01884       cm_store(dwrk, new);
01885 #else 
01886       
01887       
01888 
01889       
01890       if (can_put_to_stack(new, &bottom, &stacknum, stacksize) == -1) {
01891         free_node(new);
01892         continue;
01893       }
01894       
01895       if (r->graphout) {
01896         
01897         new->lastcontext = now->prevgraph;
01898         new->prevgraph = wordgraph_assign(new->seq[new->seqnum-2],
01899                                           new->seq[new->seqnum-1],
01900                                           (new->seqnum >= 3) ? new->seq[new->seqnum-3] : WORD_INVALID,
01901                                           new->bestt + 1,
01902 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01903 #ifdef PASS2_STRICT_IWCD
01904                                           
01905                                           new->wordend_frame[new->bestt],
01906 #else
01907                                           now->wordend_frame[new->bestt],
01908 #endif
01909 #else
01910                                           now->bestt,
01911 #endif
01912                                           new->score, prev_score,
01913 #ifdef PASS2_STRICT_IWCD
01914                                           new->g[new->bestt] - new->lscore,
01915 #else
01916                                           now->g[new->bestt+1],
01917 #endif
01918 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01919 #ifdef PASS2_STRICT_IWCD
01920                                           
01921                                           new->wordend_gscore[new->bestt],
01922 #else
01923                                           now->wordend_gscore[new->bestt],
01924 #endif
01925 #else
01926                                           now->tail_g_score,
01927 #endif
01928                                           now->lscore,
01929 #ifdef CM_SEARCH
01930                                           new->cmscore[new->seqnum-2],
01931 #else
01932                                           LOG_ZERO,
01933 #endif
01934                                           r
01935                                           );
01936       } 
01937       put_to_stack(new, &start, &bottom, &stacknum, stacksize);
01938       if (debug2_flag) {
01939         j = new->seq[new->seqnum-1];
01940         jlog("DEBUG:  %15s [%15s](id=%5d)(%f) [%d-%d] pushed\n",winfo->wname[j], winfo->woutput[j], j, new->score, new->estimated_next_t + 1, new->bestt);
01941       }
01942       dwrk->current = new;
01943       
01944       dwrk->pushctr++;
01945 #endif
01946     } 
01947 
01948 #ifdef CM_SEARCH
01949     
01950     cm_sum_score(dwrk
01951 #ifdef CM_MULTIPLE_ALPHA
01952                  , jconf->annotate.cm_alpha_bgn 
01953                  , jconf->annotate.cm_alpha_end
01954                  , jconf->annotate.cm_alpha_step
01955 #endif
01956                  );
01957     
01958     while ((new = cm_get_node(dwrk)) != NULL) {
01959       cm_set_score(dwrk, new
01960 #ifdef CM_MULTIPLE_ALPHA
01961                    , jconf->annotate.cm_alpha_bgn
01962                    , jconf->annotate.cm_alpha_end
01963                    , jconf->annotate.cm_alpha_step
01964 #endif
01965                    );
01966 #ifdef CM_SEARCH_LIMIT
01967       if (new->cmscore[new->seqnum-1] < jconf->annotate.cm_cut_thres
01968 #ifdef CM_SEARCH_LIMIT_AFTER
01969           && dwrk->finishnum > 0
01970 #endif
01971           ) {
01972         free_node(new);
01973         continue;
01974       }
01975 #endif 
01976       
01977 
01978 
01979       
01980       if (can_put_to_stack(new, &bottom, &stacknum, stacksize) == -1) {
01981         free_node(new);
01982         continue;
01983       }
01984 
01985       if (r->graphout) {
01986 
01987         
01988         new->lastcontext = now->prevgraph;
01989         new->prevgraph = wordgraph_assign(new->seq[new->seqnum-2],
01990                                           new->seq[new->seqnum-1],
01991                                           (new->seqnum >= 3) ? new->seq[new->seqnum-3] : WORD_INVALID,
01992                                           new->bestt + 1,
01993 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01994 #ifdef PASS2_STRICT_IWCD
01995                                           new->wordend_frame[new->bestt],
01996 #else
01997                                           now->wordend_frame[new->bestt],
01998 #endif
01999 #else
02000                                           now->bestt,
02001 #endif
02002                                           new->score, prev_score,
02003 #ifdef PASS2_STRICT_IWCD
02004                                           new->g[new->bestt] - new->lscore,
02005 #else
02006                                           now->g[new->bestt+1],
02007 #endif
02008 #ifdef GRAPHOUT_PRECISE_BOUNDARY
02009 #ifdef PASS2_STRICT_IWCD
02010                                           new->wordend_gscore[new->bestt],
02011 #else
02012                                           now->wordend_gscore[new->bestt],
02013 #endif
02014 #else
02015                                           now->tail_g_score,
02016 #endif
02017                                           now->lscore,
02018 #ifdef CM_SEARCH
02019                                           new->cmscore[new->seqnum-2],
02020 #else
02021                                           LOG_ZERO,
02022 #endif
02023                                           r
02024                                           );
02025       } 
02026       
02027       put_to_stack(new, &start, &bottom, &stacknum, stacksize);
02028       if (debug2_flag) {
02029         j = new->seq[new->seqnum-1];
02030         jlog("DEBUG:  %15s [%15s](id=%5d)(%f) [%d-%d] pushed\n",winfo->wname[j], winfo->woutput[j], j, new->score, new->estimated_next_t + 1, new->bestt);
02031       }
02032       dwrk->current = new;
02033       
02034       dwrk->pushctr++;
02035     }
02036 #endif
02037 
02038     if (debug2_flag) {
02039       jlog("DEBUG: %d pushed\n",dwrk->pushctr-i);
02040     }
02041     if (r->lmtype == LM_DFA) {
02042       if (now_noise_calced == TRUE) free_node(now_noise);
02043     }
02044     
02045     
02046 
02047 
02048 
02049     free_node(now);
02050 
02051   }
02052   
02053   
02054   
02055 
02056   
02057   
02058   
02059 
02060   if (dwrk->finishnum == 0) {           
02061     if (verbose_flag) {
02062       jlog("WARNING: %02d %s: got no candidates, output 1st pass result as a final result\n", r->config->id, r->config->name);
02063     }
02064     
02065     now = newnode(r);
02066     for (i=0;i<r->pass1_wnum;i++) {
02067       now->seq[i] = r->pass1_wseq[r->pass1_wnum-1-i];
02068     }
02069     now->seqnum = r->pass1_wnum;
02070     now->score = r->pass1_score;
02071 #ifdef CONFIDENCE_MEASURE
02072     
02073 #ifdef CM_MULTIPLE_ALPHA
02074     for(j=0;j<jconf->annotate.cm_alpha_num;j++) {
02075       for(i=0;i<now->seqnum;i++) now->cmscore[i][j] = 0.0;
02076     }
02077 #else
02078     for(i=0;i<now->seqnum;i++) now->cmscore[i] = 0.0;
02079 #endif
02080 #endif 
02081 
02082     if (r->lmtype == LM_PROB && r->config->successive.enabled) {
02083       
02084       
02085       segment_set_last_nword(now, r);
02086     }
02087     
02088     if (jconf->annotate.align_result_word_flag) word_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r);
02089     if (jconf->annotate.align_result_phoneme_flag) phoneme_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r);
02090     if (jconf->annotate.align_result_state_flag) state_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r);
02091 
02092     
02093     r->result.status = J_RESULT_STATUS_FAIL;
02094     
02095 
02096     free_node(now);
02097 
02098   } else {                      
02099     if (debug2_flag) {
02100       jlog("STAT: %02d %s: got %d candidates\n", r->config->id, r->config->name, dwrk->finishnum);
02101     }
02102       
02103 
02104       
02105 
02106       if (debug2_flag) jlog("DEBUG: done\n");
02107       result_reorder_and_output(&r_start, &r_bottom, &r_stacknum, jconf->output.output_hypo_maxnum, r, param);
02108       
02109       
02110   }
02111   
02112   
02113   
02114   if (verbose_flag) {
02115     jlog("STAT: %02d %s: %d generated, %d pushed, %d nodes popped in %d\n",
02116          r->config->id, r->config->name,
02117          dwrk->genectr, dwrk->pushctr, dwrk->popctr, backtrellis->framelen);
02118     jlog_flush();
02119 #ifdef GRAPHOUT_DYNAMIC
02120     if (r->graphout) {
02121       jlog("STAT: %02d %s: graph: %d merged", r->config->id, r->config->name, dynamic_merged_num);
02122 #ifdef GRAPHOUT_SEARCH
02123       jlog("S, %d terminated", terminate_search_num);
02124 #endif
02125       jlog(" in %d\n", dwrk->popctr);
02126     }
02127 #endif
02128   }
02129     
02130   if (dwrk->finishnum > 0 && r->graphout) {
02131     if (verbose_flag) jlog("STAT: ------ wordgraph post-processing begin ------\n");
02132     
02133     
02134     wordgraph_purge_leaf_nodes(&wordgraph_root, r);
02135 #ifdef GRAPHOUT_DEPTHCUT
02136     
02137     wordgraph_depth_cut(&wordgraph_root, r);
02138 #endif
02139 
02140     
02141 
02142 
02143 
02144     wordgraph_adjust_boundary(&wordgraph_root, r);
02145 
02146     if (jconf->graph.confnet) {
02147       
02148 
02149       
02150 
02151       
02152       r->graph_totalwordnum = wordgraph_sort_and_annotate_id(&wordgraph_root, r);
02153       
02154       wordgraph_check_coherence(wordgraph_root, r);
02155       
02156       graph_forward_backward(wordgraph_root, r);
02157       if (verbose_flag) jlog("STAT: ------ wordgraph post-processing end ------\n");
02158 
02159       r->result.wg = wordgraph_root;
02160 
02161       
02162 
02163 
02164 
02165 
02166       
02167       
02168       graph_make_order(wordgraph_root, r);
02169       
02170       r->result.confnet = confnet_create(wordgraph_root, r);
02171       
02172       
02173       
02174       graph_free_order();
02175       
02176       
02177 
02178     } else if (jconf->graph.lattice) {
02179       
02180 
02181       
02182       wordgraph_compaction_thesame(&wordgraph_root);
02183       
02184       wordgraph_compaction_exacttime(&wordgraph_root, r);
02185       
02186       wordgraph_compaction_neighbor(&wordgraph_root, r);
02187       
02188       r->graph_totalwordnum = wordgraph_sort_and_annotate_id(&wordgraph_root, r);
02189       
02190       wordgraph_check_coherence(wordgraph_root, r);
02191       
02192       graph_forward_backward(wordgraph_root, r);
02193       if (verbose_flag) jlog("STAT: ------ wordgraph post-processing end ------\n");
02194       
02195       r->result.wg = wordgraph_root;
02196       
02197 
02198     } else {
02199       j_internal_error("InternalError: graph generation specified but no output format specified?\n");
02200     }
02201 
02202     
02203     
02204   } 
02205 
02206   
02207   
02208   
02209   nw_free(nextword, nwroot);
02210   free_all_nodes(start);
02211   free_wordtrellis();
02212 #ifdef SCAN_BEAM
02213   free(dwrk->framemaxscore);
02214 #endif
02215   
02216   clear_stocker(dwrk);
02217 }
02218 
02219