package edu.stanford.nlp.sempre;
import java.util.*;
import com.google.common.collect.Sets;
import fig.basic.*;
/**
* Extracts indicator features that count how many times semantic functions and
* LHSs have been used in the derivation For now we count how many times MergeFn
* and JoinFn, also how many time unary, binary and entity lexical entries have
* been used. The feature is a pair with the operation and the count
*
* @author jonathanberant
*/
public class DerivOpCountFeatureComputer implements FeatureComputer {
public static class Options {
@Option(gloss = "Count only basic categories and SemanticFns")
public boolean countBasicOnly = true;
}
public static Options opts = new Options();
public static final String entityCat = "$Entity";
public static final String unaryCat = "$Unary";
public static final String binaryCat = "$Binary";
public static final String joinFn = "JoinFn";
public static final String mergeFn = "MergeFn";
public static final String bridgeFn = "BridgeFn";
public static Set<String> featureNames = Sets.newHashSet(entityCat, unaryCat, binaryCat, joinFn, mergeFn, bridgeFn);
@Override
public void extractLocal(Example ex, Derivation deriv) {
if (!FeatureExtractor.containsDomain("opCount")) return;
if (!deriv.isRoot(ex.numTokens())) return;
// extract the operation count
Map<String, Integer> opCounter = new HashMap<>();
extractOperationsRecurse(deriv, opCounter);
addFeatures(deriv, opCounter);
}
private void extractOperationsRecurse(Derivation deriv, Map<String, Integer> opCounter) {
// Basic case: no rule
if (deriv.children.isEmpty()) return;
// increment counts for current rule
MapUtils.incr(opCounter, deriv.rule.lhs);
MapUtils.incr(opCounter, deriv.rule.sem.getClass().getSimpleName());
// recursive call
for (Derivation child : deriv.children)
extractOperationsRecurse(child, opCounter);
}
private void addFeatures(Derivation deriv, Map<String, Integer> opCounter) {
for (String feature : (opts.countBasicOnly ? featureNames : opCounter.keySet()))
deriv.addFeature("opCount", "count(" + feature + ")=" + MapUtils.get(opCounter, feature, 0));
}
}