// file: $isip/class/pr/HiddenMarkovModel/HiddenMarkovModel.h
// version: $Id: HiddenMarkovModel.h 10636 2007-01-26 22:18:09Z tm334 $
//

// make sure definitions are only made once
//
#ifndef ISIP_HIDDEN_MARKOV_MODEL
#define ISIP_HIDDEN_MARKOV_MODEL

#ifndef ISIP_DOUBLE
#include <Double.h>
#endif

#ifndef ISIP_ULONG
#include <Ulong.h>
#endif

#ifndef ISIP_VECTOR_BYTE
#include <VectorByte.h>
#endif

#ifndef ISIP_MATRIX_FLOAT
#include <MatrixFloat.h>
#endif

#ifndef ISIP_FRONT_END
#include <FrontEnd.h>
#endif

#ifndef ISIP_TRAIN_NODE
#include <TrainNode.h>
#endif

#ifndef ISIP_WRAPPER
#include <Wrapper.h>
#endif

#ifndef ISIP_HASH_KEY
#include <HashKey.h>
#endif

#ifndef ISIP_LANGUAGE_MODEL
#include <LanguageModel.h>
#endif

#ifndef ISIP_LANGUAGE_MODEL_IHD
#include <LanguageModelIHD.h>
#endif

#ifndef ISIP_HIERARCHICAL_SEARCH
#include <HierarchicalSearch.h>
#endif

#ifndef ISIP_STACK_SEARCH
#include <StackSearch.h>
#endif

#ifndef ISIP_TRANSCRIPTION_DATABASE
#include <TranscriptionDatabase.h>
#endif

#ifndef ISIP_AUDIO_DATABASE
#include <AudioDatabase.h>
#endif

#ifndef ISIP_SYMBOL_GRAPH_DATABASE
#include <SymbolGraphDatabase.h>
#endif

#ifndef ISIP_ANNOTATION_GRAPH
#include <AnnotationGraph.h>
#endif

#ifndef ISIP_ANNOTATION
#include <Annotation.h>
#endif

#ifndef ISIP_NBEST_PATH
#include <NBestPath.h>
#endif

#ifndef ISIP_SDB
#include <Sdb.h>
#endif

#ifndef ISIP_PHONETIC_DECISION_TREE
#include <PhoneticDecisionTree.h>
#endif

#ifndef ISIP_MAXIMUM_LIKELIHOOD_LINEAR_REGRESSION
#include <MaximumLikelihoodLinearRegression.h>
#endif

#ifndef ISIP_ANNOTATION_GRAPH
#include <AnnotationGraph.h>
#endif


// HiddenMarkovModel: an intermediate class providing base
//                    for Decode and Train algorithm using
//                    Viterbi or Baum-Welch implementation
//
class HiddenMarkovModel {
  
  //--------------------------------------------------------------------------
  //
  // public constants
  //
  //--------------------------------------------------------------------------
public:
  
  // define the class name
  //
  static const String CLASS_NAME;

  //----------------------------------------
  //
  // other important constants
  //
  //----------------------------------------

  // define the algorithm choices
  //
  enum ALGORITHM { DECODE = 0, TRAIN, MODEL_CREATION, INITIALIZE,
		   MIXTURE_SPLITTING,
		   CONTEXT_GENERATION, TRAIN_PARAMETER_TYING,
		   TEST_PARAMETER_TYING, FORCED_ALIGNMENT,
		   MLLR, MAP, SYMBOL_GRAPH_GENERATION,
		   SYMBOL_GRAPH_RESCORING, NBEST_GENERATION,
		   DEF_ALGORITHM = DECODE };
  
  // define the implementation choices
  //
  enum IMPLEMENTATION { VITERBI = 0, STACK, BAUM_WELCH, GLOBAL, 
			VARIANCE_SPLITTING, SYMBOL_GENERATION, ML,
			MODEL_GENERATION, WORD_DEPENDENT_NBEST, VITERBI_NBEST,
			RESCORE_ACOUSTIC, RESCORE_LANGUAGE, RESCORE_BOTH,
			DEF_IMPLEMENTATION = VITERBI };

  // define the context choices
  //
  enum CONTEXT_MODE { SYMBOL_ONLY = 0, SYMBOL_INTERNAL, CROSS_SYMBOL, 
		      DEF_CONTEXT_MODE = SYMBOL_ONLY };

