// Path: src/edu/stanford/nlp/semparse/open/ling/WordVectorTable.java
// public class WordVectorTable {
//   public static class Options {
//     @Option public String wordVectorFilename = null;
//     
//     @Option(gloss = "vector to use for UNKNOWN words (-1 = don't use any vector)")
//     public int wordVectorUNKindex = 0;
//   }
//   public static Options opts = new Options();
//   
//   public static Map<String, Integer> wordToIndex;
//   public static double[][] wordVectors;
//   public static int numWords, numDimensions;
//   
//   public static void initModels() {
//     if (wordVectors != null || opts.wordVectorFilename == null || opts.wordVectorFilename.isEmpty()) return;
//     Path dataPath = Paths.get(opts.wordVectorFilename);
//     LogInfo.logs("Reading word vectors from %s", dataPath);
//     try (BufferedReader in = Files.newBufferedReader(dataPath, Charset.forName("UTF-8"))) {
//       String[] headerTokens = in.readLine().split(" ");
//       numWords = Integer.parseInt(headerTokens[0]);
//       numDimensions = Integer.parseInt(headerTokens[1]);
//       wordToIndex = new HashMap<>();
//       wordVectors = new double[numWords][numDimensions];
//       for (int i = 0; i < numWords; i++) {
//         String[] tokens = in.readLine().split(" ");
//         wordToIndex.put(tokens[0], i);
//         for (int j = 0; j < numDimensions; j++) {
//           wordVectors[i][j] = Double.parseDouble(tokens[j+1]);
//         }
//       }
//       LogInfo.logs("Neural network vectors: %s words; %s dimensions per word", numWords, numDimensions);
//     } catch (IOException e) {
//       LogInfo.fails("Cannot load neural network vectors from %s", dataPath);
//     }
//   }
//   
//   public static double[] getVector(String word) {
//     initModels();
//     Integer index = wordToIndex.get(word);
//     if (index == null) {
//       index = opts.wordVectorUNKindex;
//       if (index < 0) return null;
//     }
//     return wordVectors[index];
//   }
// 
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/model/candidate/Candidate.java
// public class Candidate {
//   public final Example ex;
//   public final CandidateGroup group;
//   public final TreePattern pattern;
//   public final List<String> predictedEntities;
//   public FeatureVector features;
//   
//   public Candidate(CandidateGroup group, TreePattern pattern) {
//     this.pattern = pattern;
//     this.group = group;
//     group.candidates.add(this);
//     // Perform shallow copy
//     this.ex = group.ex;
//     this.predictedEntities = group.predictedEntities;
//   }
//   
//   public int numEntities() {
//     return group.numEntities();
//   }
//   
//   public double getReward() {
//     return group.ex.expectedAnswer.reward(this);
//   }
//   
//   public Map<String, Double> getCombinedFeatures() {
//     Map<String, Double> map = new HashMap<>();
//     features.increment(1, map);
//     group.features.increment(1, map);
//     return map;
//   }
//   
//   // ============================================================
//   // Debug Print
//   // ============================================================
//   
//   public String sampleEntities() {
//     return group.sampleEntities();
//   }
//   
//   public String allEntities() {
//     return group.allEntities();
//   }
// }


import edu.stanford.nlp.semparse.open.ling.WordVectorTable;
import edu.stanford.nlp.semparse.open.model.candidate.Candidate;
import fig.basic.Option;
package edu.stanford.nlp.semparse.open.model;


/**
 * Parameters for advanced word vector features.
 */
public abstract class AdvancedWordVectorParams {
  public static class Options {
    @Option(gloss = "Whether to use full rank")
    public boolean vecFullRank = true;
    
    @Option(gloss = "Use pooling (vecOpenPOSOnly and vecFreqWeighted will be ignored)")
    public boolean vecPooling = false;
    
    @Option(gloss = "Only use Open POS words")
    public boolean vecOpenPOSOnly = false;
    
    @Option(gloss = "Use frequency-weighted vectors")
    public boolean vecFreqWeighted = false;
  }
  public static Options opts = new Options();
  
  public static AdvancedWordVectorParams create() {
    if (opts.vecFullRank)
      return new AdvancedWordVectorParamsFullRank();
    else
      return new AdvancedWordVectorParamsLowRank();
  }
  
