// Path: src/main/java/edu/berkeley/nlp/lm/collections/BoundedList.java
// public class BoundedList<E> extends AbstractList<E>
// {
// 	private final E leftBoundary;
// 
// 	private final E rightBoundary;
// 
// 	private final List<E> list;
// 
// 	/**
// 	 * Returns the object at the given index, provided the index is between 0
// 	 * (inclusive) and size() (exclusive). If the index is < 0, then a left
// 	 * boundary object is returned. If the index is >= size(), a right boundary
// 	 * object is returned. The default boundary objects are both null, unless
// 	 * other objects are specified on construction.
// 	 */
// 	@Override
// 	public E get(final int index) {
// 		if (index < 0) return leftBoundary;
// 		if (index >= list.size()) return rightBoundary;
// 		return list.get(index);
// 	}
// 
// 	@Override
// 	public int size() {
// 		return list.size();
// 	}
// 
// 	public BoundedList(final List<E> list, final E leftBoundary, final E rightBoundary) {
// 		this.list = list;
// 		this.leftBoundary = leftBoundary;
// 		this.rightBoundary = rightBoundary;
// 	}
// 
// 	@Override
// 	public List<E> subList(final int fromIndex, final int toIndex) {
// 		final List<E> retVal = new ArrayList<E>(toIndex - fromIndex);
// 		for (int i = fromIndex; i < toIndex; ++i) {
// 			retVal.add(get(i));
// 		}
// 		return retVal;
// 	}
// 
// }


import java.util.List;
import edu.berkeley.nlp.lm.collections.BoundedList;
package edu.berkeley.nlp.lm;



/**
 * Top-level interface for an n-gram language model which accepts n-gram in an
 * array-of-integers encoding. The integers represent words of type
 * <code>W</code> in the vocabulary, and the mapping from the vocabulary to
 * integers is managed by an instance of the {@link WordIndexer} class.
 * 
 * @author adampauls
 */
public interface ArrayEncodedNgramLanguageModel<W> extends NgramLanguageModel<W>
{

	/**
	 * Calculate language model score of an n-gram. <b>Warning:</b> if you
	 * pass in an n-gram of length greater than <code>getLmOrder()</code>,
	 * this call will silently ignore the extra words of context. In other
	 * words, if you pass in a 5-gram (<code>endPos-startPos == 5</code>) to
	 * a 3-gram model, it will only score the words from <code>startPos + 2</code>
	 * to <code>endPos</code>.
	 * 
	 * @param ngram
	 *            array of words in integer representation
	 * @param startPos
	 *            start of the portion of the array to be read
	 * @param endPos
	 *            end of the portion of the array to be read.
	 * @return
	 */
	public float getLogProb(int[] ngram, int startPos, int endPos);

	/**
	 * Equivalent to <code>getLogProb(ngram, 0, ngram.length)</code>
	 * 
	 * @see #getLogProb(int[], int, int)
	 */
	public float getLogProb(int[] ngram);

	public static class DefaultImplementations
	{

		public static <T> float scoreSentence(final List<T> sentence, final ArrayEncodedNgramLanguageModel<T> lm) {
// Path: src/main/java/edu/berkeley/nlp/lm/collections/BoundedList.java
// public class BoundedList<E> extends AbstractList<E>
// {
// 	private final E leftBoundary;
// 
// 	private final E rightBoundary;
// 
// 	private final List<E> list;
// 
// 	/**
// 	 * Returns the object at the given index, provided the index is between 0
// 	 * (inclusive) and size() (exclusive). If the index is < 0, then a left
// 	 * boundary object is returned. If the index is >= size(), a right boundary
// 	 * object is returned. The default boundary objects are both null, unless
// 	 * other objects are specified on construction.
// 	 */
// 	@Override
// 	public E get(final int index) {
// 		if (index < 0) return leftBoundary;
// 		if (index >= list.size()) return rightBoundary;
// 		return list.get(index);
// 	}
// 
// 	@Override
// 	public int size() {
// 		return list.size();
// 	}
// 
// 	public BoundedList(final List<E> list, final E leftBoundary, final E rightBoundary) {
// 		this.list = list;
// 		this.leftBoundary = leftBoundary;
// 		this.rightBoundary = rightBoundary;
// 	}
// 
// 	@Override
// 	public List<E> subList(final int fromIndex, final int toIndex) {
// 		final List<E> retVal = new ArrayList<E>(toIndex - fromIndex);
// 		for (int i = fromIndex; i < toIndex; ++i) {
// 			retVal.add(get(i));
// 		}
// 		return retVal;
// 	}
// 
// }


// Path: src/main/java/edu/berkeley/nlp/lm/ArrayEncodedNgramLanguageModel.java
import java.util.List;
import edu.berkeley.nlp.lm.collections.BoundedList;

package edu.berkeley.nlp.lm;



/**
 * Top-level interface for an n-gram language model which accepts n-gram in an
 * array-of-integers encoding. The integers represent words of type
 * <code>W</code> in the vocabulary, and the mapping from the vocabulary to
 * integers is managed by an instance of the {@link WordIndexer} class.
 * 
 * @author adampauls
 */
public interface ArrayEncodedNgramLanguageModel<W> extends NgramLanguageModel<W>
{

	/**
	 * Calculate language model score of an n-gram. <b>Warning:</b> if you
	 * pass in an n-gram of length greater than <code>getLmOrder()</code>,
	 * this call will silently ignore the extra words of context. In other
	 * words, if you pass in a 5-gram (<code>endPos-startPos == 5</code>) to
	 * a 3-gram model, it will only score the words from <code>startPos + 2</code>
	 * to <code>endPos</code>.
	 * 
	 * @param ngram
	 *            array of words in integer representation
	 * @param startPos
	 *            start of the portion of the array to be read
	 * @param endPos
	 *            end of the portion of the array to be read.
	 * @return
	 */
	public float getLogProb(int[] ngram, int startPos, int endPos);

	/**
	 * Equivalent to <code>getLogProb(ngram, 0, ngram.length)</code>
	 * 
	 * @see #getLogProb(int[], int, int)
	 */
	public float getLogProb(int[] ngram);

	public static class DefaultImplementations
	{

		public static <T> float scoreSentence(final List<T> sentence, final ArrayEncodedNgramLanguageModel<T> lm) {
			final List<T> sentenceWithBounds = new BoundedList<T>(sentence, lm.getWordIndexer().getStartSymbol(), lm.getWordIndexer().getEndSymbol());