package edu.stanford.nlp.sempre;
import fig.basic.*;
import java.util.*;
/**
* Uses the SimpleLexicon.
*
* Example:
* (rule $ROOT ($PHRASE) (SimpleLexiconFn (type fb:type.any)))
*
* @author Percy Liang
*/
public class SimpleLexiconFn extends SemanticFn {
public static class Options {
@Option(gloss = "Number of entities to return from entity lexicon")
public int maxEntityEntries = 100;
@Option(gloss = "Verbosity level") public int verbose = 0;
}
public static Options opts = new Options();
private static SimpleLexicon lexicon;
// Only return entries whose type matches this
private SemType restrictType = SemType.topType;
public SimpleLexiconFn() {
lexicon = SimpleLexicon.getSingleton();
}
public void init(LispTree tree) {
super.init(tree);
for (int i = 1; i < tree.children.size(); i++) {
// (type fb:people.person): allow us to restrict the type
LispTree arg = tree.child(i);
if ("type".equals(arg.child(0).value)) {
restrictType = SemType.fromLispTree(arg.child(1));
}
}
}
public DerivationStream call(Example ex, Callable c) {
String phrase = c.childStringValue(0);
List<SimpleLexicon.Entry> entries = lexicon.lookup(phrase);
// Filter by type
List<SimpleLexicon.Entry> newEntries = new ArrayList<SimpleLexicon.Entry>();
for (SimpleLexicon.Entry e : entries) {
if (opts.verbose >= 3)
LogInfo.logs("SimpleLexiconFn: %s => %s [type = %s meet-> %s]", phrase, e.formula, e.type, restrictType.meet(e.type));
if (!restrictType.meet(e.type).isValid()) continue;
newEntries.add(e);
}
entries = newEntries;
return new MyDerivationStream(ex, c, entries, phrase);
}
public class MyDerivationStream extends MultipleDerivationStream {
private Example ex;
private Callable callable;
private List<SimpleLexicon.Entry> entries;
private String phrase;
private int currIndex = 0;
public MyDerivationStream(Example ex, Callable c, List<SimpleLexicon.Entry> entries, String phrase) {
this.ex = ex;
this.callable = c;
this.entries = entries;
this.phrase = phrase;
}
@Override public int estimatedSize() { return entries.size(); }
@Override
public Derivation createDerivation() {
if (currIndex == entries.size()) return null;
SimpleLexicon.Entry entry = entries.get(currIndex++);
FeatureVector features = new FeatureVector();
Derivation deriv = new Derivation.Builder()
.withCallable(callable)
.formula(entry.formula)
.type(entry.type)
.localFeatureVector(features)
.createDerivation();
if (FeatureExtractor.containsDomain("basicStats")) {
if (entry.features != null) {
for (StringDoubleVec.Entry e : entry.features)
features.add("basicStats", e.getFirst(), e.getSecond());
}
}
// Doesn't generalize, but add it for now, otherwise not separable
if (FeatureExtractor.containsDomain("lexAlign"))
deriv.addFeature("lexAlign", phrase + " --- " + entry.formula);
if (SemanticFn.opts.trackLocalChoices)
deriv.addLocalChoice("SimpleLexiconFn " + deriv.startEndString(ex.getTokens()) + " " + entry);
return deriv;
}
}
}