  // define the cross-word choices
  //
  enum FUNCTION_MODE { NONE = 0, GRAMMAR_DECODING, NETWORK_DECODING,
		       ACCUMULATE, UPDATE, DEF_FUNCTION_MODE = NONE };    

  // define modes
  //
  enum MODE { FILE = 0, TRANSFORM, LIST, DATABASE,
	      DEF_MODE = DATABASE };

  // define update modes
  //
  enum UPDATE_MODE { TRANSITIONS = 0, OBSERVATIONS, ALL, DEF_UPDATE_MODE = ALL };  

  // define output formats
  //
  enum FORMAT { NIST_SCORE = 0, NATIVE, JSGF, IHD, XML, ABNF, BNF,
		SYMBOL_GRAPH, DEF_FORMAT = IHD };

  // define output types
  //
  enum TYPE { TEXT = 0, BINARY, DEF_TYPE = BINARY };  

  // define internal on/off states
  //  
  static const byte OFF = 0;
  static const byte ON = 1;

  // define internal default values
  //
  static const String DEF_TRANSCRIPTION_LEVEL;
  static const String DEF_SYMBOL_GRAPH_LEVEL;  
  static const String DEF_FORCE_ALIGNMENT_LEVEL;
  
  // define internal constants
  //
  static const float DEF_WEIGTH_ONE = 0;
  static const float DEF_WEIGTH_HALF = -0.693147;
  static const float DEF_BETA_PRUNING_THRESHOLD = 3.40282347e+38F;  
  static const float DEF_FLT_MIN = 1.17549435e-38F;
  static const float DEF_FLT_MAX = 3.40282347e+38F;
  static const float DEF_DBL_MIN = 2.2250738585072014e-308;
  static const float DEF_DBL_MAX = 1.7976931348623157e+308;
  
  // define the static NameMap objects
  //
  static const NameMap IMPL_MAP;
  static const NameMap ALGO_MAP;
  static const NameMap CONTEXT_MODE_MAP;
  static const NameMap FUNCTION_MODE_MAP;    
  static const NameMap MODE_MAP;
  static const NameMap FORMAT_MAP;
  static const NameMap TYPE_MAP;    
  static const NameMap UPDATE_MODE_MAP; 
  
  //----------------------------------------
  //
  // i/o related constants
  //
  //----------------------------------------
  
  static const String DEF_PARAM;
  static const String PARAM_UPDATE_LEVELS;
  static const String PARAM_NUM_MIXTURES;  
  static const String PARAM_NUM_ITERATIONS;
  static const String PARAM_VAR_FLOOR;
  static const String PARAM_VAR_FLOOR_FILE;
  static const String PARAM_BETA_THRESHOLD;
  static const String PARAM_TRANSCRIPTION_LEVEL;
  static const String PARAM_SYMBOL_GRAPH_LEVEL;  
  static const String PARAM_FORCE_ALIGNMENT_LEVEL;
  static const String PARAM_TRANS_DB;
  static const String PARAM_AUDIO_DB;
  static const String PARAM_SYMBOL_GRAPH_DB;  
  static const String PARAM_MIN_MPD;
  static const String PARAM_MIN_OCCUPANCY;
  static const String PARAM_MIN_MODEL_COUNT;    
  static const String PARAM_ALGORITHM;
  static const String PARAM_IMPLEMENTATION;

  static const String PARAM_NBEST_PATHS;
  static const String PARAM_MAX_NBEST_PATHS;
  static const String PARAM_NBEST_BEAM;  
  
  static const String PARAM_CONFIGURATION;
  static const String PARAM_FRONT_END;  
  static const String PARAM_LANGUAGE_MODEL;
  static const String PARAM_STATISTICAL_MODEL_POOL;    
  static const String PARAM_UPDATE_LANGUAGE_MODEL;
  static const String PARAM_UPDATE_STATISTICAL_MODEL_POOL;
  static const String PARAM_ACCUMULATOR;
  static const String PARAM_ACCUMULATOR_LIST;
  
