/* This file is part of the Joshua Machine Translation System. * * Joshua is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package joshua.decoder.ff.lm; import joshua.decoder.JoshuaConfiguration; import joshua.decoder.Support; import joshua.corpus.vocab.SymbolTable; import java.util.List; /** * This class implements NGramLanguageModel by creating wrappers * around the necessary functions to capture common errors. Most * methods are declared final, in an attempt to limit what subclasses * may be defined. * * @author Zhifei Li, <zhifei.work@gmail.com> * @version $LastChangedDate: 2009-12-30 10:10:38 -0600 (Wed, 30 Dec 2009) $ */ public abstract class AbstractLM extends DefaultNGramLanguageModel { public AbstractLM(SymbolTable symbolTable, int order) { super(symbolTable, order); } public final double sentenceLogProbability( List<Integer> sentence, int order, int startIndex ) { return super.sentenceLogProbability(sentence, order, startIndex); } public final double ngramLogProbability(int[] ngram) { return super.ngramLogProbability(ngram); } public final double ngramLogProbability(int[] ngram, int order) { if (ngram.length > order) { throw new RuntimeException("ngram length is greather than the max order"); } // if (ngram.length==1 && "we".equals(symbolTable.getWord(ngram[0]))) { // System.err.println("Something weird is about to happen"); // } int historySize = ngram.length - 1; if (historySize >= order || historySize < 0) { // BUG: use logger or exception. Don't zero default throw new RuntimeException("Error: history size is " + historySize); // return 0; } double probability = ngramLogProbability_helper(ngram, order); if (probability < -JoshuaConfiguration.lm_ceiling_cost) { probability = -JoshuaConfiguration.lm_ceiling_cost; } return probability; } protected abstract double ngramLogProbability_helper(int[] ngram, int order); /** * @deprecated this function is much slower than the int[] * version */ @Deprecated public final double logProbOfBackoffState(List<Integer> ngram, int order, int qtyAdditionalBackoffWeight) { return logProbabilityOfBackoffState( Support.subIntArray(ngram, 0, ngram.size()), order, qtyAdditionalBackoffWeight); } public final double logProbabilityOfBackoffState(int[] ngram, int order, int qtyAdditionalBackoffWeight) { if (ngram.length > order) { throw new RuntimeException("ngram length is greather than the max order"); } if (ngram[ngram.length-1] != LanguageModelFF.BACKOFF_LEFT_LM_STATE_SYM_ID) { throw new RuntimeException("last wrd is not <bow>"); } if (qtyAdditionalBackoffWeight > 0) { return logProbabilityOfBackoffState_helper( ngram, order, qtyAdditionalBackoffWeight); } else { return 0.0; } } protected abstract double logProbabilityOfBackoffState_helper( int[] ngram, int order, int qtyAdditionalBackoffWeight); // BUG: We should have different classes based on the configuration in use public int[] leftEquivalentState(int[] originalState, int order, double[] cost ) { if (JoshuaConfiguration.use_left_equivalent_state) throw new UnsupportedOperationException("getLeftEquivalentState is not overwritten by a concrete class"); return originalState; } // BUG: We should have different classes based on the configuration in use public int[] rightEquivalentState(int[] originalState, int order) { if ( !JoshuaConfiguration.use_right_equivalent_state || originalState.length != this.ngramOrder-1) { return originalState; } else { throw new UnsupportedOperationException("getRightEquivalentState is not overwritten by a concrete class"); } } }