gt:                 if (st.countTokens() != 3) {
context: /*
   * Copyright 1999-2002 Carnegie Mellon University.  
   * Portions Copyright 2002 Sun Microsystems, Inc.  
   * Portions Copyright 2002 Mitsubishi Electric Research Laboratories.
   * All Rights Reserved.  Use is subject to license terms.
   * 
   * See the file "license.terms" for information on usage and
   * redistribution of this file, and for a DISCLAIMER OF ALL 
   * WARRANTIES.
   *
   */
  package edu.cmu.sphinx.linguist.language.ngram;
  
  import edu.cmu.sphinx.linguist.WordSequence;
  import edu.cmu.sphinx.linguist.dictionary.Dictionary;
  import edu.cmu.sphinx.linguist.dictionary.Word;
  import edu.cmu.sphinx.util.LogMath;
  import edu.cmu.sphinx.util.props.ConfigurationManagerUtils;
  import edu.cmu.sphinx.util.props.PropertyException;
  import edu.cmu.sphinx.util.props.PropertySheet;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.*;
  
  import static java.lang.Math.max;
  
  
  /**
   * An ASCII ARPA language model loader. This loader makes no attempt to
   * optimize storage, so it can only load very small language models
   * <p>
   * Note that all probabilities in the grammar are stored in LogMath log base
   * format. Language Probabilities in the language model file are stored in log
   * 10 base.
   */
  
  public class SimpleNGramModel implements LanguageModel {
  
      // ----------------------------
      // Configuration data
      // ----------------------------
      private String name;
  
      private URL urlLocation;
      private float unigramWeight;
      private Dictionary dictionary;
      private int desiredMaxDepth;
      private int maxNGram;
  
  
      /*  0: float logProbability;
          1: float logBackoff; */
      private Map<WordSequence, float[]> map;
  
      private Set<String> vocabulary;
      protected int lineNumber;
      protected BufferedReader reader;
      protected String fileName;
      private boolean allocated;
      private LinkedList<WordSequence> tokens;
  
      public SimpleNGramModel(String location, Dictionary dictionary,
              float unigramWeight, int desiredMaxDepth)
              throws MalformedURLException {
          this(ConfigurationManagerUtils.resourceToURL(location), dictionary,
               unigramWeight, desiredMaxDepth);
      }
  
      public SimpleNGramModel(URL urlLocation, Dictionary dictionary,
              float unigramWeight, int desiredMaxDepth)
      {
          this.urlLocation = urlLocation;
          this.unigramWeight = unigramWeight;
          this.desiredMaxDepth = desiredMaxDepth;
          this.dictionary = dictionary;
          this.map = new HashMap<>();
          this.vocabulary = new HashSet<>();
          this.tokens = new LinkedList<>();
      }
  
      public SimpleNGramModel() {
  
      }
  
      /*
       * (non-Javadoc)
       * @see
       * edu.cmu.sphinx.util.props.Configurable#newProperties(edu.cmu.sphinx.
       * util.props.PropertySheet)
       */
      public void newProperties(PropertySheet ps) throws PropertyException {
  
          if (allocated) {
              throw new RuntimeException("Can't change properties after allocation");
          }
  
          urlLocation = ConfigurationManagerUtils.getResource(PROP_LOCATION, ps);
          unigramWeight = ps.getFloat(PROP_UNIGRAM_WEIGHT);
          desiredMaxDepth = ps.getInt(PROP_MAX_DEPTH);
          dictionary = (Dictionary) ps.getComponent(PROP_DICTIONARY);
          map = new HashMap<>();
          vocabulary = new HashSet<>();
          tokens = new LinkedList<>();
      }
  
      /*
       * (non-Javadoc)
       * @see edu.cmu.sphinx.linguist.language.ngram.LanguageModel#allocate()
       */
      public void allocate() throws IOException {
          allocated = true;
          load(urlLocation, unigramWeight, dictionary);
          if (desiredMaxDepth > 0) {
              if (desiredMaxDepth < maxNGram) {
                  maxNGram = desiredMaxDepth;
              }
          }
      }
  
      /*
       * (non-Javadoc)
       * @see edu.cmu.sphinx.linguist.language.ngram.LanguageModel#deallocate()
       */
      public void deallocate() {
          allocated = false;
      }
  
      /*
       * (non-Javadoc)
       * @see edu.cmu.sphinx.util.props.Configurable#getName()
       */
      public String getName() {
          return name;
      }
  
      /**
       * Gets the ngram probability of the word sequence represented by the word
       * list
       *
       * @param wordSequence the word sequence
       * @return the probability of the word sequence. Probability is in logMath
       *         log base
       */
      public float getProbability(WordSequence wordSequence) {
          float logProbability = 0.0f;
          float[] prob = getProb(wordSequence);
          if (prob == null) {
              if (wordSequence.size() > 1) {
                  logProbability = getBackoff(wordSequence.getOldest())
                                   + getProbability(wordSequence.getNewest());
              } else { // if the single word is not in the model at all
                  // then its zero likelihood that we'll use it
                  logProbability = LogMath.LOG_ZERO;
              }
          } else {
              logProbability = prob[0];
          }
          // System.out.println("Search: " + wordSequence + " : "
          // + logProbability + " "
          // + LogMath.logToLinear(logProbability));
          return logProbability;
      }
  
      /**
       * Gets the smear term for the given wordSequence
       *
       * @param wordSequence the word sequence
       * @return the smear term associated with this word sequence
       */
      public float getSmear(WordSequence wordSequence) {
          return 0.0f; // TODO not implemented
      }
  
      /**
       * Returns the backoff probability for the give sequence of words
       *
       * @param wordSequence the sequence of words
       * @return the backoff probability in LogMath log base
       */
      public float getBackoff(WordSequence wordSequence) {
          float logBackoff = 0.0f; // log of 1.0
          float[] prob = getProb(wordSequence);
          if (prob != null) {
              logBackoff = prob[1];
          }
          return logBackoff;
      }
  
      /**
       * Returns the maximum depth of the language model
       *
       * @return the maximum depth of the language model
       */
      public int getMaxDepth() {
          return maxNGram;
      }
  
      /**
       * Returns the set of words in the language model. The set is unmodifiable.
       *
       * @return the unmodifiable set of words
       */
      public Set<String> getVocabulary() {
          return Collections.unmodifiableSet(vocabulary);
      }
  
      @Override
      public void onUtteranceEnd() {
          //TODO not implemented
      }
  
      /**
       * Gets the probability entry for the given word sequence or null if there
       * is no entry
       *
       * @param wordSequence a word sequence
       * @return the probability entry for the wordlist or null
       */
      private float[] getProb(WordSequence wordSequence) {
          return map.get(wordSequence);
      }
  
      /**
       * Converts a wordList to a string
       *
       * @param wordList the wordList
       * @return the string
       */
      @SuppressWarnings("unused")
      private static String listToString(List<Word> wordList) {
          StringBuilder sb = new StringBuilder();
          for (Word word : wordList)
              sb.append(word).append(' ');
          return sb.toString();
      }
  
      /** Dumps the language model */
      public void dump() {
          for (Map.Entry<WordSequence, float[]> entry : map.entrySet())
              System.out.println(entry.getKey() + " " + entry.getValue());
      }
  
      /**
       * Retrieves a string representation of the wordlist, suitable for map
       * access
       *
       * @param wordList the list of words
       * @return a string representation of the word list
       */
      @SuppressWarnings("unused")
      private static String getRepresentation(List<String> wordList) {
          if (wordList.isEmpty())
              return "";
          StringBuilder sb = new StringBuilder();
          for (String word : wordList)
              sb.append(word).append('+');
          sb.setLength(sb.length() - 1);
          return sb.toString();
      }
  
      /**
       * Loads the language model from the given location.
       *
       * @param location the URL location of the model
       * @param unigramWeight the unigram weight
       * @throws IOException if an error occurs while loading
       */
      private void load(URL location, float unigramWeight,
                        Dictionary dictionary) throws IOException {
          String line;
          float logUnigramWeight = LogMath.linearToLog(unigramWeight);
          float inverseLogUnigramWeight = LogMath
                  .linearToLog(1.0 - unigramWeight);
  
          open(location);
          // look for beginning of data
          readUntil("\\data\\");
          // look for ngram statements
  
  
          List<Integer> ngramList = new ArrayList<>(64*1024);
  
          while ((line = readLine()) != null) {
              if (line.startsWith("ngram")) {
                  StringTokenizer st = new StringTokenizer(line, " \t\n\r\f=");
  