  static const String PARAM_OUTPUT_MODE;
  static const String PARAM_OUTPUT_FORMAT;
  static const String PARAM_OUTPUT_TYPE;  
  static const String PARAM_OUTPUT_LEVELS;
  static const String PARAM_UPDATE_MODE;
  static const String PARAM_FUNCTION_MODE;
  static const String PARAM_CONTEXT_MODE;
  static const String PARAM_CONTEXT_LEVEL;
  static const String PARAM_CONTEXT_ORDER;    
  static const String PARAM_OUTPUT_FILE;
  static const String PARAM_OUTPUT_LIST;    
  static const String PARAM_CONTEXT_LIST;
  static const String PARAM_QUES_ANS;
  static const String PARAM_PHONETIC_DT;
  static const String PARAM_PHONETIC_DT_SPLIT_THRESHOLD;
  static const String PARAM_PHONETIC_DT_MERGE_THRESHOLD;
  static const String PARAM_PHONETIC_DT_NUM_OCC_THRESHOLD;
  static const String PARAM_MLLR;
  
  static const String OPTION_TEXT;
  static const String OPTION_BINARY;  
  static const String OPTION_MODE_FILE;
  static const String OPTION_MODE_TRANSFORM;
  static const String OPTION_MODE_LIST;
  static const String OPTION_MODE_DATABASE;  
  static const String OPTION_FORMAT_NIST_SCORE;
  static const String OPTION_FORMAT_NATIVE;
  static const String OPTION_FORMAT_JSGF;
  static const String OPTION_UPDATE_TRANSITIONS;
  static const String OPTION_UPDATE_OBSERVATIONS;
  static const String OPTION_UPDATE_ALL;
  static const String OPTION_FUNCTION_NONE;
  static const String OPTION_FUNCTION_GRAMMAR_DECODING;
  static const String OPTION_FUNCTION_NETWORK_DECODING;
  static const String OPTION_FUNCTION_ACCUMULATE;
  static const String OPTION_FUNCTION_UPDATE;
  static const String OPTION_TRANSCRIPTION_LEVEL;
  
  //----------------------------------------
  //
  // default values and arguments
  //
  //----------------------------------------
  
  // default values
  //
  static const boolean DEF_VERIFY = false;
  static const boolean DEF_STREAM = false;

  static const long DEF_NBEST_PATHS = 10;
  static const long DEF_MAX_NBEST_PATHS = 50;
  static const long DEF_NBEST_BEAM = 100;
  
  static const long DEF_INITIAL_LEVEL = 0;
  static const long DEF_ALIGNMENT_LEVEL = -1;
  
  static const long DEF_NUM_LEVELS = 3;
  static const long DEF_NUM_MIXTURES = 1;  
  static const long DEF_NUM_ITERATIONS = 1;
  static const long DEF_CONTEXT_LEVEL = 0;
  static const long DEF_CONTEXT_ORDER = 3;    
  static const long DEF_CAPACITY = 12000;  
  static const float DEF_MIN_MPD = 1000;
  static const float DEF_MIN_OCCUPANCY = 1.0e-10;
  static const long DEF_MIN_MODEL_COUNT = 1;
  static const float DEF_VAR_FLOOR = 2e-4;
  
  //----------------------------------------
  //
  // error codes
  //
  //----------------------------------------  

  static const long ERR = (long)100000;
  static const long ERR_ADAPT_NO_GAUSSIAN = (long)100050;
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:
  
  // algorithm name
  //
  ALGORITHM algorithm_d;
  
  // implementation name
  //
  IMPLEMENTATION implementation_d;

  // context mode
  //
  CONTEXT_MODE context_mode_d;

  // cross-word mode
  //
  FUNCTION_MODE function_mode_d;  
  
  // output mode
  //
  MODE output_mode_d;

  // update mode
  //
  UPDATE_MODE update_mode_d;  
  
  // output format
  //
  FORMAT output_format_d;

  // output type
  //
  TYPE output_type_d;  

  // update levels
  //
  String update_levels_str_d;
  
  // vector that contains the indices of re-estimation update levels
  //
  VectorByte update_levels_d;
  
  // output levels
  //
  String output_levels_str_d;
  
  // vector that contains the indices of hypothesis output levels
  //
  VectorByte output_levels_d;

  // parameter file
  //
  Filename param_file_d;

  // language model file
  //
  Filename lm_file_d;

