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