00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 #include "lextree.h"
00136 #include "fillpen.h"
00137
00138
00139
00140
00141
00142
00143
00144
00151 static lextree_t * lextree_build(bin_mdef_t *mdef,
00152 tmat_t *tmat,
00153 s3dict_t *dict,
00154 dict2pid_t *dict2pid,
00155 wordprob_t *wordprob,
00156 int32 n_word,
00157 s3cipid_t *lc,
00159 int32 type
00160 );
00161
00162
00163 static lextree_node_t *
00164 lextree_node_alloc(lextree_t *lextree, int32 wid, int32 prob,
00165 int32 comp, int32 ssid, s3cipid_t ci, s3cipid_t rc,
00166 s3tmatid_t tmat)
00167 {
00168 lextree_node_t *ln;
00169
00170 ln = (lextree_node_t *) ckd_calloc(1, sizeof(lextree_node_t));
00171 ln->children = NULL;
00172 ln->wid = wid;
00173 ln->prob = prob;
00174 ln->ssid = ssid;
00175 ln->ci = (s3cipid_t) ci;
00176 ln->rc = rc;
00177 ln->composite = comp;
00178 hmm_init((comp ? lextree->comctx : lextree->ctx), (hmm_t *)ln, FALSE, ssid, tmat);
00179
00180 return ln;
00181 }
00182
00183 static void
00184 lextree_node_free(lextree_node_t * ln)
00185 {
00186 if (ln) {
00187 hmm_deinit((hmm_t *)ln);
00188 ckd_free(ln);
00189 }
00190 }
00191
00192
00193 static int32
00194 lextree_ug_wordprob(ngram_model_t * lm, s3dict_t * dict, wordprob_t * wp)
00195 {
00196 int32 i, j, n;
00197 int32 unk, startwid, endwid;
00198
00199 n = s3dict_size(dict);
00200 unk = ngram_unknown_wid(lm);
00201 startwid = ngram_wid(lm, S3_START_WORD);
00202 endwid = ngram_wid(lm, S3_FINISH_WORD);
00203
00204
00205
00206
00207
00208 for (i = 0, j = 0; i < n; i++) {
00209 int32 lmwid, nbo;
00210
00211 if (s3dict_basewid(dict, i) != i)
00212 continue;
00213 lmwid = ngram_wid(lm, s3dict_wordstr(dict, s3dict_basewid(dict, i)));
00214 if (lmwid == unk || lmwid == startwid || lmwid == endwid)
00215 continue;
00216 wp[j].prob = ngram_ng_score(lm, lmwid, NULL, 0, &nbo);
00217 wp[j].wid = i;
00218 ++j;
00219 }
00220
00221 return j;
00222 }
00223
00224
00225 static int32
00226 wid_wordprob2alt(s3dict_t * dict, wordprob_t * wp, int32 n)
00227 {
00228 int32 i, j;
00229 s3wid_t w;
00230
00231 for (i = 0, j = n; i < n; i++) {
00232 w = wp[i].wid;
00233 for (w = s3dict_nextalt(dict, w); IS_S3WID(w);
00234 w = s3dict_nextalt(dict, w)) {
00235
00236 wp[j].wid = w;
00237 wp[j].prob = wp[i].prob;
00238 j++;
00239 }
00240 }
00241
00242 return j;
00243 }
00244
00245 lextree_t *
00246 lextree_init(bin_mdef_t *mdef, tmat_t *tmat, s3dict_t *dict, dict2pid_t *dict2pid,
00247 fillpen_t *fp, ngram_model_t * lm, const char *lmname, int32 istreeUgProb,
00248 int32 bReport, int32 type)
00249 {
00250 s3cipid_t *lc;
00251 s3cipid_t ci;
00252 bitvec_t *lc_active;
00253 s3wid_t w;
00254 int32 n, n_lc;
00255 int32 i, j;
00256 wordprob_t *wp;
00257 lextree_t *ltree;
00258
00259
00260 lc = (s3cipid_t *) ckd_calloc(bin_mdef_n_ciphone(mdef) + 1,
00261 sizeof(s3cipid_t));
00262 lc_active = bitvec_alloc(bin_mdef_n_ciphone(mdef));
00263 wp = (wordprob_t *) ckd_calloc(s3dict_size(dict), sizeof(wordprob_t));
00264
00265 for (w = 0; w < s3dict_size(dict); w++) {
00266 ci = s3dict_pron(dict, w, s3dict_pronlen(dict, w) - 1);
00267 if (!bin_mdef_is_fillerphone(mdef, (int) ci))
00268 bitvec_set(lc_active, ci);
00269 }
00270 ci = bin_mdef_silphone(mdef);
00271 bitvec_set(lc_active, ci);
00272
00273 for (ci = 0, n_lc = 0; ci < bin_mdef_n_ciphone(mdef); ci++) {
00274 if (bitvec_is_set(lc_active, ci))
00275 lc[n_lc++] = ci;
00276 }
00277 lc[n_lc] = BAD_S3CIPID;
00278
00279 if (bReport)
00280 E_INFO("Creating Unigram Table for lm (name: %s)\n", lmname);
00281
00282
00283
00284 n = 0;
00285
00286 for (j = 0; j < s3dict_size(dict); j++) {
00287 wp[j].wid = -1;
00288 wp[j].prob = -1;
00289 }
00290 n = lextree_ug_wordprob(lm, dict, wp);
00291
00292 if (bReport)
00293 E_INFO("Size of word table after unigram + words in class: %d.\n",
00294 n);
00295 if (n < 1)
00296 E_FATAL("%d active words in %s\n", n, lmname);
00297
00298 n = wid_wordprob2alt(dict, wp, n);
00299
00300 if (bReport)
00301 E_INFO("Size of word table after adding alternative prons: %d.\n",
00302 n);
00303 if (istreeUgProb == 0) {
00304 for (i = 0; i < n; i++) {
00305 wp[i].prob = -1;
00306 }
00307 }
00308 ltree = lextree_build(mdef, tmat, dict, dict2pid,
00309 wp, n, lc, type);
00310 ltree->dict = dict;
00311 ltree->mdef = mdef;
00312 ltree->tmat = tmat;
00313 ltree->dict2pid = dict2pid;
00314 ltree->fp = fp;
00315 ltree->lm = ngram_model_retain(lm);
00316
00317 ckd_free((void *) wp);
00318 ckd_free((void *) lc);
00319 bitvec_free(lc_active);
00320
00321 strcpy(ltree->prev_word, "");
00322 return ltree;
00323 }
00324
00325 lextree_t *
00326 fillertree_init(bin_mdef_t *mdef, tmat_t *tmat, s3dict_t *dict,
00327 dict2pid_t *dict2pid, fillpen_t *fp)
00328 {
00329 int32 n;
00330 int32 i;
00331 wordprob_t *wp;
00332 lextree_t *ltree;
00333
00334 n = 0;
00335
00336 wp = (wordprob_t *) ckd_calloc(s3dict_size(dict), sizeof(wordprob_t));
00337
00338 for (i = s3dict_filler_start(dict); i <= s3dict_filler_end(dict); i++) {
00339 if (s3dict_filler_word(dict, i)) {
00340 E_DEBUG(1,("Filler word %s prob %d\n",
00341 s3dict_wordstr(dict, i), fillpen(fp, i)));
00342 wp[n].wid = i;
00343 wp[n].prob = fillpen(fp, i);
00344 n++;
00345 }
00346 }
00347
00348 ltree = lextree_build(mdef, tmat, dict, dict2pid, wp, n, NULL, LEXTREE_TYPE_FILLER);
00349 ltree->mdef = mdef;
00350 ltree->tmat = tmat;
00351 ltree->dict = dict;
00352 ltree->fp = fp;
00353 ltree->dict2pid = dict2pid;
00354
00355 ckd_free(wp);
00356 return ltree;
00357 }
00358
00359 void
00360 lextree_report(lextree_t * ltree)
00361 {
00362 E_INFO_NOFN("lextree_t, report:\n");
00363 E_INFO_NOFN("Parameters of the lexical tree. \n");
00364 E_INFO_NOFN("Type of the tree %d (0:unigram, 1: 2g, 2: 3g etc.)\n",
00365 ltree->type);
00366 E_INFO_NOFN("Number of left contexts %d \n", ltree->n_lc);
00367 E_INFO_NOFN("Number of root nodes %d\n", glist_count(ltree->root));
00368 E_INFO_NOFN("Number of nodes %d \n", ltree->n_node);
00369 E_INFO_NOFN("Number of links in the tree %d\n",
00370 num_lextree_links(ltree));
00371
00372
00373
00374
00375
00376
00377 if (ltree->prev_word)
00378 E_INFO_NOFN("The previous word for this tree %s \n",
00379 ltree->prev_word);
00380
00381 E_INFO_NOFN("The size of a node of the lexical tree %d \n",
00382 sizeof(lextree_node_t));
00383 E_INFO_NOFN("The size of a gnode_t %d \n", sizeof(gnode_t));
00384 E_INFO_NOFN("\n");
00385
00386 }
00387
00388 int32
00389 lextree_subtree_num_links(lextree_node_t * ln)
00390 {
00391 gnode_t *gn;
00392 int32 numlink = 0;
00393 if (ln == NULL) {
00394 return 0;
00395 }
00396 else {
00397 for (gn = ln->children; gn; gn = gnode_next(gn)) {
00398 ln = (lextree_node_t *) gnode_ptr(gn);
00399 numlink += 1 + lextree_subtree_num_links(ln);
00400 }
00401 return numlink;
00402 }
00403 }
00404
00405 int32
00406 num_lextree_links(lextree_t * ltree)
00407 {
00408 gnode_t *gn;
00409 int32 numlink = 0;
00410 lextree_node_t *ln;
00411
00412 for (gn = ltree->root; gn; gn = gnode_next(gn)) {
00413 ln = (lextree_node_t *) gnode_ptr(gn);
00414 numlink += 1 + lextree_subtree_num_links(ln);
00415 }
00416
00417 return numlink;
00418
00419 }
00420
00421
00422 lextree_t *
00423 lextree_build(bin_mdef_t *mdef, tmat_t *tmat,
00424 s3dict_t *dict, dict2pid_t *d2p,
00425 wordprob_t * wordprob, int32 n_word,
00426 s3cipid_t * lc, int32 type)
00427 {
00428 s3ssid_t *ldiph_lc;
00429 lextree_t *lextree;
00430 lextree_lcroot_t *lcroot;
00431 int32 n_lc, n_node, n_ci, n_sseq, pronlen, ssid, prob, ci, rc, wid, np,
00432 n_st;
00433 lextree_node_t *ln = 0, **parent, **ssid2ln;
00434 gnode_t *gn = 0;
00435 bitvec_t **ssid_lc;
00436 int32 i, j, k, p;
00437
00438 n_ci = bin_mdef_n_ciphone(mdef);
00439 n_sseq = bin_mdef_n_sseq(mdef);
00440 n_st = bin_mdef_n_emit_state(mdef);
00441
00442 lextree = (lextree_t *) ckd_calloc(1, sizeof(lextree_t));
00443 lextree->root = NULL;
00444 lextree_type(lextree) = type;
00445
00446
00447 lextree->ctx = hmm_context_init(n_st,
00448 tmat->tp, NULL,
00449 mdef->sseq);
00450 lextree->comctx = hmm_context_init(n_st,
00451 tmat->tp, NULL,
00452 d2p->comsseq);
00453
00454
00455 ssid2ln =
00456 (lextree_node_t **) ckd_calloc(n_sseq, sizeof(lextree_node_t *));
00457
00458
00459 ssid_lc = (bitvec_t **) ckd_calloc(n_sseq, sizeof(bitvec_t *));
00460 for (i = 0; i < n_sseq; i++)
00461 ssid_lc[i] = bitvec_alloc(n_ci);
00462
00463 n_node = 0;
00464
00465
00466 n_lc = 0;
00467 lcroot = NULL;
00468 if (!lc) {
00469 lextree->n_lc = 0;
00470 lextree->lcroot = NULL;
00471
00472 parent =
00473 (lextree_node_t **) ckd_calloc(1, sizeof(lextree_node_t *));
00474 }
00475 else {
00476 for (n_lc = 0; IS_S3CIPID(lc[n_lc]); n_lc++);
00477 assert(n_lc > 0);
00478
00479 lextree->n_lc = n_lc;
00480 lcroot =
00481 (lextree_lcroot_t *) ckd_calloc(n_lc,
00482 sizeof(lextree_lcroot_t));
00483 lextree->lcroot = lcroot;
00484
00485 for (i = 0; i < n_lc; i++) {
00486 lcroot[i].lc = lc[i];
00487 lcroot[i].root = NULL;
00488 }
00489
00490 parent =
00491 (lextree_node_t **) ckd_calloc(n_lc, sizeof(lextree_node_t *));
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 for (i = 0; i < n_word; i++) {
00514 wid = wordprob[i].wid;
00515 prob = wordprob[i].prob;
00516 E_DEBUG(2,("%s wid %d prob %d\n",
00517 s3dict_wordstr(dict, wid), wid, prob));
00518
00519 pronlen = s3dict_pronlen(dict, wid);
00520
00521 if (pronlen == 1) {
00522
00523 ci = s3dict_pron(dict, wid, 0);
00524 if (!lc) {
00525
00526 if (d2p->is_composite)
00527 ssid = d2p->internal[wid][0];
00528 else
00529 ssid = bin_mdef_pid2ssid(mdef, ci);
00530
00531 ln = lextree_node_alloc(lextree,
00532 wid, prob, d2p->is_composite, ssid,
00533 s3dict_pron(dict, wid, 0),
00534 BAD_S3CIPID,
00535 bin_mdef_pid2tmatid(mdef, ci));
00536
00537 lextree->root = glist_add_ptr(lextree->root, (void *) ln);
00538 n_node++;
00539 }
00540 else {
00541 np = 0;
00542 for (j = 0; j < n_lc; j++) {
00543
00544 if (d2p->is_composite) {
00545 ssid = d2p->single_lc[ci][(int) lc[j]];
00546 }
00547 else {
00548 ssid = d2p->lrdiph_rc[ci][(int) lc[j]][bin_mdef_silphone(mdef)];
00549 }
00550
00551
00552 for (k = 0; (k < np) && (parent[k]->ssid != ssid);
00553 k++);
00554 if (k >= np) {
00556 ln = lextree_node_alloc(lextree,
00557 wid, prob,
00558 d2p->is_composite, ssid,
00559 ci, BAD_S3CIPID,
00560 bin_mdef_pid2tmatid(mdef, ci));
00561
00562 lextree->root =
00563 glist_add_ptr(lextree->root, (void *) ln);
00564 n_node++;
00565
00566 lcroot[j].root =
00567 glist_add_ptr(lcroot[j].root, (void *) ln);
00568 parent[np++] = ln;
00569 }
00570 else {
00571 lcroot[j].root =
00572 glist_add_ptr(lcroot[j].root,
00573 (void *) parent[k]);
00574 }
00575 }
00576 }
00577 }
00578 else {
00579 assert(pronlen > 1);
00580
00581
00582 if (!lc) {
00583 ssid = d2p->internal[wid][0];
00584 ci = s3dict_pron(dict, wid, 0);
00585
00586
00587 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
00588 ln = (lextree_node_t *) gnode_ptr(gn);
00589 if ((ln->ssid == ssid) && ln->composite
00590 && NOT_S3WID(ln->wid))
00591 break;
00592 }
00593 if (!gn) {
00594 ln = lextree_node_alloc(lextree, BAD_S3WID, prob,
00595 d2p->is_composite, ssid, ci, BAD_S3CIPID,
00596 bin_mdef_pid2tmatid(mdef, ci));
00597
00598 lextree->root =
00599 glist_add_ptr(lextree->root, (void *) ln);
00600 n_node++;
00601 }
00602 else {
00603 if (ln->prob < prob)
00604 ln->prob = prob;
00605 }
00606 parent[0] = ln;
00607 np = 1;
00608 }
00609 else {
00610 ci = s3dict_pron(dict, wid, 0);
00611 rc = s3dict_pron(dict, wid, 1);
00612 ldiph_lc = d2p->ldiph_lc[ci][rc];
00613
00614 np = 0;
00615 for (j = 0; j < n_lc; j++) {
00616 ssid = ldiph_lc[(int) lc[j]];
00617
00618
00619 ln = ssid2ln[ssid];
00620 if (!ln) {
00621 ln = lextree_node_alloc(lextree,
00622 BAD_S3WID, prob,
00623 NOT_COMPOSITE, ssid,
00624 ci, BAD_S3CIPID,
00625 bin_mdef_pid2tmatid(mdef, ci));
00626 lextree->root =
00627 glist_add_ptr(lextree->root, (void *) ln);
00628 n_node++;
00629
00630 ssid2ln[ssid] = ln;
00631 }
00632 else if (ln->prob < prob)
00633 ln->prob = prob;
00634
00635
00636 if (bitvec_is_clear(ssid_lc[ssid], lc[j])) {
00637 lcroot[j].root =
00638 glist_add_ptr(lcroot[j].root, (void *) ln);
00639 bitvec_set(ssid_lc[ssid], lc[j]);
00640 }
00641
00642
00643 for (k = 0; (k < np) && (parent[k]->ssid != ssid);
00644 k++);
00645 if (k >= np)
00646 parent[np++] = ln;
00647 }
00648 }
00649
00650
00651 for (p = 1; p < pronlen - 1; p++) {
00652 ssid = d2p->internal[wid][p];
00653 ci = s3dict_pron(dict, wid, p);
00654
00655
00656 for (j = 0; j < np; j++) {
00657 for (gn = parent[j]->children; gn; gn = gnode_next(gn)) {
00658 ln = (lextree_node_t *) gnode_ptr(gn);
00659
00660 if ((ln->ssid == ssid) && (!ln->composite)) {
00661 assert(NOT_S3WID(ln->wid));
00662 break;
00663 }
00664 }
00665 if (gn)
00666 break;
00667 }
00668
00669 if (!gn) {
00670 ln = lextree_node_alloc(lextree, BAD_S3WID,
00671 prob, NOT_COMPOSITE,
00672 ssid, ci, BAD_S3CIPID,
00673 bin_mdef_pid2tmatid(mdef, ci));
00674
00675 for (j = 0; j < np; j++)
00676 parent[j]->children =
00677 glist_add_ptr(parent[j]->children,
00678 (void *) ln);
00679 n_node++;
00680 }
00681 else {
00682 if (ln->prob < prob)
00683 ln->prob = prob;
00684
00685 k = j;
00686
00687
00688 for (j = 0; j < k; j++)
00689 parent[j]->children =
00690 glist_add_ptr(parent[j]->children,
00691 (void *) ln);
00692
00693
00694 for (j = k + 1; j < np; j++) {
00695 gnode_t *gn;
00696 for (gn = parent[j]->children; gn; gn = gnode_next(gn))
00697 if (gnode_ptr(gn) == ln)
00698 break;
00699 if (gn == NULL)
00700 parent[j]->children =
00701 glist_add_ptr(parent[j]->children,
00702 (void *) ln);
00703 }
00704 }
00705
00706 parent[0] = ln;
00707 np = 1;
00708 }
00709
00710
00711 ssid = d2p->internal[wid][p];
00712 ci = s3dict_pron(dict, wid, p);
00713 ln = lextree_node_alloc(lextree, wid, prob,
00714 d2p->is_composite, ssid,
00715 ci, BAD_S3CIPID,
00716 bin_mdef_pid2tmatid(mdef, ci));
00717
00718 for (j = 0; j < np; j++)
00719 parent[j]->children =
00720 glist_add_ptr(parent[j]->children, (void *) ln);
00721 n_node++;
00722 }
00723 }
00724
00725 lextree->n_node = n_node;
00726 lextree->n_alloc_node = n_node;
00727
00728
00729
00730
00731
00732
00733
00734 lextree->n_alloc_blk_sz = ((n_word * bin_mdef_n_ciphone(mdef)) >> 3);
00735
00736 lextree->active =
00737 (lextree_node_t **) ckd_calloc(n_node +
00738 n_word * bin_mdef_n_ciphone(mdef),
00739 sizeof(lextree_node_t *));
00740 lextree->next_active =
00741 (lextree_node_t **) ckd_calloc(n_node +
00742 n_word * bin_mdef_n_ciphone(mdef),
00743 sizeof(lextree_node_t *));
00744
00745
00746
00747
00748
00749 lextree->n_active = 0;
00750 lextree->n_next_active = 0;
00751
00752 ckd_free((void *) ssid2ln);
00753 for (i = 0; i < n_sseq; i++)
00754 bitvec_free(ssid_lc[i]);
00755 ckd_free((void *) ssid_lc);
00756 ckd_free(parent);
00757
00758 return lextree;
00759 }
00760
00761
00762
00763 static int32
00764 lextree_subtree_free(lextree_node_t * ln, int32 level)
00765 {
00766 gnode_t *gn;
00767 lextree_node_t *ln2;
00768 int32 k;
00769
00770 k = 0;
00771
00772
00773 for (gn = ln->children; gn; gn = gnode_next(gn)) {
00774 ln2 = (lextree_node_t *) gnode_ptr(gn);
00775 k += lextree_subtree_free(ln2, level + 1);
00776 }
00777 glist_free(ln->children);
00778 ln->children = NULL;
00779
00780
00781 if ((level != 1) || (--ln->ssid == 0)) {
00782
00783
00784 lextree_node_free((void *) ln);
00785 k++;
00786 }
00787
00788 return k;
00789 }
00790
00791 static int32
00792 lextree_shrub_subtree_cw_leaves(lextree_node_t * ln, int32 level)
00793 {
00794 gnode_t *gn;
00795 lextree_node_t *ln2;
00796 int32 k;
00797 k = 0;
00798
00799
00800
00801
00802
00803 if (IS_S3WID(ln->wid) && !IS_S3SSID(ln->ssid)) {
00804
00805
00806
00807 if (ln->children != NULL) {
00808
00809 #if 0
00810 E_INFO
00811 ("Free Cross word is carried out for wid %d, ln->children %d\n",
00812 ln->wid, ln->children);
00813 #endif
00814
00815 for (gn = ln->children; gn; gn = gnode_next(gn)) {
00816 ln2 = (lextree_node_t *) gnode_ptr(gn);
00817
00818
00819
00820
00821 lextree_node_free(ln2);
00822 k++;
00823 }
00824 glist_free(ln->children);
00825 ln->children = NULL;
00826 }
00827
00828 }
00829 else {
00830
00831 for (gn = ln->children; gn; gn = gnode_next(gn)) {
00832 ln2 = (lextree_node_t *) gnode_ptr(gn);
00833 k += lextree_shrub_subtree_cw_leaves(ln2, level + 1);
00834 }
00835 }
00836
00837
00838 return k;
00839 }
00840
00841 void
00842 lextree_shrub_cw_leaves(lextree_t * lextree)
00843 {
00844 gnode_t *gn, *cwgn;
00845 glist_t root;
00846 lextree_node_t *ln;
00847 lextree_node_t *cwln;
00848 int32 k, i;
00849
00850
00851 k = 0;
00852
00853 if (lextree->n_lc > 0) {
00854 for (i = 0; i < lextree->n_lc; i++) {
00855 root = lextree->lcroot[i].root;
00856
00857 if (root != NULL) {
00858 for (gn = root; gn; gn = gnode_next(gn)) {
00859
00860 ln = (lextree_node_t *) gnode_ptr(gn);
00861
00862 if (IS_S3WID(ln->wid) && ln->children != NULL) {
00863
00864 #if 0
00865 E_INFO
00866 ("Tree %d, lc %d, Free Cross word is carried out for wid %d, ln->children %d\n",
00867 lextree, lextree->lcroot[i].lc, ln->wid,
00868 ln->children);
00869 #endif
00870 for (cwgn = ln->children; cwgn;
00871 cwgn = gnode_next(cwgn)) {
00872 cwln = (lextree_node_t *) gnode_ptr(cwgn);
00873 lextree_node_free(cwln);
00874 }
00875 glist_free(ln->children);
00876 ln->children = NULL;
00877 }
00878 }
00879 }
00880 }
00881 }
00882
00883 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
00884 ln = (lextree_node_t *) gnode_ptr(gn);
00885 k += lextree_shrub_subtree_cw_leaves(ln, 0);
00886 }
00887 lextree_n_node(lextree) -= k;
00888 }
00889
00890
00891
00892
00893
00894
00895 void
00896 lextree_free(lextree_t * lextree)
00897 {
00898 gnode_t *gn, *gn2;
00899 lextree_node_t *ln, *ln2;
00900 int32 i, k;
00901
00902 if (lextree->n_lc > 0) {
00903 for (i = 0; i < lextree->n_lc; i++) {
00904 glist_free(lextree->lcroot[i].root);
00905 lextree->lcroot[i].root = NULL;
00906 }
00907
00908 ckd_free(lextree->lcroot);
00909 }
00910
00911
00912 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
00913 ln = (lextree_node_t *) gnode_ptr(gn);
00914 for (gn2 = ln->children; gn2; gn2 = gnode_next(gn2)) {
00915 ln2 = (lextree_node_t *) gnode_ptr(gn2);
00916 if (ln2->composite >= 0) {
00917 ln2->composite = -1;
00918 ln2->ssid = 1;
00919 }
00920 else
00921 ln2->ssid++;
00922 }
00923 }
00924
00925
00926 k = 0;
00927 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
00928 ln = (lextree_node_t *) gnode_ptr(gn);
00929 k += lextree_subtree_free(ln, 0);
00930 }
00931 glist_free(lextree->root);
00932
00933 ckd_free((void *) lextree->active);
00934 ckd_free((void *) lextree->next_active);
00935
00936
00937 if (k != lextree->n_node)
00938 E_ERROR("#Nodes allocated(%d) != #nodes freed(%d)\n",
00939 lextree->n_node, k);
00940
00941 hmm_context_free(lextree->ctx);
00942 hmm_context_free(lextree->comctx);
00943
00944 ngram_model_free(lextree->lm);
00945
00946 ckd_free(lextree);
00947 }
00948
00949
00950 void
00951 lextree_ci_active(lextree_t * lextree, bitvec_t *ci_active)
00952 {
00953 lextree_node_t **list, *ln;
00954 int32 i;
00955
00956 list = lextree->active;
00957
00958 for (i = 0; i < lextree->n_active; i++) {
00959 ln = list[i];
00960 bitvec_set(ci_active, ln->ci);
00961 }
00962 }
00963
00964
00965 void
00966 lextree_ssid_active(lextree_t * lextree, bitvec_t * ssid, bitvec_t * comssid)
00967 {
00968 lextree_node_t **list, *ln;
00969 int32 i;
00970
00971 list = lextree->active;
00972
00973 for (i = 0; i < lextree->n_active; i++) {
00974 ln = list[i];
00975
00976
00977
00978
00979
00980
00981
00982
00983 if (ln->composite)
00984 bitvec_set(comssid, ln->ssid);
00985 else
00986 bitvec_set(ssid, ln->ssid);
00987 }
00988 }
00989
00990
00991 void
00992 lextree_utt_end(lextree_t * l)
00993 {
00994 lextree_node_t *ln;
00995 int32 i;
00996
00997 for (i = 0; i < l->n_active; i++) {
00998 ln = l->active[i];
00999 hmm_clear((hmm_t *)ln);
01000 }
01001
01002 l->n_active = 0;
01003 l->n_next_active = 0;
01004
01005 strcpy(l->prev_word, "");
01006
01007
01008
01009
01010
01011 if (!dict2pid_is_composite(l->dict2pid)) {
01012 lextree_shrub_cw_leaves(l);
01013 }
01014 }
01015
01016
01017 static void
01018 lextree_node_print(lextree_node_t * ln, s3dict_t * dict, FILE * fp)
01019 {
01020 fprintf(fp, "wid(%d)pr(%d)com(%d)ss(%d)rc(%d)", ln->wid, ln->prob,
01021 ln->composite, ln->ssid, ln->rc);
01022 if (IS_S3WID(ln->wid))
01023 fprintf(fp, "%s", s3dict_wordstr(dict, ln->wid));
01024 fprintf(fp, "\n");
01025 }
01026
01027
01028
01029 static void
01030 lextree_subtree_print(lextree_node_t * ln, int32 level, s3dict_t * dict,
01031 FILE * fp)
01032 {
01033 int32 i;
01034 gnode_t *gn;
01035
01036 for (i = 0; i < level; i++)
01037 fprintf(fp, " ");
01038 lextree_node_print(ln, dict, fp);
01039
01040 for (gn = ln->children; gn; gn = gnode_next(gn)) {
01041 ln = (lextree_node_t *) gnode_ptr(gn);
01042 lextree_subtree_print(ln, level + 1, dict, fp);
01043 }
01044 }
01045
01046 static void
01047 lextree_subtree_print_dot(lextree_node_t * ln, int32 level, s3dict_t * dict,
01048 bin_mdef_t * mdef, FILE * fp)
01049 {
01050 gnode_t *gn;
01051
01052
01053 if (IS_S3WID(ln->wid)) {
01054 fprintf(fp, "\"%s\";\n", s3dict_wordstr(dict, ln->wid));
01055 }
01056 else {
01057 for (gn = ln->children; gn; gn = gnode_next(gn)) {
01058 ln = (lextree_node_t *) gnode_ptr(gn);
01059 fprintf(fp, " \"%s\" -> ", bin_mdef_ciphone_str(mdef, ln->ci));
01060 lextree_subtree_print_dot(ln, level + 1, dict, mdef, fp);
01061 }
01062 }
01063 }
01064
01065 #define GRAPH_RAVIFMT 1
01066 #define GRAPH_DOTFMT 2
01067
01068 void
01069 lextree_dump(lextree_t * lextree, FILE * fp, int32 fmt)
01070 {
01071 gnode_t *gn;
01072 lextree_node_t *ln;
01073
01074 if (fmt > 2) {
01075 fmt = GRAPH_RAVIFMT;
01076 }
01077 if (fmt == GRAPH_RAVIFMT) {
01078 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
01079 ln = (lextree_node_t *) gnode_ptr(gn);
01080 lextree_subtree_print(ln, 0, lextree->dict, fp);
01081 }
01082
01083 if (lextree->n_lc > 0) {
01084 int32 i;
01085 for (i = 0; i < lextree->n_lc; i++) {
01086 fprintf(fp, "lcroot %d\n", lextree->lcroot[i].lc);
01087 for (gn = lextree->lcroot[i].root; gn; gn = gnode_next(gn)) {
01088 ln = (lextree_node_t *) gnode_ptr(gn);
01089 lextree_node_print(ln, lextree->dict, fp);
01090 }
01091 }
01092 }
01093 }
01094 else if (fmt == GRAPH_DOTFMT) {
01095 fprintf(fp, "digraph G {\n");
01096 fprintf(fp, "rankdir=LR \n");
01097 for (gn = lextree->root; gn; gn = gnode_next(gn)) {
01098 ln = (lextree_node_t *) gnode_ptr(gn);
01099
01100 fprintf(fp, " \"%s\" -> ", bin_mdef_ciphone_str(lextree->mdef, ln->ci));
01101
01102 lextree_subtree_print_dot(ln, 0, lextree->dict, lextree->mdef, fp);
01103 }
01104 fprintf(fp, "}\n");
01105 }
01106 fflush(fp);
01107 }
01108
01109
01110
01111
01112 static void
01113 lextree_realloc_active_list(lextree_t * lt, int32 num_active)
01114 {
01115 if (num_active >= lt->n_alloc_node && lt->type != LEXTREE_TYPE_FILLER) {
01116 E_INFO("num_active %d, n_alloc_node %d, n_node %d\n", num_active,
01117 lt->n_alloc_node, lt->n_node);
01118 lextree_n_alloc_node(lt) = lextree_n_node(lt);
01119 lt->active =
01120 (lextree_node_t **) ckd_realloc(lt->active,
01121 lextree_n_alloc_node(lt) *
01122 sizeof(lextree_node_t *));
01123 if (lt->active == NULL) {
01124 E_INFO("help.\n");
01125 }
01126 lt->next_active =
01127 (lextree_node_t **) ckd_realloc(lt->next_active,
01128 lextree_n_alloc_node(lt) *
01129 sizeof(lextree_node_t *));
01130 if (lt->next_active == NULL) {
01131 E_INFO("help.\n");
01132 }
01133
01134 E_INFO("Reallocating more memory, now has node %d\n",
01135 lextree_n_alloc_node(lt));
01136 }
01137 }
01138
01139
01140 void
01141 lextree_enter(lextree_t * lextree, s3cipid_t lc, int32 cf,
01142 int32 inscore, int32 inhist, int32 thresh)
01143 {
01144 glist_t root;
01145 gnode_t *gn, *cwgn;
01146 lextree_node_t *ln, *cwln;
01147 int32 nf, scr;
01148 int32 i, n;
01149 int32 rc;
01150 int32 n_ci, n_st, n_rc;
01151
01152 tmat_t *tmat;
01153 s3ssid_t *rmap;
01154
01155 nf = cf + 1;
01156
01157 n_ci = bin_mdef_n_ciphone(lextree->mdef);
01158 n_st = bin_mdef_n_emit_state(lextree->mdef);
01159 tmat = lextree->tmat;
01160 rc = 0;
01161
01162 assert(lextree);
01163
01164 if (lextree->n_lc == 0) {
01165 assert(NOT_S3CIPID(lc));
01166 root = lextree->root;
01167 }
01168 else {
01169 for (i = 0; (i < lextree->n_lc) && (lextree->lcroot[i].lc != lc);
01170 i++);
01171
01172 assert(i < lextree->n_lc);
01173
01174 root = lextree->lcroot[i].root;
01175 }
01176
01177
01178 n = lextree->n_next_active;
01179
01180
01181 for (gn = root; gn; gn = gnode_next(gn)) {
01182 ln = (lextree_node_t *) gnode_ptr(gn);
01183
01184 if (NOT_S3WID(ln->wid) ||
01185 (IS_S3WID(ln->wid)
01186 && dict2pid_is_composite(lextree->dict2pid))
01187 ) {
01188 scr = inscore + ln->prob;
01189 if ((scr >= thresh) && (hmm_in_score(&ln->hmm) < scr)) {
01190 E_DEBUG(4,("entering non-leaf root node with %d + %d >= (thresh %d score %d)\n",
01191 inscore, ln->prob, thresh, hmm_in_score(&ln->hmm)));
01192 hmm_in_score(&ln->hmm) = scr;
01193 hmm_in_history(&ln->hmm) = inhist;
01194
01195 if (hmm_frame(&ln->hmm) != nf) {
01196 hmm_frame(&ln->hmm) = nf;
01197 lextree->next_active[n++] = ln;
01198 }
01199 }
01200 }
01201 else {
01202
01203
01204
01205
01206 assert(IS_S3WID(ln->wid));
01207 if (ln->children == NULL) {
01208 n_ci = bin_mdef_n_ciphone(lextree->mdef);
01209 rmap = lextree->dict2pid->lrssid[ln->ci][0].ssid;
01210 n_rc = get_rc_nssid(lextree->dict2pid, ln->wid, lextree->dict);
01211
01212 if (!s3dict_filler_word(lextree->dict, ln->wid)) {
01213
01214 for (rc = 0; rc < n_rc; rc++) {
01215 cwln =
01216 lextree_node_alloc(lextree,
01217 ln->wid, ln->prob,
01218 NOT_COMPOSITE, rmap[rc],
01219 ln->ci, rc,
01220 bin_mdef_pid2tmatid(lextree->mdef, ln->ci));
01221 ln->children =
01222 glist_add_ptr(ln->children, (void *) cwln);
01223 }
01224
01225 }
01226 else {
01227
01228
01229
01230 cwln =
01231 lextree_node_alloc(lextree,
01232 ln->wid, ln->prob,
01233 NOT_COMPOSITE, rmap[0],
01234 ln->ci, 0,
01235 bin_mdef_pid2tmatid(lextree->mdef, ln->ci));
01236 lextree_n_node(lextree) += 1;
01237
01238 ln->children =
01239 glist_add_ptr(ln->children, (void *) cwln);
01240 }
01241
01242 }
01243
01244
01245 for (cwgn = ln->children; cwgn; cwgn = gnode_next(cwgn)) {
01246 cwln = (lextree_node_t *) gnode_ptr(cwgn);
01247 scr = inscore + cwln->prob;
01248 if ((scr >= thresh) && (hmm_in_score(&cwln->hmm) < scr)) {
01249 hmm_in_score(&cwln->hmm) = scr;
01250 hmm_in_history(&cwln->hmm) = inhist;
01251
01252 if (hmm_frame(&cwln->hmm) != nf) {
01253 hmm_frame(&cwln->hmm) = nf;
01254 lextree->next_active[n++] = cwln;
01255 }
01256 }
01257 }
01258 }
01259
01260 }
01261 lextree->n_next_active = n;
01262 }
01263
01264
01265 void
01266 lextree_active_swap(lextree_t * lextree)
01267 {
01268 lextree_node_t **t;
01269
01270 t = lextree->active;
01271 lextree->active = lextree->next_active;
01272 lextree->next_active = t;
01273 lextree->n_active = lextree->n_next_active;
01274 lextree->n_next_active = 0;
01275 }
01276
01277
01278 int32
01279 lextree_hmm_eval(lextree_t * lextree, int16 *senscr, int16 *comsen, int32 frm, FILE * fp)
01280 {
01281 int32 best, wbest, n_st;
01282 int32 i, k;
01283 lextree_node_t **list, *ln;
01284 bin_mdef_t *mdef;
01285 dict2pid_t *d2p;
01286
01287 mdef = lextree->mdef;
01288 d2p = lextree->dict2pid;
01289 n_st = bin_mdef_n_emit_state(mdef);
01290
01291 list = lextree->active;
01292 best = MAX_NEG_INT32;
01293 wbest = MAX_NEG_INT32;
01294
01295 hmm_context_set_senscore(lextree->ctx, senscr);
01296 hmm_context_set_senscore(lextree->comctx, comsen);
01297
01298 for (i = 0; i < lextree->n_active; i++) {
01299 ln = list[i];
01300
01301 if (IS_S3WID(ln->wid)) {
01302
01303 }
01304
01305 assert(hmm_frame(&ln->hmm) == frm);
01306 assert(ln->ssid >= 0);
01307
01308 if (fp) {
01309
01310 hmm_dump((hmm_t *)ln, fp);
01311 }
01312
01313 k = hmm_vit_eval((hmm_t *)ln);
01314
01315 if (best < k)
01316 best = k;
01317
01318 if (IS_S3WID(ln->wid)) {
01319 if (wbest < k)
01320 wbest = k;
01321 }
01322
01323 }
01324
01325 lextree->best = best;
01326 lextree->wbest = wbest;
01327
01328 if (fp) {
01329 fprintf(fp, "Fr %d #active %d best %d wbest %d\n",
01330 frm, lextree->n_active, best, wbest);
01331 fflush(fp);
01332 }
01333
01334 return best;
01335 }
01336
01337
01338 void
01339 lextree_hmm_histbin(lextree_t * lextree, int32 bestscr, int32 * bin,
01340 int32 nbin, int32 bw)
01341 {
01342 lextree_node_t **list, *ln;
01343 int32 i, k;
01344 glist_t *binln;
01345 gnode_t *gn;
01346
01347 binln = (glist_t *) ckd_calloc(nbin, sizeof(glist_t));
01348
01349 list = lextree->active;
01350
01351 for (i = 0; i < lextree->n_active; i++) {
01352 ln = list[i];
01353
01354 if (IS_S3WID(ln->wid)) {
01355 assert(ln->ssid != BAD_S3SSID);
01356 }
01357
01358
01359
01360
01361
01362 k = (bestscr - hmm_bestscore(&ln->hmm)) / bw;
01363 if (k >= nbin)
01364 k = nbin - 1;
01365 assert(k >= 0);
01366
01367 bin[k]++;
01368 binln[k] = glist_add_ptr(binln[k], (void *) ln);
01369 }
01370
01371
01372 k = 0;
01373 for (i = 0; i < nbin; i++) {
01374 for (gn = binln[i]; gn; gn = gnode_next(gn)) {
01375 ln = (lextree_node_t *) gnode_ptr(gn);
01376 list[k++] = ln;
01377 }
01378 glist_free(binln[i]);
01379 }
01380 assert(k == lextree->n_active);
01381
01382 ckd_free((void *) binln);
01383 }
01384
01385
01386
01387
01388
01389 int32
01390 lextree_hmm_propagate_non_leaves(lextree_t * lextree,
01391 int32 cf, int32 th, int32 pth, int32 wth)
01392 {
01393 bin_mdef_t *mdef;
01394 dict2pid_t *d2p;
01395 s3dict_t *dict;
01396 int32 nf, newscore;
01397 lextree_node_t **list, *ln, *ln2;
01398 lextree_node_t *cwln;
01399 tmat_t *tmat;
01400 gnode_t *gn, *gn2;
01401 int32 i, n, lastfrm;
01402 int32 hth;
01403 int32 rc;
01404 int32 n_ci, n_st, n_rc;
01405 s3ssid_t *rmap;
01406
01407 lastfrm = -1;
01408 hth = 0;
01409 mdef = lextree->mdef;
01410 n_ci = bin_mdef_n_ciphone(mdef);
01411 n_st = bin_mdef_n_emit_state(mdef);
01412 d2p = lextree->dict2pid;
01413 dict = lextree->dict;
01414 tmat = lextree->tmat;
01415
01416 nf = cf + 1;
01417
01418 list = lextree->active;
01419
01420 E_DEBUG(1, ("lextree_hmm_propagate_non_leaves: cf %d th %d pth %d wth %d\n",
01421 cf, th, pth, wth));
01422 n = lextree->n_next_active;
01423 assert(n == 0);
01424
01425 E_DEBUG(1,("No. of active node within the lexical tree: %d\n",lextree->n_active));
01426
01427 for (i = 0; i < lextree->n_active; i++) {
01428 E_DEBUG(3,("Looking at node %d of %d\n", i, lextree->n_alloc_node));
01429 ln = list[i];
01430
01431 if (IS_S3WID(ln->wid)) {
01432 E_DEBUG(3,("Is WID %d = %s, ln->rc %d, ln->ssid %d\n",
01433 ln->wid, s3dict_wordstr(dict, ln->wid), ln->rc, ln->ssid));
01434 assert(ln->ssid != BAD_S3SSID);
01435 }
01436
01437
01438 if (hmm_frame(&ln->hmm) < nf) {
01439 if (hmm_bestscore(&ln->hmm) >= th) {
01440 E_DEBUG(4,("Activating (%d >= %d)\n", hmm_bestscore(&ln->hmm), th));
01441 hmm_frame(&ln->hmm) = nf;
01442 lextree->next_active[n++] = ln;
01443 }
01444 else {
01445 E_DEBUG(4,("Deactivating (%d < %d)\n", hmm_bestscore(&ln->hmm), th));
01446 hmm_clear((hmm_t *)ln);
01447 }
01448 }
01449
01450 if (NOT_S3WID(ln->wid)) {
01451 if (hmm_out_score(&ln->hmm) < pth)
01452 continue;
01453 E_DEBUG(4,("Propagating (%d >= %d)\n", hmm_out_score(&ln->hmm), pth));
01454
01455 for (gn = ln->children; gn; gn = gnode_next(gn)) {
01456
01457 ln2 = gnode_ptr(gn);
01458
01459
01460
01461 if (dict2pid_is_composite(d2p) ||
01462 (!dict2pid_is_composite(d2p) && NOT_S3WID(ln2->wid))) {
01463
01464
01465
01466
01467
01468 newscore = hmm_out_score(&ln->hmm) + (ln2->prob - ln->prob);
01469
01470 E_DEBUG(4,(" newscore %d + %d - %d = %d\n",
01471 hmm_out_score(&ln->hmm), ln2->prob, ln->prob, newscore));
01472 if ((newscore >= th) &&
01473
01474 (hmm_in_score(&ln2->hmm) < newscore)) {
01475 hmm_in_score(&ln2->hmm) = newscore;
01476 hmm_in_history(&ln2->hmm) = hmm_out_history(&ln->hmm);
01477
01478 if (hmm_frame(&ln2->hmm) != nf) {
01479 E_DEBUG(4,(" entering this node\n"));
01480 hmm_frame(&ln2->hmm) = nf;
01481
01482 lextree->next_active[n++] = ln2;
01483 }
01484 }
01485 }
01486 else {
01487 assert(IS_S3WID(ln2->wid));
01488 assert(ln2->ssid == BAD_S3SSID && ln2->rc == BAD_S3CIPID);
01489
01490 assert(!dict2pid_is_composite(d2p));
01491
01492
01493 if (ln2->children == NULL) {
01494 assert(s3dict_pronlen(dict, ln2->wid) > 1);
01495
01496
01497 assert(ln2->ssid == BAD_S3SSID);
01498 n_ci = bin_mdef_n_ciphone(mdef);
01499
01500
01501 E_DEBUG(3,
01502 ("Tree %d, Cross word expansion is carried out at cf %d for wid %d, wstr %s, ln->children %d\n",
01503 lextree, cf, ln2->wid, s3dict_wordstr(lextree->dict, ln2->wid),
01504 ln2->children));
01505
01506 rmap = d2p->rssid[ln2->ci][ln->ci].ssid;
01507 n_rc =
01508 d2p->rssid[ln2->ci][ln->ci].n_ssid;
01509
01510 assert(n_rc ==
01511 get_rc_nssid(d2p, ln2->wid,
01512 dict));
01513
01514 for (rc = 0; rc < n_rc; rc++) {
01515 cwln =
01516 lextree_node_alloc(lextree,
01517 ln2->wid, ln2->prob,
01518 NOT_COMPOSITE, rmap[rc],
01519 ln2->ci, rc,
01520 bin_mdef_pid2tmatid(mdef, ln2->ci));
01521 lextree_n_node(lextree) += 1;
01522
01523 ln2->children =
01524 glist_add_ptr(ln2->children,
01525 (void *) cwln);
01526 }
01527 }
01528
01529
01530 for (gn2 = ln2->children; gn2; gn2 = gnode_next(gn2)) {
01531 cwln = gnode_ptr(gn2);
01532
01533
01534
01535
01536 newscore = hmm_out_score(&ln->hmm)
01537 + (cwln->prob - ln->prob);
01538
01539
01540 if ((newscore >= th) &&
01541
01542 (hmm_in_score(&cwln->hmm) < newscore)) {
01543 hmm_in_score(&cwln->hmm) = newscore;
01544 hmm_in_history(&cwln->hmm) = hmm_out_history(&ln->hmm);
01545
01546 if (hmm_frame(&cwln->hmm) != nf) {
01547 hmm_frame(&cwln->hmm) = nf;
01548
01549 lextree->next_active[n++] = cwln;
01550 }
01551 }
01552 }
01553 assert(ln2->ssid == BAD_S3SSID && ln2->rc == BAD_S3CIPID);
01554
01555 }
01556 }
01557 }
01558 }
01559
01560 lextree->n_next_active = n;
01561 #ifdef SPHINX_DEBUG
01562 E_DEBUG(3,("Debugging.\n"));
01563 for (i = 0; i < lextree->n_next_active; i++) {
01564 ln = lextree->next_active[i];
01565
01566 E_DEBUG(3,(" ln->wid %d, str %s, ln->ssid %d, ln->rc %d,\n", ln->wid,
01567 s3dict_wordstr(dict, ln->wid), ln->ssid, ln->rc));
01568 }
01569 #endif
01570 E_DEBUG(1,("lextree->n_next_active %d\n", lextree->n_next_active));
01571 return LEXTREE_OPERATION_SUCCESS;
01572 }
01573
01574 int32
01575 lextree_hmm_propagate_leaves(lextree_t * lextree,
01576 vithist_t * vh, int32 cf, int32 wth)
01577 {
01578
01579 lextree_node_t **list, *ln;
01580 #ifdef SPHINX_DEBUG
01581 int32 n_active_word_end;
01582 #endif
01583 int32 i;
01584
01585
01586 list = lextree->active;
01587
01588 E_DEBUG(1, ("lextree_hmm_propagate_leaves: cf %d wth %d\n", cf, wth));
01589 for (i = 0; i < lextree->n_active; i++) {
01590 ln = list[i];
01591
01592 if (IS_S3WID(ln->wid)) {
01593
01594 if (hmm_out_score(&ln->hmm) < wth)
01595 continue;
01596
01597 if (hmm_out_history(&ln->hmm) == -1) {
01598
01599
01600
01601 E_ERROR("out.history==-1, error\n");
01602 return LEXTREE_OPERATION_FAILURE;
01603 }
01604
01605
01606
01607 E_DEBUG(2,("Rescoring exit %s with score %d\n",
01608 s3dict_wordstr(lextree->dict, ln->wid),
01609 hmm_out_score(&ln->hmm) - ln->prob));
01610 if (dict2pid_is_composite(lextree->dict2pid)) {
01611 vithist_rescore(vh, lextree->lm, lextree->dict,
01612 lextree->dict2pid, lextree->fp, ln->wid, cf,
01613 hmm_out_score(&ln->hmm) - ln->prob,
01614 hmm_out_history(&ln->hmm), lextree->type, -1);
01615 }
01616 else {
01617
01618 assert(ln->ssid != BAD_S3SSID);
01619 assert(ln->rc != BAD_S3CIPID);
01620
01621 vithist_rescore(vh, lextree->lm, lextree->dict,
01622 lextree->dict2pid, lextree->fp, ln->wid, cf,
01623 hmm_out_score(&ln->hmm) - ln->prob,
01624 hmm_out_history(&ln->hmm), lextree->type, ln->rc);
01625
01626 }
01627
01628
01629 #ifdef SPHINX_DEBUG
01630 n_active_word_end++;
01631 #endif
01632 }
01633 }
01634
01635 E_DEBUG(1,("number of active leaf nodes %d\n",n_active_word_end));
01636 return LEXTREE_OPERATION_SUCCESS;
01637 }