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) > 0) {
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 free_node(now);
01104 }
01105
01106 if (now != NULL) free_node(now);
01107 free_all_nodes(*r_start);
01108 }
01109
01145 void
01146 pass2_finalize_on_no_result(RecogProcess *r, boolean use_1pass_as_final)
01147 {
01148 NODE *now;
01149 int i, j;
01150
01151
01152
01153
01154
01155 now = newnode(r);
01156 for (i=0;i<r->pass1_wnum;i++) {
01157 now->seq[i] = r->pass1_wseq[r->pass1_wnum-1-i];
01158 }
01159 now->seqnum = r->pass1_wnum;
01160 now->score = r->pass1_score;
01161 #ifdef CONFIDENCE_MEASURE
01162
01163 #ifdef CM_MULTIPLE_ALPHA
01164 for(j=0;j<jconf->annotate.cm_alpha_num;j++) {
01165 for(i=0;i<now->seqnum;i++) now->cmscore[i][j] = 0.0;
01166 }
01167 #else
01168 for(i=0;i<now->seqnum;i++) now->cmscore[i] = 0.0;
01169 #endif
01170 #endif
01171
01172 if (r->lmtype == LM_PROB && r->config->successive.enabled) {
01173
01174
01175 segment_set_last_nword(now, r);
01176 }
01177
01178 if (use_1pass_as_final) {
01179
01180
01181 store_result_pass2(now, r);
01182 r->result.status = J_RESULT_STATUS_SUCCESS;
01183 } else {
01184
01185 r->result.status = J_RESULT_STATUS_FAIL;
01186
01187 }
01188
01189 free_node(now);
01190 }
01191
01192
01193
01194
01195
01196
01224 void
01225 wchmm_fbs(HTK_Param *param, RecogProcess *r, int cate_bgn, int cate_num)
01226 {
01227
01228
01229 int stacknum;
01230 NODE *start = NULL;
01231 NODE *bottom = NULL;
01232
01233
01234
01235 int r_stacksize;
01236 int r_stacknum;
01237 NODE *r_start = NULL;
01238 NODE *r_bottom = NULL;
01239
01240
01241
01242 NEXTWORD fornoise;
01243
01244 NEXTWORD **nextword, *nwroot;
01245 int maxnwnum;
01246 int nwnum;
01247 NODE *now, *new;
01248 NODE *now_noise;
01249 boolean now_noise_calced;
01250 boolean acc;
01251 int t;
01252 int w,i,j;
01253 LOGPROB last_score = LOG_ZERO;
01254
01255 LOGPROB prev_score;
01256 WordGraph *wordgraph_root = NULL;
01257 boolean merged_p;
01258 #ifdef GRAPHOUT_DYNAMIC
01259 int dynamic_merged_num = 0;
01260 WordGraph *wtmp;
01261 LOGPROB lscore_prev;
01262 #endif
01263 #ifdef GRAPHOUT_SEARCH
01264 int terminate_search_num = 0;
01265 #endif
01266
01267
01268 int stacksize, ncan, maxhypo, peseqlen;
01269 JCONF_SEARCH *jconf;
01270 WORD_INFO *winfo;
01271 NGRAM_INFO *ngram;
01272 DFA_INFO *gdfa;
01273 BACKTRELLIS *backtrellis;
01274 StackDecode *dwrk;
01275
01276 if (r->lmtype == LM_DFA) {
01277 if (debug2_flag) jlog("DEBUG: only words in these categories will be expanded: %d-%d\n", cate_bgn, cate_bgn + cate_num-1);
01278 }
01279
01280
01281
01282
01283
01284
01285
01286 jconf = r->config;
01287 winfo = r->lm->winfo;
01288 if (r->lmtype == LM_PROB) {
01289 ngram = r->lm->ngram;
01290 } else if (r->lmtype == LM_DFA) {
01291 gdfa = r->lm->dfa;
01292 }
01293 backtrellis = r->backtrellis;
01294 dwrk = &(r->pass2);
01295
01296 stacksize = jconf->pass2.stack_size;
01297 ncan = jconf->pass2.nbest;
01298 maxhypo = jconf->pass2.hypo_overflow;
01299 peseqlen = backtrellis->framelen;
01300
01301
01302 r->peseqlen = backtrellis->framelen;
01303
01304
01305
01306
01307 nextword = nw_malloc(&maxnwnum, &nwroot, winfo->num);
01308
01309
01310 malloc_wordtrellis(r);
01311
01312
01313 start = bottom = NULL;
01314 stacknum = 0;
01315
01316
01317 r_stacksize = ncan;
01318 r_start = r_bottom = NULL;
01319 r_stacknum = 0;
01320
01321
01322
01323 dwrk->popctr = 0;
01324 dwrk->genectr = 0;
01325 dwrk->pushctr = 0;
01326 dwrk->finishnum = 0;
01327
01328 #ifdef CM_SEARCH
01329
01330 cm_init(dwrk, winfo->num, jconf->annotate.cm_alpha
01331 #ifdef CM_MULTIPLE_ALPHA
01332 , jconf->annotate.cm_alpha_num
01333 #endif
01334 );
01335 #endif
01336 #ifdef SCAN_BEAM
01337
01338 dwrk->framemaxscore = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
01339 envl_init(dwrk, peseqlen);
01340 #endif
01341
01342
01343
01344 if (jconf->pass2.enveloped_bestfirst_width >= 0) wb_init(dwrk);
01345
01346 if (jconf->graph.enabled) {
01347 wordgraph_init(r->wchmm);
01348 }
01349
01350
01351
01352
01353
01354
01355
01356 if (r->lmtype == LM_PROB) {
01357 nwnum = ngram_firstwords(nextword, peseqlen, maxnwnum, r);
01358 } else if (r->lmtype == LM_DFA) {
01359 nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r);
01360
01361
01362
01363 while (nwnum < 0) {
01364 nextword = nw_expand(nextword, &maxnwnum, &nwroot, winfo->num);
01365 nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r);
01366 }
01367 }
01368
01369 if (debug2_flag) {
01370 jlog("DEBUG: %d words in wordtrellis as first hypothesis\n", nwnum);
01371 }
01372
01373
01374 for (w = 0; w < nwnum; w++) {
01375 if (r->lmtype == LM_DFA) {
01376
01377 if (! (winfo->wton[nextword[w]->id] >= cate_bgn && winfo->wton[nextword[w]->id] < cate_bgn + cate_num)) {
01378 continue;
01379 }
01380 }
01381
01382 new = newnode(r);
01383 start_word(new, nextword[w], param, r);
01384 if (r->lmtype == LM_DFA) {
01385 if (new->score <= LOG_ZERO) {
01386 free_node(new);
01387 continue;
01388 }
01389 }
01390 dwrk->genectr++;
01391 #ifdef CM_SEARCH
01392
01393 cm_store(dwrk, new);
01394 #else
01395
01396 if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01397 dwrk->current = new;
01398
01399 if (jconf->graph.enabled) {
01400 new->prevgraph = NULL;
01401 new->lastcontext = NULL;
01402 }
01403 dwrk->pushctr++;
01404 }
01405 #endif
01406 }
01407 #ifdef CM_SEARCH
01408
01409 cm_sum_score(dwrk
01410 #ifdef CM_MULTIPLE_ALPHA
01411 , jconf->annotate.cm_alpha_bgn
01412 , jconf->annotate.cm_alpha_end
01413 , jconf->annotate.cm_alpha_step
01414 #endif
01415 );
01416
01417
01418 while ((new = cm_get_node(dwrk)) != NULL) {
01419 cm_set_score(dwrk, new
01420 #ifdef CM_MULTIPLE_ALPHA
01421 , jconf->annotate.cm_alpha_bgn
01422 , jconf->annotate.cm_alpha_end
01423 , jconf->annotate.cm_alpha_step
01424 #endif
01425 );
01426 #ifdef CM_SEARCH_LIMIT
01427 if (new->cmscore[new->seqnum-1] < jconf->annotate.cm_cut_thres
01428 #ifdef CM_SEARCH_LIMIT_AFTER
01429 && dwrk->finishnum > 0
01430 #endif
01431 ) {
01432 free_node(new);
01433 continue;
01434 }
01435 #endif
01436
01437 if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01438 dwrk->current = new;
01439
01440 if (r->graphout) {
01441 new->prevgraph = NULL;
01442 new->lastcontext = NULL;
01443 }
01444 dwrk->pushctr++;
01445 }
01446 }
01447 #endif
01448
01449 if (debug2_flag) {
01450 jlog("DEBUG: %d pushed\n", dwrk->pushctr);
01451 }
01452
01453
01454
01455
01456
01457 for (;;) {
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 #ifdef DEBUG
01472 jlog("DEBUG: get one hypothesis\n");
01473 #endif
01474 now = get_best_from_stack(&start,&stacknum);
01475 if (now == NULL) {
01476 jlog("WARNING: %02d %s: hypothesis stack exhausted, terminate search now\n", r->config->id, r->config->name);
01477 jlog("STAT: %02d %s: %d sentences have been found\n", r->config->id, r->config->name, dwrk->finishnum);
01478 break;
01479 }
01480
01481 if (now->score <= LOG_ZERO) {
01482 free_node(now);
01483 continue;
01484 }
01485
01486
01487
01488 if (r->graphout) {
01489 prev_score = now->score;
01490 }
01491
01492
01493
01494 if (jconf->pass2.enveloped_bestfirst_width >= 0) {
01495 if (!wb_ok(dwrk, now, jconf->pass2.enveloped_bestfirst_width)) {
01496
01497
01498
01499
01500
01501 if (debug2_flag) {
01502 jlog("DEBUG: popped but pruned by word envelope:");
01503 put_hypo_woutput(now, r->lm->winfo);
01504 }
01505 free_node(now);
01506 continue;
01507 }
01508 }
01509
01510 #ifdef CM_SEARCH_LIMIT_POP
01511 if (now->cmscore[now->seqnum-1] < jconf->annotate.cm_cut_thres_pop) {
01512 free_node(now);
01513 continue;
01514 }
01515 #endif
01516
01517 dwrk->popctr++;
01518
01519
01520
01521 if (debug2_flag) {
01522 jlog("DEBUG: --- pop %d:\n", dwrk->popctr);
01523 jlog("DEBUG: "); put_hypo_woutput(now, r->lm->winfo);
01524 jlog("DEBUG: "); put_hypo_wname(now, r->lm->winfo);
01525 jlog("DEBUG: %d words, f=%f, g=%f\n", now->seqnum, now->score, now->g[now->bestt]);
01526 jlog("DEBUG: last word on trellis: [%d-%d]\n", now->estimated_next_t + 1, now->bestt);
01527 }
01528
01529 dwrk->current = now;
01530
01531
01532 if (r->graphout) {
01533
01534 #ifdef GRAPHOUT_DYNAMIC
01535
01536 wtmp = wordgraph_check_merge(now->prevgraph, &wordgraph_root, now->seq[now->seqnum-1], &merged_p, jconf);
01537 if (wtmp != NULL) {
01538 dynamic_merged_num++;
01539
01540 lscore_prev = (now->prevgraph) ? now->prevgraph->lscore_tmp : 0.0;
01541
01542 if (now->prevgraph != NULL) {
01543 if (now->prevgraph->saved) {
01544 j_internal_error("wchmm_fbs: already saved??\n");
01545 }
01546 wordgraph_free(now->prevgraph);
01547 }
01548
01549 if (now->lastcontext != NULL
01550 && now->lastcontext != wtmp
01551 ) {
01552 wordgraph_check_and_add_leftword(now->lastcontext, wtmp, lscore_prev);
01553 #ifdef GRAPHOUT_SEARCH_CONSIDER_RIGHT
01554 if (merged_p) {
01555 if (wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev) == FALSE) {
01556 merged_p = TRUE;
01557 } else {
01558 merged_p = FALSE;
01559 }
01560 } else {
01561 wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev);
01562 }
01563 #else
01564 wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev);
01565 #endif
01566 }
01567
01568 now->prevgraph = wtmp;
01569
01570
01571
01572 } else {
01573 wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root);
01574 }
01575 #ifdef GRAPHOUT_SEARCH
01576
01577 if (merged_p && now->endflag == FALSE
01578 #ifdef GRAPHOUT_SEARCH_DELAY_TERMINATION
01579
01580
01581 && (jconf->graph.graphout_search_delay == FALSE || dwrk->finishnum > 0)
01582 #endif
01583 ) {
01584 terminate_search_num++;
01585 free_node(now);
01586 continue;
01587 }
01588 #endif
01589 #else
01590
01591 wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root);
01592 #endif
01593 }
01594
01595
01596
01597 envl_update(dwrk, now, peseqlen);
01598
01599
01600
01601
01602
01603
01604
01605
01606 #ifdef DEBUG
01607 VERMES("endflag check\n");
01608 #endif
01609
01610 if (now->endflag) {
01611 if (debug2_flag) {
01612 jlog("DEBUG: This is a full sentence candidate\n");
01613 }
01614
01615 if (now->score == last_score) {
01616 free_node(now);
01617 continue;
01618 } else {
01619 last_score = now->score;
01620 }
01621
01622 dwrk->finishnum++;
01623 if (debug2_flag) {
01624 jlog("DEBUG: %d-th sentence found\n", dwrk->finishnum);
01625 }
01626
01627
01628
01629
01630
01631 put_to_stack(now, &r_start, &r_bottom, &r_stacknum, r_stacksize);
01632
01633
01634 if (dwrk->finishnum >= ncan) {
01635 break;
01636 } else {
01637 continue;
01638 }
01639
01640 }
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 #ifdef DEBUG
01651 jlog("DEBUG: loop end check\n");
01652 #endif
01653 if (dwrk->popctr >= maxhypo) {
01654 jlog("WARNING: %02d %s: num of popped hypotheses reached the limit (%d)\n", r->config->id, r->config->name, maxhypo);
01655
01656
01657 if (debug2_flag) put_all_in_stack(&start, &stacknum, r->lm->winfo);
01658 free_node(now);
01659 break;
01660 }
01661
01662
01663 if (now->seqnum >= MAXSEQNUM) {
01664 jlog("ERROR: sentence length exceeded system limit ( > %d)\n", MAXSEQNUM);
01665 free_node(now);
01666 continue;
01667 }
01668
01669 #ifndef GRAPHOUT_PRECISE_BOUNDARY
01670 if (r->graphout) {
01671
01672
01673 if(!jconf->am.ccd_flag) {
01674 now->tail_g_score = now->g[now->bestt];
01675 }
01676 }
01677 #endif
01678
01679
01680
01681
01682
01683 #ifdef DEBUG
01684 jlog("DEBUG: scan_word\n");
01685 #endif
01686 scan_word(now, param, r);
01687 if (now->score < LOG_ZERO) {
01688 jlog("WARNING: too low score, ignore: score=%f",now->score);
01689 put_hypo_woutput(now, r->lm->winfo);
01690 free_node(now);
01691 continue;
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703 #ifdef DEBUG
01704 jlog("DEBUG: accept check\n");
01705 #endif
01706
01707 if (r->lmtype == LM_PROB) {
01708 acc = ngram_acceptable(now, r);
01709 } else if (r->lmtype == LM_DFA) {
01710 acc = dfa_acceptable(now, r);
01711 }
01712 if (acc && now->estimated_next_t <= 5) {
01713 new = newnode(r);
01714
01715
01716 last_next_word(now, new, param, r);
01717 if (debug2_flag) {
01718 jlog("DEBUG: This is acceptable as a sentence candidate\n");
01719 }
01720
01721
01722 if (new->score <= LOG_ZERO) {
01723 if (debug2_flag) {
01724 jlog("DEBUG: But invalid because Viterbi pass does not reach the 0th frame\n");
01725 }
01726 free_node(new);
01727 free_node(now);
01728 continue;
01729 }
01730
01731
01732 if (debug2_flag) {
01733 jlog("DEBUG This hypo itself was pushed with final score=%f\n", new->score);
01734 }
01735 new->endflag = TRUE;
01736 if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) {
01737 if (r->graphout) {
01738 if (new->score > LOG_ZERO) {
01739 new->lastcontext = now->prevgraph;
01740 new->prevgraph = wordgraph_assign(new->seq[new->seqnum-1],
01741 WORD_INVALID,
01742 (new->seqnum >= 2) ? new->seq[new->seqnum-2] : WORD_INVALID,
01743 0,
01744 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01745
01746 #ifdef PASS2_STRICT_IWCD
01747 new->wordend_frame[0],
01748 #else
01749 now->wordend_frame[0],
01750 #endif
01751 #else
01752 now->bestt,
01753 #endif
01754 new->score,
01755 prev_score,
01756 now->g[0],
01757 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01758 #ifdef PASS2_STRICT_IWCD
01759 new->wordend_gscore[0],
01760 #else
01761 now->wordend_gscore[0],
01762 #endif
01763 #else
01764 now->tail_g_score,
01765 #endif
01766 now->lscore,
01767 #ifdef CM_SEARCH
01768 new->cmscore[new->seqnum-1],
01769 #else
01770 LOG_ZERO,
01771 #endif
01772 r
01773 );
01774 } else {
01775 new->lastcontext = now->lastcontext;
01776 new->prevgraph = now->prevgraph;
01777 }
01778 }
01779 }
01780
01781
01782 }
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801 #ifdef DEBUG
01802 jlog("DEBUG: get next words\n");
01803 #endif
01804 if (r->lmtype == LM_PROB) {
01805 nwnum = ngram_nextwords(now, nextword, maxnwnum, r);
01806 } else if (r->lmtype == LM_DFA) {
01807 nwnum = dfa_nextwords(now, nextword, maxnwnum, r);
01808
01809
01810
01811 while (nwnum < 0) {
01812 nextword = nw_expand(nextword, &maxnwnum, &nwroot, winfo->num);
01813 nwnum = dfa_nextwords(now, nextword, maxnwnum, r);
01814 }
01815 }
01816 if (debug2_flag) {
01817 jlog("DEBUG: %d words extracted from wordtrellis\n", nwnum);
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827 #ifdef DEBUG
01828 jlog("DEBUG: generate hypo\n");
01829 #endif
01830
01831 if (r->lmtype == LM_DFA) {
01832 now_noise_calced = FALSE;
01833 }
01834 i = dwrk->pushctr;
01835
01836 #ifdef CM_SEARCH
01837
01838 cm_init(dwrk, winfo->num, jconf->annotate.cm_alpha
01839 #ifdef CM_MULTIPLE_ALPHA
01840 , jconf->annotate.cm_alpha_num
01841 #endif
01842 );
01843 #endif
01844
01845
01846 for (w = 0; w < nwnum; w++) {
01847 if (r->lmtype == LM_DFA) {
01848
01849 if (! (winfo->wton[nextword[w]->id] >= cate_bgn && winfo->wton[nextword[w]->id] < cate_bgn + cate_num)) {
01850 continue;
01851 }
01852 }
01853 new = newnode(r);
01854
01855 if (r->lmtype == LM_DFA) {
01856
01857 if (nextword[w]->can_insert_sp == TRUE) {
01858
01859
01860
01861 if (now_noise_calced == FALSE) {
01862
01863
01864
01865 fornoise.id = gdfa->sp_id;
01866 now_noise = newnode(r);
01867 cpy_node(now_noise, now);
01868 #if 0
01869 now_noise_tmp = newnode(r);
01870 next_word(now, now_noise_tmp, &fornoise, param, r);
01871 scan_word(now_noise_tmp, param, r);
01872 for(t=0;t<peseqlen;t++) {
01873 now_noise->g[t] = max(now_noise_tmp->g[t], now->g[t]);
01874 }
01875 free_node(now_noise_tmp);
01876 #else
01877
01878
01879 if (jconf->pass2.looktrellis_flag) {
01880 if(!dfa_look_around(&fornoise, now, r)){
01881 free_node(now_noise);
01882 free_node(new);
01883 continue;
01884 }
01885 }
01886
01887
01888
01889
01890
01891
01892 next_word(now, now_noise, &fornoise, param, r);
01893 scan_word(now_noise, param, r);
01894 for(t=0;t<peseqlen;t++) {
01895 now_noise->g[t] = max(now_noise->g[t], now->g[t]);
01896 }
01897
01898
01899
01900
01901 now_noise->seqnum--;
01902 #endif
01903 now_noise_calced = TRUE;
01904 }
01905
01906
01907
01908 if (jconf->pass2.looktrellis_flag) {
01909 if(!dfa_look_around(nextword[w], now_noise, r)){
01910 free_node(new);
01911 continue;
01912 }
01913 }
01914
01915
01916
01917
01918 next_word(now_noise, new, nextword[w], param, r);
01919
01920 } else {
01921
01922
01923
01924 if (jconf->pass2.looktrellis_flag) {
01925 if(!dfa_look_around(nextword[w], now, r)){
01926 free_node(new);
01927 continue;
01928 }
01929 }
01930
01931
01932
01933
01934 next_word(now, new, nextword[w], param, r);
01935
01936 }
01937 }
01938
01939 if (r->lmtype == LM_PROB) {
01940
01941
01942
01943
01944
01945 next_word(now, new, nextword[w], param, r);
01946
01947 }
01948
01949 if (new->score <= LOG_ZERO) {
01950 free_node(new);
01951 continue;
01952 }
01953
01954 dwrk->genectr++;
01955
01956 #ifdef CM_SEARCH
01957
01958 cm_store(dwrk, new);
01959 #else
01960
01961
01962
01963
01964 if (can_put_to_stack(new, &bottom, &stacknum, stacksize) == -1) {
01965 free_node(new);
01966 continue;
01967 }
01968
01969 if (r->graphout) {
01970
01971 new->lastcontext = now->prevgraph;
01972 new->prevgraph = wordgraph_assign(new->seq[new->seqnum-2],
01973 new->seq[new->seqnum-1],
01974 (new->seqnum >= 3) ? new->seq[new->seqnum-3] : WORD_INVALID,
01975 new->bestt + 1,
01976 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01977 #ifdef PASS2_STRICT_IWCD
01978
01979 new->wordend_frame[new->bestt],
01980 #else
01981 now->wordend_frame[new->bestt],
01982 #endif
01983 #else
01984 now->bestt,
01985 #endif
01986 new->score, prev_score,
01987 #ifdef PASS2_STRICT_IWCD
01988 new->g[new->bestt] - new->lscore,
01989 #else
01990 now->g[new->bestt+1],
01991 #endif
01992 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01993 #ifdef PASS2_STRICT_IWCD
01994
01995 new->wordend_gscore[new->bestt],
01996 #else
01997 now->wordend_gscore[new->bestt],
01998 #endif
01999 #else
02000 now->tail_g_score,
02001 #endif
02002 now->lscore,
02003 #ifdef CM_SEARCH
02004 new->cmscore[new->seqnum-2],
02005 #else
02006 LOG_ZERO,
02007 #endif
02008 r
02009 );
02010 }
02011 put_to_stack(new, &start, &bottom, &stacknum, stacksize);
02012 if (debug2_flag) {
02013 j = new->seq[new->seqnum-1];
02014 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);
02015 }
02016 dwrk->current = new;
02017
02018 dwrk->pushctr++;
02019 #endif
02020 }
02021
02022 #ifdef CM_SEARCH
02023
02024 cm_sum_score(dwrk
02025 #ifdef CM_MULTIPLE_ALPHA
02026 , jconf->annotate.cm_alpha_bgn
02027 , jconf->annotate.cm_alpha_end
02028 , jconf->annotate.cm_alpha_step
02029 #endif
02030 );
02031
02032 while ((new = cm_get_node(dwrk)) != NULL) {
02033 cm_set_score(dwrk, new
02034 #ifdef CM_MULTIPLE_ALPHA
02035 , jconf->annotate.cm_alpha_bgn
02036 , jconf->annotate.cm_alpha_end
02037 , jconf->annotate.cm_alpha_step
02038 #endif
02039 );
02040 #ifdef CM_SEARCH_LIMIT
02041 if (new->cmscore[new->seqnum-1] < jconf->annotate.cm_cut_thres
02042 #ifdef CM_SEARCH_LIMIT_AFTER
02043 && dwrk->finishnum > 0
02044 #endif
02045 ) {
02046 free_node(new);
02047 continue;
02048 }
02049 #endif
02050
02051
02052
02053
02054 if (can_put_to_stack(new, &bottom, &stacknum, stacksize) == -1) {
02055 free_node(new);
02056 continue;
02057 }
02058
02059 if (r->graphout) {
02060
02061
02062 new->lastcontext = now->prevgraph;
02063 new->prevgraph = wordgraph_assign(new->seq[new->seqnum-2],
02064 new->seq[new->seqnum-1],
02065 (new->seqnum >= 3) ? new->seq[new->seqnum-3] : WORD_INVALID,
02066 new->bestt + 1,
02067 #ifdef GRAPHOUT_PRECISE_BOUNDARY
02068 #ifdef PASS2_STRICT_IWCD
02069 new->wordend_frame[new->bestt],
02070 #else
02071 now->wordend_frame[new->bestt],
02072 #endif
02073 #else
02074 now->bestt,
02075 #endif
02076 new->score, prev_score,
02077 #ifdef PASS2_STRICT_IWCD
02078 new->g[new->bestt] - new->lscore,
02079 #else
02080 now->g[new->bestt+1],
02081 #endif
02082 #ifdef GRAPHOUT_PRECISE_BOUNDARY
02083 #ifdef PASS2_STRICT_IWCD
02084 new->wordend_gscore[new->bestt],
02085 #else
02086 now->wordend_gscore[new->bestt],
02087 #endif
02088 #else
02089 now->tail_g_score,
02090 #endif
02091 now->lscore,
02092 #ifdef CM_SEARCH
02093 new->cmscore[new->seqnum-2],
02094 #else
02095 LOG_ZERO,
02096 #endif
02097 r
02098 );
02099 }
02100
02101 put_to_stack(new, &start, &bottom, &stacknum, stacksize);
02102 if (debug2_flag) {
02103 j = new->seq[new->seqnum-1];
02104 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);
02105 }
02106 dwrk->current = new;
02107
02108 dwrk->pushctr++;
02109 }
02110 #endif
02111
02112 if (debug2_flag) {
02113 jlog("DEBUG: %d pushed\n",dwrk->pushctr-i);
02114 }
02115 if (r->lmtype == LM_DFA) {
02116 if (now_noise_calced == TRUE) free_node(now_noise);
02117 }
02118
02119
02120
02121
02122
02123 free_node(now);
02124
02125 }
02126
02127
02128
02129
02130
02131 if (dwrk->finishnum == 0) {
02132
02133
02134 if (verbose_flag) {
02135 if (r->config->sw.fallback_pass1_flag) {
02136 jlog("%02d %s: got no candidates, output 1st pass result as a final result\n", r->config->id, r->config->name);
02137 } else {
02138 jlog("WARNING: %02d %s: got no candidates, search failed\n", r->config->id, r->config->name);
02139 }
02140 }
02141 pass2_finalize_on_no_result(r, r->config->sw.fallback_pass1_flag);
02142
02143 } else {
02144
02145 if (debug2_flag) {
02146 jlog("STAT: %02d %s: got %d candidates\n", r->config->id, r->config->name, dwrk->finishnum);
02147 }
02148
02149
02150
02151
02152 if (debug2_flag) jlog("DEBUG: done\n");
02153 result_reorder_and_output(&r_start, &r_bottom, &r_stacknum, jconf->output.output_hypo_maxnum, r, param);
02154
02155 r->result.status = J_RESULT_STATUS_SUCCESS;
02156
02157
02158 }
02159
02160
02161
02162 if (verbose_flag) {
02163 jlog("STAT: %02d %s: %d generated, %d pushed, %d nodes popped in %d\n",
02164 r->config->id, r->config->name,
02165 dwrk->genectr, dwrk->pushctr, dwrk->popctr, backtrellis->framelen);
02166 jlog_flush();
02167 #ifdef GRAPHOUT_DYNAMIC
02168 if (r->graphout) {
02169 jlog("STAT: %02d %s: graph: %d merged", r->config->id, r->config->name, dynamic_merged_num);
02170 #ifdef GRAPHOUT_SEARCH
02171 jlog("S, %d terminated", terminate_search_num);
02172 #endif
02173 jlog(" in %d\n", dwrk->popctr);
02174 }
02175 #endif
02176 }
02177
02178 if (dwrk->finishnum > 0 && r->graphout) {
02179 if (verbose_flag) jlog("STAT: ------ wordgraph post-processing begin ------\n");
02180
02181
02182 wordgraph_purge_leaf_nodes(&wordgraph_root, r);
02183 #ifdef GRAPHOUT_DEPTHCUT
02184
02185 wordgraph_depth_cut(&wordgraph_root, r);
02186 #endif
02187
02188
02189
02190
02191
02192 wordgraph_adjust_boundary(&wordgraph_root, r);
02193
02194 if (jconf->graph.confnet) {
02195
02196
02197
02198
02199
02200 r->graph_totalwordnum = wordgraph_sort_and_annotate_id(&wordgraph_root, r);
02201
02202 wordgraph_check_coherence(wordgraph_root, r);
02203
02204 graph_forward_backward(wordgraph_root, r);
02205 if (verbose_flag) jlog("STAT: ------ wordgraph post-processing end ------\n");
02206
02207 r->result.wg = wordgraph_root;
02208
02209
02210
02211
02212
02213
02214
02215
02216 graph_make_order(wordgraph_root, r);
02217
02218 r->result.confnet = confnet_create(wordgraph_root, r);
02219
02220
02221
02222 graph_free_order(r);
02223
02224
02225
02226 } else if (jconf->graph.lattice) {
02227
02228
02229
02230 wordgraph_compaction_thesame(&wordgraph_root);
02231
02232 wordgraph_compaction_exacttime(&wordgraph_root, r);
02233
02234 wordgraph_compaction_neighbor(&wordgraph_root, r);
02235
02236 r->graph_totalwordnum = wordgraph_sort_and_annotate_id(&wordgraph_root, r);
02237
02238 wordgraph_check_coherence(wordgraph_root, r);
02239
02240 graph_forward_backward(wordgraph_root, r);
02241 if (verbose_flag) jlog("STAT: ------ wordgraph post-processing end ------\n");
02242
02243 r->result.wg = wordgraph_root;
02244
02245
02246 } else {
02247 j_internal_error("InternalError: graph generation specified but no output format specified?\n");
02248 }
02249
02250
02251
02252 }
02253
02254
02255
02256
02257 nw_free(nextword, nwroot);
02258 free_all_nodes(start);
02259 free_wordtrellis(dwrk);
02260 #ifdef SCAN_BEAM
02261 free(dwrk->framemaxscore);
02262 #endif
02263
02264 clear_stocker(dwrk);
02265 }
02266
02267