// file: $isip/class/search/NGramCache/ngca_05.cc
// version: $Id: ngca_05.cc 9101 2003-04-19 20:52:59Z parihar $
//

// isip include files
//
#include "NGramCache.h"

// method: assign
//
// arguments:
//  const NGramCache& arg: (input) node to copy
//
// return: logical error status
//
// assign NGramCache from the copy
//
boolean NGramCache::assign(const NGramCache& arg_a) {

  // declare local variables
  //
  boolean status = false;
  
  // copy the cache over
  //
  status = cache_d.assign(arg_a.cache_d);
  
  // exit gracefully
  //
  return status;
}

// method: clear
//
// arguments:
//  Integral::CMODE cmode: (input) clear mode
//
// return: logical error status
//
// clear the contents of the NGramCache
//
boolean NGramCache::clear(Integral::CMODE cmode_a) {

  // declare local variables
  //
  boolean status = false;
  
  // clear the cache
  //
  status = cache_d.clear(cmode_a);
  
  // exit gracefully
  //
  return status;
}

// method: eq
//
// arguments:
//  const NGramCache& arg: (input) NGramCache to compare
//
// return: true if the NGramCaches are equivalent, else false
//
// compare two NGramCaches. they are equivalent if they have equivalent history
// objects
//
boolean NGramCache::eq(const NGramCache& arg_a) const {

  // compare the caches
  //
  return cache_d.eq(arg_a.cache_d);
}

// method: getScore
//
// arguments:
//   NGramModel& model: (input) n-gram model
//   Context& context: (input) n-symbols
//
// return: n-gram score
//
// computes the n-gram score for the input n-symbols
//
float NGramCache::getScore(NGramModel& model_a, Context& context_a) {

  // declare local variables
  //
  Float score = 0.0;

  // context was NOT previously cached
  //
  Float* val;
  if ((val = cache_d.get(context_a)) == (Float*)NULL) {

    // get the n-gram order
    //
    long lm_order = model_a.getOrder();

    // error checking
    //
    if (lm_order < 1) {
      return score;
    }
    
    // convert the context to its symbol indices (facilitates faster lookup)
    //
    Context* tmp_context = (Context*)NULL;
    context_a.convert(tmp_context);

    VectorLong symbol_indices(lm_order);    
    for (long i = 0; i < lm_order; i++) {
      symbol_indices(i) = (*tmp_context)(-lm_order + i);
    }

    if (tmp_context != (Context*)NULL) {
      delete tmp_context;
    }

    // lookup the n-gram score
    //
    score = model_a.getScore(symbol_indices);

    // cache the n-gram score
    //
    cache_d.insert(context_a, &score);
  }

  // context WAS previously cached
  //
  else {
    score = *val;
  }
  
  // return the n-gram score
  //
  return score;
}
