// file: plist_prune_0.cc
//

// isip include files
//
#include "path_list.h"
#include "path_list_constants.h"
#include <decoder_constants.h>
#include <word.h>
#include <nbest_node.h>

// method: prune_cc
//
// arguments:
//  float_8 beam: (input) beam for pruning
//  int_4 max_paths: (input) maximum number of histories allowed
//
// return: a logical_1 indicating status
//
// this method performs beam pruning on the partial paths in this list
// and also keeps the stack depth to a fixed number
//
logical_1 Path_list::prune_cc(float_8 beam_a, int_4 max_paths_a) {
  
  // define local variables
  //
  float_8 beam_threshold = (float_8)DEC_DEFAULT_SCORE;
  Nbest_node* nnode = (Nbest_node*)NULL;
  Link_node* lnd = (Link_node*)NULL;
  Link_node* node = (Link_node*)NULL;
  
  // get best path from the head of the list
  //
  node = paths_d->get_head_cc();

  // get the next path
  //
  lnd = node->get_next_cc();

  // get the nbest node in the node
  //
  nnode = (Nbest_node*)(node->get_item_cc());
  beam_threshold = max_score_d - beam_a;  

  // process the list
  //
  if (paths_d != (Link_list*)NULL) {
    for (node = lnd; node != (Link_node*)NULL;
	 node = lnd) {      

      // get next node
      //
      lnd = node->get_next_cc();
      
      // get the nbest node
      //
      nnode = (Nbest_node*)(node->get_item_cc());

      // if this node falls below threshold, prune it
      //
      if (nnode->get_score_cc() < beam_threshold) {

	// prune the nbest node
	//
	delete nnode;
    
	// remove link node from the current list
	//
	paths_d->remove_cc(node);

	// decrement history count
	//
	num_paths_d--;	
      }      
    }
  }

  // prune to limit the maximum number of paths in the list
  //
  while (num_paths_d > max_paths_a) {
    
    // get the last node in the history node list
    //
    lnd = paths_d->get_curr_cc();
    
    // get the item in this node and remove it
    //
    nnode = (Nbest_node*)(lnd->get_item_cc());
    delete nnode;
    
    // remove link node from the current list
    //
    paths_d->remove_cc(lnd);

    // decrement history count
    //
    num_paths_d--;

    // if there are no more histories remaining release list memory
    //
    if (num_paths_d == (int_4)0) {
      delete paths_d;
      paths_d = (Link_list*)NULL;
    }
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}


