package edu.stanford.nlp.sempre; import java.util.*; import fig.basic.*; /** * Given the maximum formula size in a floating grammar, compute the maximum size * that each floating grammar category can have. * * For example, if the grammar looks like this: * $ROOT -> $A | $A $B * $A -> $C $A * $B -> $C * $C -> $D $B | nothing * ... * and the maximum formula size (for $ROOT) is 10, then the maximum formula sizes for * $A, $B, $C and $D are 9, 9, 8, and 7, respectively. * * The bound is = maxFormulaSize - (shortest distance from $ROOT to cat) * * @author ppasupat */ public class CatSizeBound { public static class Options { @Option(gloss = "verbosity") public int verbose = 0; } public static Options opts = new Options(); private final int maxFormulaSize; private final Map<String, Integer> bound = new HashMap<>(); public CatSizeBound(int maxFormulaSize, Grammar grammar) { this(maxFormulaSize, grammar.getRules()); } public CatSizeBound(int maxFormulaSize, List<Rule> rules) { this.maxFormulaSize = maxFormulaSize; if (!FloatingParser.opts.useSizeInsteadOfDepth) { LogInfo.warnings("Currently CatSizeBound is usable only when useSizeInsteadOfDepth = true."); return; } // Construct graph Map<String, Set<String>> graph = new HashMap<>(); for (Rule rule : rules) { if (!Rule.isCat(rule.lhs)) throw new RuntimeException("Non-cat found in LHS of rule " + rule); for (String rhsCat : rule.rhs) { if (Rule.isCat(rhsCat)) MapUtils.addToSet(graph, rule.lhs, rhsCat); } } // Breadth first search bound.put(Rule.rootCat, maxFormulaSize); Queue<String> queue = new ArrayDeque<>(); queue.add(Rule.rootCat); while (!queue.isEmpty()) { String cat = queue.remove(); if (!graph.containsKey(cat)) continue; for (String rhsCat : graph.get(cat)) { if (bound.containsKey(rhsCat)) continue; bound.put(rhsCat, bound.get(cat) - 1); queue.add(rhsCat); } } if (opts.verbose >= 1) { LogInfo.begin_track("CatSizeBound: distances"); for (Map.Entry<String, Integer> entry : bound.entrySet()) LogInfo.logs("%25s : %2d", entry.getKey(), entry.getValue()); LogInfo.end_track(); } } public int getBound(String cat) { return bound.getOrDefault(cat, maxFormulaSize); } }