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);
}
Esempio n. 2
0
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;
}