// Path: src/edu/stanford/nlp/semparse/open/core/eval/CandidateStatistics.java
// public class CandidateStatistics {
//   public final Candidate candidate;
//   public final int rank, uniqueRank;    // rank and uniqueRank are 1-indexed
//   public final double score;
//   
//   public CandidateStatistics(Candidate candidate, int rank, int uniqueRank, double score) {
//     this.candidate = candidate;
//     this.rank = rank;
//     this.uniqueRank = uniqueRank;
//     this.score = score;
//   }
//   
//   /**
//    * Convert Pair<Candidate, Double> to CandidateStatistics
//    */
//   public static List<CandidateStatistics> getRankedCandidateStats(List<Pair<Candidate, Double>> rankedCandidates) {
//     List<CandidateStatistics> answer = new ArrayList<>();
//     Set<List<String>> foundPredictedEntities = new HashSet<>();
//     for (int rank = 0; rank < rankedCandidates.size(); rank++) {
//       Pair<Candidate, Double> entry = rankedCandidates.get(rank);
//       Candidate candidate = entry.getFirst();
//       foundPredictedEntities.add(candidate.predictedEntities);
//       answer.add(new CandidateStatistics(candidate, rank + 1, foundPredictedEntities.size(), entry.getSecond()));
//     }
//     return answer;
//   }
// }


import java.util.List;
import edu.stanford.nlp.semparse.open.core.eval.CandidateStatistics;
import fig.basic.Option;
    this.criteria = criteria;
  }
  
  @Override
  public IRScore getIRScore(List<String> predictedEntities) {
    return criteria.getIRScore(predictedEntities);
  }
  
  @Override
  public double reward(List<String> predictedEntities) {
    if (!opts.generous) {
      return countCorrectEntities(predictedEntities) == criteria.numCriteria() ? 1 : 0;
    } else {
      // Generous reward
      double f1 = criteria.getIRScore(predictedEntities).f1;
      return f1 > ExpectedAnswerInjectiveMatch.opts.irThreshold ? f1 : 0;
    }
  }
  
  @Override
  public int computeCountCorrectEntities(List<String> predictedEntities) {
    return criteria.countMatchedCriteria(predictedEntities);
  }
  
  @Override
  public boolean isLikelyCorrect(List<String> predictedEntities) {
    return countCorrectEntities(predictedEntities) == criteria.numCriteria();
  }
  
  @Override
// Path: src/edu/stanford/nlp/semparse/open/core/eval/CandidateStatistics.java
// public class CandidateStatistics {
//   public final Candidate candidate;
//   public final int rank, uniqueRank;    // rank and uniqueRank are 1-indexed
//   public final double score;
//   
//   public CandidateStatistics(Candidate candidate, int rank, int uniqueRank, double score) {
//     this.candidate = candidate;
//     this.rank = rank;
//     this.uniqueRank = uniqueRank;
//     this.score = score;
//   }
//   
//   /**
//    * Convert Pair<Candidate, Double> to CandidateStatistics
//    */
//   public static List<CandidateStatistics> getRankedCandidateStats(List<Pair<Candidate, Double>> rankedCandidates) {
//     List<CandidateStatistics> answer = new ArrayList<>();
//     Set<List<String>> foundPredictedEntities = new HashSet<>();
//     for (int rank = 0; rank < rankedCandidates.size(); rank++) {
//       Pair<Candidate, Double> entry = rankedCandidates.get(rank);
//       Candidate candidate = entry.getFirst();
//       foundPredictedEntities.add(candidate.predictedEntities);
//       answer.add(new CandidateStatistics(candidate, rank + 1, foundPredictedEntities.size(), entry.getSecond()));
//     }
//     return answer;
//   }
// }


// Path: src/edu/stanford/nlp/semparse/open/dataset/ExpectedAnswerCriteriaMatch.java
import java.util.List;
import edu.stanford.nlp.semparse.open.core.eval.CandidateStatistics;
import fig.basic.Option;

    this.criteria = criteria;
  }
  
  @Override
  public IRScore getIRScore(List<String> predictedEntities) {
    return criteria.getIRScore(predictedEntities);
  }
  
  @Override
  public double reward(List<String> predictedEntities) {
    if (!opts.generous) {
      return countCorrectEntities(predictedEntities) == criteria.numCriteria() ? 1 : 0;
    } else {
      // Generous reward
      double f1 = criteria.getIRScore(predictedEntities).f1;
      return f1 > ExpectedAnswerInjectiveMatch.opts.irThreshold ? f1 : 0;
    }
  }
  
  @Override
  public int computeCountCorrectEntities(List<String> predictedEntities) {
    return criteria.countMatchedCriteria(predictedEntities);
  }
  
  @Override
  public boolean isLikelyCorrect(List<String> predictedEntities) {
    return countCorrectEntities(predictedEntities) == criteria.numCriteria();
  }
  
  @Override
  public CandidateStatistics findBestCandidate(List<CandidateStatistics> rankedCandidateStats) {