  // statistical model pool file
  //
  Filename smp_file_d;

  // configuration file
  //
  Filename cnfg_file_d;

  // fornt-end file
  //
  Filename fend_file_d;
  
  // updated model file
  //
  Filename update_lm_file_d;

  // updated statistics file
  //
  Filename update_smp_file_d;    

  // transcription file
  //
  Filename transcription_db_file_d;  

  // audio database file
  //
  Filename audio_db_file_d;

  // symbol graph database file
  //
  Filename symbol_graph_db_file_d;  

  // output file
  //
  Filename output_file_d;

  // accumulator file
  //
  Filename accum_file_d;

  // accumulator list
  //
  Filename accum_list_d;  

  // acumulator path
  //
  Filename accumulator_path_d;
  
  // accumulator name
  //
  String accumulator_name_d;
  
  // output list file
  //
  Filename output_list_d;
  
  // context generation file
  //
  Filename context_list_d;
  
  // variance floor file
  //
  Filename variance_floor_file_d;  

  // phonetic question-answers file
  //
  Filename ques_ans_file_d;  

  // phonetic decision-tree file
  //
  Filename phonetic_dt_file_d;  

  // split-threshold for the phonetic-decision-tree
  //
  Float phonetic_dt_split_threshold_d;

  // merge-threshold for the phonetic-decision-tree
  //
  Float phonetic_dt_merge_threshold_d;

  // num_occ-threshold for the phonetic-decision-tree
  //
  Float phonetic_dt_num_occ_threshold_d;

  // variance floor
  //
  Float variance_floor_d;

  // beta pruning threshold
  //
  Float beta_threshold_d;  

  // transcription level
  //
  String transcription_level_d;

  // symbol graph level
  //
  String symbol_graph_level_d;  

  // initial level
  //
  Long initial_level_d;

  // alignment level
  //
  String force_alignment_level_d;

  // force alignment level
  //
  Long alignment_level_d;
  
  // context level
  //
  Long context_level_d;

  // context order
  //
  Long context_order_d;    

  // n-best hypothesis generation parameters
  //
  Long nbest_paths_d;
  Long max_nbest_paths_d;
  Long nbest_beam_d;
  
  // streaming input flag
  //
  boolean stream_d;
  
  // verification mode flag
  //
  boolean verify_d;
  
  // front end
  //
  Vector<FrontEnd> vector_fe_d;
  
  // utterance trellis
  //
  BiGraph<TrainNode>* trellis_d;

  // hierarchical search
  //
  HierarchicalSearch search_engine_d;

  // language model
  //
  LanguageModelIHD lm_d;

  // stack search
  //
  StackSearch stack_engine_d;

  // number of search levels
  //
  Long num_levels_d;

  // number of mixtures
  //
  Long num_mixtures_d;  

  // number of iterations of training
  //
  Long num_iterations_d;  

  // minimum model probability deviance
  //
  Float min_mpd_d;

  // floor on the occupancy probability
  //
  Float min_occupancy_d;

  // minimum number of times a model must occur before update
  //
  Long min_model_count_d;

  // transcription database
  //
  TranscriptionDatabase transcription_db_d;

  // audio database
  //
  AudioDatabase audio_db_d;

  // Maximum likelihood linear regression object
  //
  MaximumLikelihoodLinearRegression mllr_d;
  
  // symbol graph database
  //
  SymbolGraphDatabase symbol_graph_db_d;  

  // debug level
  //
  static Integral::DEBUG debug_level_d;
  
  // verbosity
  //
  static Integral::DEBUG verbosity_d;

  // static memory manager
  //
  static MemoryManager mgr_d;
  
  //---------------------------------------------------------------------------
  //
  // required public methods
  //
  //---------------------------------------------------------------------------
public:
  
  // method: name
  //
  static const String& name() {
    return CLASS_NAME;
  }

  // other static methods
  //   
  static boolean diagnose(Integral::DEBUG debug_level);

  // method: setDebug
  //
  boolean setDebug(Integral::DEBUG debug_level) {
    debug_level_d = debug_level;
    HierarchicalSearch::setDebug(debug_level);
    SymbolGraph::setDebug(debug_level);
    SymbolGraphNode::setDebug(debug_level);        
    StackSearch::setDebug(debug_level);
    SearchNode::setDebug(debug_level);
    Trace::setDebug(debug_level);
    Instance::setDebug(debug_level);
    History::setDebug(debug_level);
    Context::setDebug(debug_level);    
    return true;
  }
  
