Network的数据项initial的数据类型是NetNode。它的类型type是n_word。它是AddInitialFinal(Lattice *wnet, Network *net,int xc)函数中添加进入Network中的。
它的links指向识别网络的开始节点(或有多个)。
进入正题,AttachInst函数,首先创建对象NetInst,它是用来存放tokens和links的。然后设置Inst的输出连接次数n,为0表示1-Best搜索;随后,构建识别的中间状态和出口状态,它们是关于TokenSet的。最后确定inst的后续传递路径。
已知pri有head和tail两个指针,它们是识别信息precinfo的头、尾两个分别指向NetInst的指针。我们看看NetInst的内容:
/* The instances actually store tokens and links etc */
/* Instances are stored in creation/token propagation order to allow */
/* null/word/tee instances to be connected together and still do propagation */
/* in one pass. Only HMMs need extra tokens, others are 1 state */
struct _NetInst
{
struct _NetInst *link; /* Doubly linked list of instances, forward */
struct _NetInst *knil; /* Doubly linked list of instances, backward */
NetNode *node; /* Position of instance within network */
int flags; /* Flags, active ... */
TokenSet *state; /* TokenSet[0..N-2] in state [1..N-1] for hmm */
TokenSet *exit; /* TokenSet in exit state */
LogFloat wdlk; /* Max likelihood of t=0 path to word end node */
LogFloat max; /* Likelihood for pruning of instance */
Boolean pxd; /* External propagation done this frame */
Boolean ooo; /* Instance potentially out of order */
#ifdef SANITY
int ipos;
#endif
};
precinfo包含了head和tail的指向该结构体的指针,这个结构体作为节点,可以构成双向链表,next为link;previous为knil。节点信息则包括state、exit、wdlk和max。每经过一个Inst,就把它接入到链表的tail后面。输出时,从head开始输出,一直到tail结束。
因此,precinfo包含了识别处理时经过的NetInst顺序节点。每个节点都携带了识别的过程信息,比如路径、语言模型打分、输出概率模型分数等等。
把新创建的Inst追加到precinfo的tail后面(注意双向链表的指向关系)。
inst->link=&pri->tail;
inst->knil=pri->tail.knil;
inst->link->knil=inst;
inst->knil->link=inst;
根据上面的四行代码,实现在pri->tail后面添加inst,示意图如下:
由于该Inst是为net->intial创建的,因此它们之间有双边指向的关系,(inst->node = inital; initial->inst = inst)。
接着,重排序节点信息。看下一章关于ReOrderList函数代码。