  protected static int getDim() {
    if (opts.vecPooling) {
// Path: src/edu/stanford/nlp/semparse/open/ling/WordVectorTable.java
// public class WordVectorTable {
//   public static class Options {
//     @Option public String wordVectorFilename = null;
//     
//     @Option(gloss = "vector to use for UNKNOWN words (-1 = don't use any vector)")
//     public int wordVectorUNKindex = 0;
//   }
//   public static Options opts = new Options();
//   
//   public static Map<String, Integer> wordToIndex;
//   public static double[][] wordVectors;
//   public static int numWords, numDimensions;
//   
//   public static void initModels() {
//     if (wordVectors != null || opts.wordVectorFilename == null || opts.wordVectorFilename.isEmpty()) return;
//     Path dataPath = Paths.get(opts.wordVectorFilename);
//     LogInfo.logs("Reading word vectors from %s", dataPath);
//     try (BufferedReader in = Files.newBufferedReader(dataPath, Charset.forName("UTF-8"))) {
//       String[] headerTokens = in.readLine().split(" ");
//       numWords = Integer.parseInt(headerTokens[0]);
//       numDimensions = Integer.parseInt(headerTokens[1]);
//       wordToIndex = new HashMap<>();
//       wordVectors = new double[numWords][numDimensions];
//       for (int i = 0; i < numWords; i++) {
//         String[] tokens = in.readLine().split(" ");
//         wordToIndex.put(tokens[0], i);
//         for (int j = 0; j < numDimensions; j++) {
//           wordVectors[i][j] = Double.parseDouble(tokens[j+1]);
//         }
//       }
//       LogInfo.logs("Neural network vectors: %s words; %s dimensions per word", numWords, numDimensions);
//     } catch (IOException e) {
//       LogInfo.fails("Cannot load neural network vectors from %s", dataPath);
//     }
//   }
//   
//   public static double[] getVector(String word) {
//     initModels();
//     Integer index = wordToIndex.get(word);
//     if (index == null) {
//       index = opts.wordVectorUNKindex;
//       if (index < 0) return null;
//     }
//     return wordVectors[index];
//   }
// 
// }
// 
// Path: src/edu/stanford/nlp/semparse/open/model/candidate/Candidate.java
// public class Candidate {
//   public final Example ex;
//   public final CandidateGroup group;
//   public final TreePattern pattern;
//   public final List<String> predictedEntities;
//   public FeatureVector features;
//   
//   public Candidate(CandidateGroup group, TreePattern pattern) {
//     this.pattern = pattern;
//     this.group = group;
//     group.candidates.add(this);
//     // Perform shallow copy
//     this.ex = group.ex;
//     this.predictedEntities = group.predictedEntities;
//   }
//   
//   public int numEntities() {
//     return group.numEntities();
//   }
//   
//   public double getReward() {
//     return group.ex.expectedAnswer.reward(this);
//   }
//   
//   public Map<String, Double> getCombinedFeatures() {
//     Map<String, Double> map = new HashMap<>();
//     features.increment(1, map);
//     group.features.increment(1, map);
//     return map;
//   }
//   
//   // ============================================================
//   // Debug Print
//   // ============================================================
//   
//   public String sampleEntities() {
//     return group.sampleEntities();
//   }
//   
//   public String allEntities() {
//     return group.allEntities();
//   }
// }


// Path: src/edu/stanford/nlp/semparse/open/model/AdvancedWordVectorParams.java
import edu.stanford.nlp.semparse.open.ling.WordVectorTable;
import edu.stanford.nlp.semparse.open.model.candidate.Candidate;
import fig.basic.Option;

package edu.stanford.nlp.semparse.open.model;


/**
 * Parameters for advanced word vector features.
 */
public abstract class AdvancedWordVectorParams {
  public static class Options {
    @Option(gloss = "Whether to use full rank")
    public boolean vecFullRank = true;
    
    @Option(gloss = "Use pooling (vecOpenPOSOnly and vecFreqWeighted will be ignored)")
    public boolean vecPooling = false;
    
    @Option(gloss = "Only use Open POS words")
    public boolean vecOpenPOSOnly = false;
    
    @Option(gloss = "Use frequency-weighted vectors")
    public boolean vecFreqWeighted = false;
  }
  public static Options opts = new Options();
  
  public static AdvancedWordVectorParams create() {
    if (opts.vecFullRank)
      return new AdvancedWordVectorParamsFullRank();
    else
      return new AdvancedWordVectorParamsLowRank();
  }
  
  protected static int getDim() {
    if (opts.vecPooling) {
      return 2 * WordVectorTable.numDimensions;