  // constructor(s)/destructor(s)
  //
  ~HiddenMarkovModel();
  HiddenMarkovModel();
  HiddenMarkovModel(const HiddenMarkovModel& arg);

  // method: assign
  //
  boolean assign(const HiddenMarkovModel& arg) {
    return Error::handle(name(), L"assign", Error::ARG, __FILE__, __LINE__);
  }
  
  // i/o methods
  //
  long sofSize() const;
  boolean read(Sof& sof, long tag, const String& name = CLASS_NAME);
  boolean write(Sof& sof, long tag, const String& name = CLASS_NAME) const;
  
  boolean readData(Sof& sof, const String& pname = DEF_PARAM,
		   long size = SofParser::FULL_OBJECT,
		   boolean param = true,
		   boolean nested = false);
  boolean writeData(Sof& sof, const String& param = DEF_PARAM) const;
  
  // method: new
  //
  static void* operator new(size_t size) {
    return mgr_d.get();
  }

  // method: new[]
  //
  static void* operator new[](size_t size) {
    return mgr_d.getBlock(size);
  }

  // method: delete
  //
  static void operator delete(void* ptr) {
    mgr_d.release(ptr);
  }

  // method: delete[]
  //
  static void operator delete[](void* ptr) {
    mgr_d.releaseBlock(ptr);
  }

  // method: setGrowSize
  //
  static boolean setGrowSize(long grow_size) {
    return mgr_d.setGrow(grow_size);
  }

  //---------------------------------------------------------------------------
  //
  // class-specific public methods
  //  set methods
  //
  //---------------------------------------------------------------------------
  
  // method: getStream
  //
  boolean getStream() {
    return stream_d;
  }

  // method: setStream
  //
  boolean setStream(boolean arg) {
    return (stream_d = arg);
  }

  // method: getAlgorithm
  //
  ALGORITHM getAlgorithm() {
    return algorithm_d;
  }

  // method: setAlgorithm
  //
  boolean setAlgorithm(ALGORITHM arg) {
    return (algorithm_d = arg);
  }

  // method: getImplementation
  //
  IMPLEMENTATION getImplementation() {
    return implementation_d;
  }
  
  // method: setImplementation
  //
  boolean setImplementation(IMPLEMENTATION arg) {
    return (implementation_d = arg);
  }

  // method: getContextMode
  //
  CONTEXT_MODE getContextMode() {
    return context_mode_d;
  }
  
  // method: setContextMode
  //
  boolean setContextMode(CONTEXT_MODE arg) {
    return (context_mode_d = arg);
  }  

  // method: setFunctionMode
  //
  boolean setFunctionMode(const String& arg);
  
  // method: getFunctionMode
  //
  FUNCTION_MODE getFunctionMode() {
    return function_mode_d;
  }

  // method: setOutputMode
  //
  boolean setOutputMode(const String& arg);
  
  // method: getOutputMode
  //
  MODE getOutputMode() {
    return output_mode_d;
  }

  // method: setUpdateMode
  //
  boolean setUpdateMode(const String& arg);
  
  // method: getUpdateMode
  //
  UPDATE_MODE getUpdateMode() {
    return update_mode_d;
  }

  // method: setOutputFormat
  //
  boolean setOutputFormat(const String& arg);
  
  // method: setOutputLevelString
  //
  boolean setOutputLevelString(const String& arg) {
    return output_levels_str_d.assign(arg);
  }

  // method: setUpdateLevelString
  //
  boolean setUpdateLevelString(const String& arg) {
    return update_levels_str_d.assign(arg);
  }  

  // method: setAccumulatorPath
  boolean setAccumulatorPath(const Filename& arg) {
    return accumulator_path_d.assign(arg);
  }

  // method: setAccumulatorName
  boolean setAccumulatorName(const String& arg) {
    return accumulator_name_d.assign(arg);
  }
  
  // method: getOutputFormat
  //
  FORMAT getOutputFormat() {
    return output_format_d;
  }

  // method: setOutputType
  //
  boolean setOutputType(const String& arg);
  
