54 #include "sphinxbase/fsg_model.h"
76 #define FSG_MODEL_BEGIN_DECL "FSG_BEGIN"
77 #define FSG_MODEL_END_DECL "FSG_END"
78 #define FSG_MODEL_N_DECL "N"
79 #define FSG_MODEL_NUM_STATES_DECL "NUM_STATES"
80 #define FSG_MODEL_S_DECL "S"
81 #define FSG_MODEL_START_STATE_DECL "START_STATE"
82 #define FSG_MODEL_F_DECL "F"
83 #define FSG_MODEL_FINAL_STATE_DECL "FINAL_STATE"
84 #define FSG_MODEL_T_DECL "T"
85 #define FSG_MODEL_TRANSITION_DECL "TRANSITION"
86 #define FSG_MODEL_COMMENT_CHAR '#'
90 nextline_str2words(FILE * fp, int32 * lineno,
91 char **lineptr,
char ***wordptr)
103 if ((*lineptr)[0] == FSG_MODEL_COMMENT_CHAR)
111 if (*wordptr == NULL)
114 *wordptr =
ckd_realloc(*wordptr, n *
sizeof(**wordptr));
121 int32 from, int32 to, int32 logp, int32 wid)
127 if (fsg->
trans[from].trans == NULL)
131 for (gn = gl = fsg_model_trans(fsg, from, to); gn; gn = gnode_next(gn)) {
133 if (link->
wid == wid) {
142 link->from_state = from;
150 (
char const *)&link->to_state,
151 sizeof(link->to_state), gl);
155 fsg_model_tag_trans_add(
fsg_model_t * fsg, int32 from, int32 to, int32 logp, int32 wid)
161 E_FATAL(
"Null transition prob must be <= 1.0 (state %d -> %d)\n",
169 if (fsg->
trans[from].null_trans == NULL)
173 link = fsg_model_null_trans(fsg, from, to);
185 link->from_state = from;
192 (
char const *)&link->to_state,
193 sizeof(link->to_state), link);
194 assert(link == link2);
200 fsg_model_null_trans_add(
fsg_model_t * fsg, int32 from, int32 to, int32 logp)
202 return fsg_model_tag_trans_add(fsg, from, to, logp, -1);
213 E_INFO(
"Computing transitive closure for null transitions\n");
219 for (i = 0; i < fsg->
n_state; ++i) {
220 for (j = 0; j < fsg->
n_state; ++j) {
221 if ((null = fsg_model_null_trans(fsg, i, j)))
235 for (gn1 = nulls; gn1; gn1 = gnode_next(gn1)) {
237 assert(tl1->
wid < 0);
239 for (gn2 = nulls; gn2; gn2 = gnode_next(gn2)) {
242 if (tl1->to_state == tl2->from_state) {
243 k = fsg_model_null_trans_add(fsg,
254 (fsg, tl1->from_state,
264 E_INFO(
"%d null transitions added\n", n);
270 fsg_model_trans(
fsg_model_t *fsg, int32 i, int32 j)
274 if (fsg->
trans[i].trans == NULL)
277 sizeof(j), &val) < 0)
283 fsg_model_null_trans(
fsg_model_t *fsg, int32 i, int32 j)
287 if (fsg->
trans[i].null_trans == NULL)
290 sizeof(j), &val) < 0)
300 if (fsg->
trans[i].trans == NULL && fsg->
trans[i].null_trans == NULL)
303 if (fsg->
trans[i].null_trans)
305 if (fsg->
trans[i].trans)
307 if (itor->itor != NULL)
318 else if (itor->null_itor)
329 itor->gn = gnode_next(itor->gn);
331 if (itor->gn == NULL) {
333 if (itor->itor != NULL)
335 else if (itor->null_itor == NULL)
340 if (itor->null_itor == NULL)
343 if (itor->null_itor == NULL)
348 fsg_arciter_free(itor);
364 fsg_model_word_id(
fsg_model_t *fsg,
char const *word)
369 for (wid = 0; wid < fsg->
n_word; ++wid) {
370 if (0 == strcmp(fsg->
vocab[wid], word))
380 fsg_model_word_add(
fsg_model_t *fsg,
char const *word)
385 wid = fsg_model_word_id(fsg, word);
405 fsg_model_add_silence(
fsg_model_t * fsg,
char const *silword,
406 int state, float32 silprob)
409 int n_trans, silwid, src;
411 E_INFO(
"Adding silence transitions for %s to FSG\n", silword);
413 silwid = fsg_model_word_add(fsg, silword);
421 for (src = 0; src < fsg->
n_state; src++) {
422 fsg_model_trans_add(fsg, src, src, logsilp, silwid);
427 fsg_model_trans_add(fsg, state, state, logsilp, silwid);
431 E_INFO(
"Added %d silence word transitions\n", n_trans);
436 fsg_model_add_alt(
fsg_model_t * fsg,
char const *baseword,
439 int i, basewid, altwid;
443 for (basewid = 0; basewid < fsg->
n_word; ++basewid)
444 if (0 == strcmp(fsg->
vocab[basewid], baseword))
446 if (basewid == fsg->
n_word) {
447 E_ERROR(
"Base word %s not present in FSG vocabulary!\n", baseword);
450 altwid = fsg_model_word_add(fsg, altword);
455 E_DEBUG(2,(
"Adding alternate word transitions (%s,%s) to FSG\n",
461 for (i = 0; i < fsg->
n_state; ++i) {
463 if (fsg->
trans[i].trans == NULL)
471 for (gn = trans; gn; gn = gnode_next(gn)) {
473 if (fl->
wid == basewid) {
478 link->from_state = fl->from_state;
479 link->to_state = fl->to_state;
492 E_DEBUG(2,(
"Added %d alternate word transitions\n", ntrans));
498 fsg_model_init(
char const *name,
logmath_t *lmath, float32 lw, int32 n_state)
517 fsg_model_read(FILE * fp,
logmath_t *lmath, float32 lw)
528 int n_state, n_trans, n_null_trans;
542 n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
544 E_ERROR(
"%s declaration missing\n", FSG_MODEL_BEGIN_DECL);
548 if ((strcmp(wordptr[0], FSG_MODEL_BEGIN_DECL) == 0)) {
550 E_ERROR(
"Line[%d]: malformed FSG_BEGIN declaration\n",
563 E_WARN (
"FSG name is missing\n");
568 n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
570 || ((strcmp(wordptr[0], FSG_MODEL_N_DECL) != 0)
571 && (strcmp(wordptr[0], FSG_MODEL_NUM_STATES_DECL) != 0))
572 || (sscanf(wordptr[1],
"%d", &n_state) != 1)
575 (
"Line[%d]: #states declaration line missing or malformed\n",
581 fsg = fsg_model_init(fsgname, lmath, lw, n_state);
586 n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
588 || ((strcmp(wordptr[0], FSG_MODEL_S_DECL) != 0)
589 && (strcmp(wordptr[0], FSG_MODEL_START_STATE_DECL) != 0))
590 || (sscanf(wordptr[1],
"%d", &(fsg->
start_state)) != 1)
594 (
"Line[%d]: start state declaration line missing or malformed\n",
600 n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
602 || ((strcmp(wordptr[0], FSG_MODEL_F_DECL) != 0)
603 && (strcmp(wordptr[0], FSG_MODEL_FINAL_STATE_DECL) != 0))
604 || (sscanf(wordptr[1],
"%d", &(fsg->
final_state)) != 1)
608 (
"Line[%d]: final state declaration line missing or malformed\n",
615 n_trans = n_null_trans = 0;
619 n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
621 E_ERROR(
"Line[%d]: transition or FSG_END statement expected\n",
626 if ((strcmp(wordptr[0], FSG_MODEL_END_DECL) == 0)) {
630 if ((strcmp(wordptr[0], FSG_MODEL_T_DECL) == 0)
631 || (strcmp(wordptr[0], FSG_MODEL_TRANSITION_DECL) == 0)) {
634 if (((n != 4) && (n != 5))
635 || (sscanf(wordptr[1],
"%d", &i) != 1)
636 || (sscanf(wordptr[2],
"%d", &j) != 1)
637 || (i < 0) || (i >= fsg->
n_state)
638 || (j < 0) || (j >= fsg->
n_state)) {
640 (
"Line[%d]: transition spec malformed; Expecting: from-state to-state trans-prob [word]\n",
646 if ((p <= 0.0) || (p > 1.0)) {
648 (
"Line[%d]: transition spec malformed; Expecting float as transition probability\n",
654 E_ERROR(
"Line[%d]: transition or FSG_END statement expected\n",
667 fsg_model_trans_add(fsg, i, j, tprob, wid);
671 if (fsg_model_null_trans_add(fsg, i, j, tprob) == 1) {
673 nulls =
glist_add_ptr(nulls, fsg_model_null_trans(fsg, i, j));
678 E_INFO(
"FSG: %d states, %d unique words, %d transitions (%d null)\n",
679 fsg->
n_state, hash_table_inuse(vocab), n_trans, n_null_trans);
682 nulls = fsg_model_null_trans_closure(fsg, nulls);
686 fsg->
n_word = hash_table_inuse(vocab);
690 char const *word = hash_entry_key(itor->
ent);
692 fsg->
vocab[wid] = (
char *)word;
714 fsg_model_readfile(
const char *file,
logmath_t *lmath, float32 lw)
719 if ((fp = fopen(file,
"r")) == NULL) {
720 E_ERROR(
"Failed to open FSG file '%s' for reading: %s\n", file, strerror(errno));
723 fsg = fsg_model_read(fp, lmath, lw);
743 if (fsg->
trans[i].trans) {
765 for (i = 0; i < fsg->
n_word; ++i)
767 for (i = 0; i < fsg->
n_state; ++i)
768 trans_list_free(fsg, i);
785 fprintf(fp,
"%s %s\n", FSG_MODEL_BEGIN_DECL, fsg->
name ? fsg->
name :
"");
786 fprintf(fp,
"%s %d\n", FSG_MODEL_NUM_STATES_DECL, fsg->
n_state);
787 fprintf(fp,
"%s %d\n", FSG_MODEL_START_STATE_DECL, fsg->
start_state);
788 fprintf(fp,
"%s %d\n", FSG_MODEL_FINAL_STATE_DECL, fsg->
final_state);
790 for (i = 0; i < fsg->
n_state; i++) {
793 for (itor = fsg_model_arcs(fsg, i); itor; itor = fsg_arciter_next(itor)) {
796 fprintf(fp,
"%s %d %d %f %s\n", FSG_MODEL_TRANSITION_DECL,
797 tl->from_state, tl->to_state,
799 (tl->
wid < 0) ?
"" : fsg_model_word_str(fsg, tl->
wid));
803 fprintf(fp,
"%s\n", FSG_MODEL_END_DECL);
809 fsg_model_writefile(
fsg_model_t *fsg,
char const *file)
815 E_INFO(
"Writing FSG file '%s'\n", file);
817 if ((fp = fopen(file,
"w")) == NULL) {
818 E_ERROR(
"Failed to open FSG file '%s' for reading: %s\n", file, strerror(errno));
822 fsg_model_write(fsg, fp);
828 fsg_model_write_fsm_trans(
fsg_model_t *fsg,
int i, FILE *fp)
832 for (itor = fsg_model_arcs(fsg, i); itor;
833 itor = fsg_arciter_next(itor)) {
835 fprintf(fp,
"%d %d %s %f\n",
836 tl->from_state, tl->to_state,
837 (tl->
wid < 0) ?
"<eps>" : fsg_model_word_str(fsg, tl->
wid),
848 fsg_model_write_fsm_trans(fsg, fsg_model_start_state(fsg), fp);
851 for (i = 0; i < fsg->
n_state; i++) {
852 if (i == fsg_model_start_state(fsg))
854 fsg_model_write_fsm_trans(fsg, i, fp);
858 fprintf(fp,
"%d 0\n", fsg_model_final_state(fsg));
864 fsg_model_writefile_fsm(
fsg_model_t *fsg,
char const *file)
870 E_INFO(
"Writing FSM file '%s'\n", file);
872 if ((fp = fopen(file,
"w")) == NULL) {
873 E_ERROR(
"Failed to open fsm file '%s' for writing: %s\n", file, strerror(errno));
877 fsg_model_write_fsm(fsg, fp);
883 fsg_model_write_symtab(
fsg_model_t *fsg, FILE *file)
887 fprintf(file,
"<eps> 0\n");
888 for (i = 0; i < fsg_model_n_word(fsg); ++i) {
889 fprintf(file,
"%s %d\n", fsg_model_word_str(fsg, i), i + 1);
895 fsg_model_writefile_symtab(
fsg_model_t *fsg,
char const *file)
901 E_INFO(
"Writing FSM symbol table '%s'\n", file);
903 if ((fp = fopen(file,
"w")) == NULL) {
904 E_ERROR(
"Failed to open symbol table '%s' for writing: %s\n", file, strerror(errno));
908 fsg_model_write_symtab(fsg, fp);