void fsg_model_trans_add(fsg_model_t * fsg, int32 from, int32 to, int32 logp, int32 wid) { fsg_link_t *link; glist_t gl; gnode_t *gn; if (fsg->trans[from].trans == NULL) fsg->trans[from].trans = hash_table_new(5, HASH_CASE_YES); /* Check for duplicate link (i.e., link already exists with label=wid) */ for (gn = gl = fsg_model_trans(fsg, from, to); gn; gn = gnode_next(gn)) { link = (fsg_link_t *) gnode_ptr(gn); if (link->wid == wid) { if (link->logs2prob < logp) link->logs2prob = logp; return; } } /* Create transition object */ link = listelem_malloc(fsg->link_alloc); link->from_state = from; link->to_state = to; link->logs2prob = logp; link->wid = wid; /* Add it to the list of transitions and update the hash table */ gl = glist_add_ptr(gl, (void *) link); hash_table_replace_bkey(fsg->trans[from].trans, (char const *) &link->to_state, sizeof(link->to_state), gl); }
static fsg_pnode_t * fsg_psubtree_init(fsg_lextree_t *lextree, fsg_model_t * fsg, int32 from_state, fsg_pnode_t ** alloc_head) { int32 dst; gnode_t *gn; fsg_link_t *fsglink; fsg_pnode_t *root; int32 n_ci; fsg_glist_linklist_t *glist = NULL; root = NULL; assert(*alloc_head == NULL); n_ci = bin_mdef_n_ciphone(lextree->mdef); if (n_ci > (FSG_PNODE_CTXT_BVSZ * 32)) { E_FATAL ("#phones > %d; increase FSG_PNODE_CTXT_BVSZ and recompile\n", FSG_PNODE_CTXT_BVSZ * 32); } for (dst = 0; dst < fsg_model_n_state(fsg); dst++) { /* Add all links from from_state to dst */ for (gn = fsg_model_trans(fsg, from_state, dst); gn; gn = gnode_next(gn)) { /* Add word emitted by this transition (fsglink) to lextree */ fsglink = (fsg_link_t *) gnode_ptr(gn); assert(fsg_link_wid(fsglink) >= 0); /* Cannot be a null trans */ root = psubtree_add_trans(lextree, root, &glist, fsglink, lextree->lc[from_state], lextree->rc[dst], alloc_head); } } fsg_glist_linklist_free(glist); return root; }