  // method: getOutputType
  //
  TYPE getOutputType() {
    return output_type_d;
  }
  
  // method: getParamFile
  //
  Filename& getParamFile() {
    return param_file_d;
  }
  
  // method: setParamFile
  //
  boolean setParamFile(const Filename& arg) {
    return param_file_d.assign(arg);
  }

  // method: getLanguageModelFile
  //
  Filename& getLanguageModelFile() {
    return lm_file_d;
  }
  
  // method: setLanguageModelFile
  //
  boolean setLanguageModelFile(const Filename& arg) {
    return lm_file_d.assign(arg);
  }    

  // method: getStatisticalModelPoolFile
  //
  Filename& getStatisticalModelPoolFile() {
    return smp_file_d;
  }
  
  // method: setStatisticalModelPoolFile
  //
  boolean setStatisticalModelPoolFile(const Filename& arg) {
    return smp_file_d.assign(arg);
  }

  // method: getConfigFile
  //
  Filename& getConfigFile() {
    return cnfg_file_d;
  }
  
  // method: setConfigFile
  //
  boolean setConfigFile(const Filename& arg) {
    return cnfg_file_d.assign(arg);
  }

  // method: getFrontEndFile
  //
  Filename& getFrontEndFile() {
    return fend_file_d;
  }
  
  // method: setFrontEndFile
  //
  boolean setFrontEndFile(const Filename& arg) {
    return fend_file_d.assign(arg);
  }

  // method: getLanguageModelUpdateFile
  //
  Filename& getLanguageModelUpdateFile() {
    return update_lm_file_d;
  }
  
  // method: setLanguageModelUpdateFile
  //
  boolean setLanguageModelUpdateFile(const Filename& arg) {
    return update_lm_file_d.assign(arg);
  }    

  // method: getStatisticalModelPoolUpdateFile
  //
  Filename& getStatisticalModelPoolUpdateFile() {
    return update_smp_file_d;
  }
  
  // method: setStatisticalModelPoolUpdateFile
  //
  boolean setStatisticalModelPoolUpdateFile(const Filename& arg) {
    return update_smp_file_d.assign(arg);
  }

  // method: getAccumulatorFile
  //
  Filename& getAccumulatorFile() {
    return accum_file_d;
  }

  // method: setAccumulatorFile
  //
  boolean setAccumulatorFile(const Filename& arg) {
    return accum_file_d.assign(arg);
  }  

  // method: getAccumulatorList
  //
  Filename& getAccumulatorList() {
    return accum_list_d;
  }
  
  // method: setAccumulatorList
  //
  boolean setAccumulatorList(const Filename& arg) {
    return accum_list_d.assign(arg);
  }
  
  // method: getOutputFile
  //
  Filename& getOutputFile() {
    return output_file_d;
  }
  
  // method: setOutputFile
  //
  boolean setOutputFile(const Filename& arg) {
    return output_file_d.assign(arg);
  }
  
  // method: getOutputList
  //
  Filename& getOutputList() {
    return output_list_d;
  }
  
  // method: setOutputList
  //
  boolean setOutputList(const Filename& arg) {
    return output_list_d.assign(arg);
  }

  // method: getContextList
  //
  Filename& getContextList() {
    return context_list_d;
  }
  
  // method: setContextList
  //
  boolean setContextList(const Filename& arg) {
    return context_list_d.assign(arg);
  }

  // method: getVarianceFloorFile
  //
  Filename& getVarianceFloorFile() {
    return variance_floor_file_d;
  }
  
  // method: setVarianceFloorFile
  //
  boolean setVarianceFloorFile(const Filename& arg) {
    return variance_floor_file_d.assign(arg);
  }

  // method: getVarianceFloor
  //  
  float getVarianceFloor() {
    return (float)variance_floor_d;
  }
  
  // method: setVarianceFloor
  //
  boolean setVarianceFloor(float arg) {
    return variance_floor_d.assign(arg);
  }

  // method: getBetaThreshold
  //  
  float getBetaThreshold() {
    return (float)beta_threshold_d;
  }
  
  // method: setBetaThreshold
  //
  boolean setBetaThreshold(float arg) {
    return beta_threshold_d.assign(arg);
  }

