// file: lat_comp_0.cc
//

// isip include files
//
#include "lattice.h"
#include "lattice_constants.h"

// method: reduce_lattice_cc
//
// arguments:
//  Lattice*& new_lat: (output) the new compact reduced lattice 
//
// return: a logical_1 indicating status
//
// this method reduces the lattice to a compact lattice
//
logical_1 Lattice::reduce_lattice_cc(Lattice*& new_lat_a) {
  
  // define some local variables
  //
  int_4 node_count = (int_4)0;
  int_4 arc_count = (int_4)0;

  // memory manager
  //
  Memory_manager* manager = Link_list::get_manager_cc();
  
  // initialize the lattice nodes of the new lattice to the size of
  // the original lattice
  //
  Lattice_node** new_lnodes = new Lattice_node*[num_nodes_d];
  
  // define a map into the new lattice from each node in the original
  // lattice
  //
  int_4* map_list = new int_4[num_nodes_d];
  for (int_4 i = 0; i < num_nodes_d; i++) {
    map_list[i] = (int_4)-1;
  }
  
  // create the new lattice
  //
  if (new_lat_a != (Lattice*)NULL) {
    delete new_lat_a;
    new_lat_a = (Lattice*)NULL;
  }
  new_lat_a = new Lattice();
  
  // set some lattice parameters
  //
  new_lat_a->lm_scale_d = lm_scale_d;
  new_lat_a->word_penalty_d = word_penalty_d;

  // copy the character strings
  //
  if (lang_model_d != (unsigned char*)NULL) {
    new_lat_a->set_lang_model_cc(lang_model_d);
  }
  if (utterance_d != (unsigned char*)NULL) {
    new_lat_a->set_utterance_cc(utterance_d);
  }
  if (model_set_d != (unsigned char*)NULL) { 
    new_lat_a->set_model_set_cc(model_set_d);
  }

  // set the start node of the new lattice to be the same as the start
  // node of the original lattice
  //
  Lattice_node* new_lstart = manager->new_lat_cc();
  new_lstart->set_word_cc(start_node_d->get_word_cc());
  new_lat_a->start_node_d = new_lstart;
  
  // place the start node at the first position in the new lattice
  // array, update the map and increment count
  //
  new_lnodes[0] = new_lstart;
  map_list[start_node_d->get_node_index_cc()] = (int_4)0;
  node_count++;

  // link all descendants of the lattice node
  //
  new_lstart->add_node_cc(start_node_d, new_lnodes, map_list,
			  node_count, arc_count);

  // set the number of nodes in the lattice
  //
  new_lat_a->num_nodes_d = node_count;
  new_lat_a->num_arcs_d = arc_count;

  // hash the nodes for the reduced lattice
  //
  for (int_4 i = 0; i < node_count; i++) {
    new_lat_a->set_lat_node_cc(new_lnodes[i]);
  }

  // clean up memory
  //
  delete [] new_lnodes;
  delete [] map_list;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
