/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* dfa.h --- DFA structures for fa-parser and word-pair info for 1st pass */

/* $Id: dfa.h,v 1.8 2003/01/06 16:10:39 ri Exp $ */

#ifndef __SENT_DFA_H__
#define __SENT_DFA_H__

#include <sent/stddefs.h>

#define DFA_STATESTEP 1000	/* allocate step of DFA state */

#define INITIAL_S 0x10000000	/* initial status flag */
#define ACCEPT_S  0x00000001	/* accept status flag */

/* DFA state */
typedef struct __dfa_state__ {
  int      	number;		/* unique ID */
  unsigned int	status;		/* status flag */
  struct __dfa_arc__	*arc;	/* pointer to the arc list */
} DFA_STATE;

/* transition arc */
typedef struct __dfa_arc__ {
  short label;                  /* input = category ID */
  int to_state;			/* pointer to next state */
  struct __dfa_arc__   *next;	/* pointer to next arc in the same state */
} DFA_ARC;

/* terminal (=category) info */
typedef struct __termword__ {
  int term_num;			/* total num of category */
  WORD_ID **tw;			/* words in the category [c][0..wnum[c]-1] */
  int *wnum;			/* num of word for each category [c] */
} TERM_INFO;

/* total DFA info */
typedef struct __dfainfo__ {
  DFA_STATE *st;		/* array of all DFA state */
  int maxstatenum;		/* maximum (=allocated) number of states */
  int state_num;		/* total number of states */
  int arc_num;			/* total number of arcs */
  int term_num;			/* total number of categories */
  /* category-pair constraint */
  /* cp[c1][c2] -> (c2%8)th bit on cp[c1][c2/8] */
  /* cp_begin[c2] -> (c2%8)th bit on cp_begin[c2/8] */
  /* cp_end[c2] -> (c2%8)th bit on cp_end[c2/8] */
  unsigned char **cp;		/* [c1][c2] = TRUE if c2 can follow c1 */
  unsigned char *cp_begin;		/* [c] = TRUE if c can appear at beginning of sentence */
  unsigned char *cp_end;		/* [c] = TRUE if c can appear at end of sentence */
  unsigned char *cp_root;	/* hold root pointer of cp */
  TERM_INFO term;		/* terminal (category) info */
  boolean *is_sp;		/* TRUE if category contains only sp */
  WORD_ID sp_id;		/* a short pause word's word ID */
} DFA_INFO;


DFA_INFO *dfa_info_new();
void dfa_info_free(DFA_INFO *dfa);
void dfa_state_init(DFA_INFO *dinfo);
void dfa_state_expand(DFA_INFO *dinfo, int needed);
boolean rddfa(FILE *fp, DFA_INFO *dinfo);
boolean rddfa_fd(int fd, DFA_INFO *dinfo);
boolean rddfa_line(char *line, DFA_INFO *dinfo, int *state_max, int *arc_num, int *terminal_max);
void dfa_append(DFA_INFO *dst, DFA_INFO *src, int soffset, int coffset);

void init_dfa(DFA_INFO *dinfo, char *filename);
WORD_ID dfa_symbol_lookup(DFA_INFO *dinfo, char *terminalname);
void extract_cpair(DFA_INFO *dinfo);
void cpair_append(DFA_INFO *dst, DFA_INFO *src, int coffset);
void print_dfa_info(DFA_INFO *dinfo);
void print_dfa_cp(DFA_INFO *dinfo);
boolean dfa_cp(DFA_INFO *dfa, int i, int j);
boolean dfa_cp_begin(DFA_INFO *dfa, int i);
boolean dfa_cp_end(DFA_INFO *dfa, int i);
void set_dfa_cp(DFA_INFO *dfa, int i, int j, boolean value);
void set_dfa_cp_begin(DFA_INFO *dfa, int i, boolean value);
void set_dfa_cp_end(DFA_INFO *dfa, int i, boolean value);
void init_dfa_cp(DFA_INFO *dfa);
void malloc_dfa_cp(DFA_INFO *dfa, int term_num);
void realloc_dfa_cp(DFA_INFO *dfa, int old_term_num, int new_term_num);
void free_dfa_cp(DFA_INFO *dfa);



#include <sent/vocabulary.h>
void make_dfa_voca_ref(DFA_INFO *dinfo, WORD_INFO *winfo);
void make_terminfo(TERM_INFO *tinfo, DFA_INFO *dinfo, WORD_INFO *winfo);
void terminfo_append(TERM_INFO *dst, TERM_INFO *src, int coffset, int woffset);
#include <sent/htk_hmm.h>
void dfa_find_pause_word(DFA_INFO *dfa, WORD_INFO *winfo, HTK_HMM_INFO *hmminfo);
void dfa_pause_word_append(DFA_INFO *dst, DFA_INFO *src, int coffset);

#endif /* __SENT_DFA_H__ */