  // method: getInitialLevel
  //  
  long getInitialLevel() {
    return (long)initial_level_d;
  }
  
  // method: setInitialLevel
  //
  boolean setInitialLevel(long arg) {
    return initial_level_d.assign(arg);
  }

  // method: getContextLevel
  //  
  long getContextLevel() {
    return (long)context_level_d;
  }
  
  // method: setContextLevel
  //
  boolean setContextLevel(long arg) {
    return context_level_d.assign(arg);
  }

  // method: getContextOrder
  //  
  long getContextOrder() {
    return (long)context_order_d;
  }
  
  // method: setContextOrder
  //
  boolean setContextOrder(long arg) {
    return context_order_d.assign(arg);
  }  
  
  // method: getNumLevels
  //  
  long getNumLevels() {
    return (long)num_levels_d;
  }
  
  // method: setNumLevels
  //
  boolean setNumLevels(long arg) {
    return num_levels_d.assign(arg);
  }

  // method: getNumMixtures
  //  
  long getNumMixtures() {
    return (long)num_mixtures_d;
  }
  
  // method: setNumMixtures
  //
  boolean setNumMixtures(long arg) {
    return num_mixtures_d.assign(arg);
  } 
 
  // method: getNumIterations
  //  
  long getNumIterations() {
    return (long)num_iterations_d;
  }
  
  // method: setNumIterations
  //
  boolean setNumIterations(long arg) {
    return num_iterations_d.assign(arg);
  } 

  // method: getMinProbabilityDeviance
  //  
  float getMinProbabilityDeviance() {
    return (float)min_mpd_d;
  }
  
  // method: setMinProbabilityDeviance
  //
  boolean setMinProbabilityDeviance(float arg) {
    return min_mpd_d.assign(arg);
  } 

  // method: getMinOccupancy
  //  
  float getMinOccupancy() {
    return (float)min_occupancy_d;
  }
  
  // method: setMinOccupancy
  //
  boolean setMinOccupancy(float arg) {
    return min_occupancy_d.assign(arg);
  } 

  // method: getMinModelCount
  //  
  long getMinModelCount() {
    return (long)min_model_count_d;
  }
  
  // method: setMinModelCount
  //
  boolean setMinModelCount(long arg) {
    return min_model_count_d.assign(arg);
  } 
  
  // method: getSplitThreshold
  //
  float getSplitThreshold() {
    return (float)phonetic_dt_split_threshold_d;
  }

  // method: setSplitThreshold
  //
  boolean setSplitThreshold(float split_threshold) {
    phonetic_dt_split_threshold_d = split_threshold;
    return true;  
  }

  // method: getMergeThreshold
  //
  float getMergeThreshold(float merge_threshold) {
    return (float)phonetic_dt_merge_threshold_d;
  }

  // method: setMergeThreshold
  //
  boolean setMergeThreshold(float merge_threshold) {
    phonetic_dt_merge_threshold_d = merge_threshold;
    return true;  
  }

  // method: getNumOccThreshold
  //
  float getNumOccThreshold() {
    return (float)phonetic_dt_num_occ_threshold_d;
  }

  // method: setNumOccThreshold
  //
  boolean setNumOccThreshold(float num_occ_threshold) {
    phonetic_dt_num_occ_threshold_d = num_occ_threshold;
    return true;  
  }

  // method: getDecisionTreeFile
  //
  Filename& getDecisionTreeFile() {
    return phonetic_dt_file_d;
  }

  // method: setDecisionTreeFile
  //
  boolean setDecisionTreeFile(const Filename& arg) {
    return phonetic_dt_file_d.assign(arg);
  }

  // method: setQuesAnserFile
  //
  boolean setQuesAnswerFile(const Filename& arg) {
    return ques_ans_file_d.assign(arg);
  }

  // method: getQuesAnserFile
  //
  Filename& getQuesAnswerFile() {
    return ques_ans_file_d;
  }

  // method: setVerbosity
  //
  boolean setVerbosity(Integral::DEBUG verbosity) {
    verbosity_d = verbosity;
    return true;
  }

  // method: setVerify
  //
  boolean setVerify(boolean verify) {
    verify_d = verify;
    return true;  
  }

  //---------------------------------------------------------------------------
  //
  // class-specific public methods:
  //  computational methods
  //
  //---------------------------------------------------------------------------

  // run methods
  //
  boolean run(Sdb& sdb);
  boolean nonLinearDecoder(Sdb& sdb);
  boolean grammarDecoder(Sdb& sdb);
  boolean networkDecoder(Sdb& sdb);    
  boolean linearDecoder(Sdb& sdb);
  boolean parameterTying(Sdb& sdb);
  
  // parameter check methods
  //
  boolean checkParams();
  
  // load and store methods
  //
  boolean load();
  boolean store();  

  // method to compute the utterance probability
  //
  boolean computeUtterProb(double& utter_prob);
  
  // method to initialize the models
  //
  boolean initialize(Sdb& sdb);
  
  // method to extract all feature vectors from file
  //
  boolean extractFeatures(long fe_index, Vector<VectorFloat>& data);

  // method sets up a mapping table that assigns a unique index to each vertex
  //
  boolean initializeMappingTable();
  
  // method to accumulate statitics during training
  //
  boolean loadAccumulators(Sdb& sdb);
  boolean storeAccumulators();
  
  boolean accumulate(double utter_prob, Vector<VectorFloat>& data);
  boolean accumulateStateTransitions(double utter_prob,
				     Vector<VectorFloat>& data);
  boolean accumulateStatisticalModels(double utter_prob,
				      Vector<VectorFloat>& data);  
  
  // method to update the models using the accumulated statistics
  //
  boolean update();
  boolean updateStateTransitions(SearchLevel& search_level);
  boolean updateStatisticalModels(SearchLevel& search_level);
  
  // method to load and initialize the transcriptions
  //
  boolean insertNonSpeechSymbols(Vector<SearchSymbol>& boundary_symbols,
				 Vector<SearchSymbol>& internal_symbols,
				 DiGraph<SearchNode>& graph,
				 SearchLevel& level);
  boolean initTranscription(String& id, long arg);

  // method related to symbol graph rescoring
  //
  boolean initSymbolGraph(Filename& symbol_graph_file); 
  
  // method related to transcriptions
  //
  boolean agToDigraph(DiGraph<SearchNode>& digraph, AnnotationGraph& ag,
		      long& channel, float& start_time, float& stop_time,
		      boolean& is_conversation);
  
  boolean agToSegment(AnnotationGraph& ag, long& channel,
		      float& start_time, float& stop_time);
  
  // method to reset the accumulators
  //
  boolean resetAccumulators();
  
  // method for parameter-tying in train mode
  //
  boolean parameterTyingTrain();
  
  // method for parameter-tying in test mode
  //
  boolean parameterTyingTest();
  
  // method to accumulate occupancies during parameter-tying
  //
  boolean loadOccupancies();

  // method to create annotation graph from trace
  //
  boolean createAnnotationGraph(AnnotationGraph& anno,
				DoubleLinkedList<Trace>& trace_path);

  // method to create annotation graph from instance
  //
  boolean createAnnotationGraph(AnnotationGraph& anno,
				DoubleLinkedList<Instance>& instance_path);

  // method to prune the annotation graph according to the output levels
  //
  boolean pruneAnnotationGraph(AnnotationGraph& anno);

  // create statistical model pool
  //
  boolean createStatisticalModels();

  //---------------------------------------------------------------------------
  //
  // other public methods
  //
  //---------------------------------------------------------------------------

  boolean parseLevels(const String& output_levels_str,
			  VectorByte& output_levels);
  
  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
  private:

  // set methods
  //
  GraphArc<SearchNode>* getSearchArc(GraphVertex<SearchNode>* src,
				     GraphVertex<SearchNode>* dst);
  
  boolean insert(VectorByte& src, long start_index, long num_elem, byte mode);
  boolean createContexts(Vector<SearchSymbol>& symbols, long order,
			 Vector<SearchSymbol>& all_contexts);
  boolean appendContexts(Vector<SearchSymbol>& symbols,
			 SearchSymbol symbol, long curr_order, long order,
			 Vector<SearchSymbol>& all_contexts);

  // method to write the decoder n-best list to file
  //
  boolean writeNBest(Filename& output_file_name,
		     NBestPath* final_plist, SymbolGraphNode* start_node);
  
};

//end of include file
//
#endif
