diff --git a/run b/run index e47e3d2..ef85fcd 100755 --- a/run +++ b/run @@ -1020,9 +1020,12 @@ o('FeatureExtractor.featureDomains', 'rule', 'stats'), lambda { |e| system 'mkdir -p ./int-output/examples/'}, lambda { |e| system 'mkdir -p ./int-output/logs/'}, lambda { |e| system 'mkdir -p ./int-output/grammar/'}, +lambda { |e| system 'mkdir -p ./int-output/json/'}, + o('Master.newExamplesPath', './int-output/examples/'), o('Master.logPath', './int-output/logs/'), o('Master.newGrammarPath', './int-output/grammar/'), +o('ILUtils.JSONLogPath', './int-output/json/'), o('Master.onlineLearnExamples', true), o('Master.independentSessions', false), diff --git a/src/edu/stanford/nlp/sempre/InteractiveUtils.java b/src/edu/stanford/nlp/sempre/ILUtils.java similarity index 79% rename from src/edu/stanford/nlp/sempre/InteractiveUtils.java rename to src/edu/stanford/nlp/sempre/ILUtils.java index cb20789..c1f4084 100644 --- a/src/edu/stanford/nlp/sempre/InteractiveUtils.java +++ b/src/edu/stanford/nlp/sempre/ILUtils.java @@ -2,30 +2,42 @@ package edu.stanford.nlp.sempre; import java.io.PrintWriter; import java.nio.file.Paths; +import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import org.testng.collections.Lists; import com.google.common.collect.ImmutableList; +import edu.stanford.nlp.sempre.Master.Options; import edu.stanford.nlp.sempre.interactive.BlockFn; import edu.stanford.nlp.sempre.interactive.DefinitionAligner; import edu.stanford.nlp.sempre.interactive.DefinitionAligner.Match; import edu.stanford.nlp.sempre.interactive.GrammarInducer; import edu.stanford.nlp.sempre.interactive.actions.ActionFormula; +import edu.stanford.nlp.sempre.interactive.actions.FlatWorld; import fig.basic.IOUtils; import fig.basic.LispTree; import fig.basic.LogInfo; +import fig.basic.Option; import fig.basic.Ref; /** * Utilities for grammar induction * @author sidaw */ -public final class InteractiveUtils { - private InteractiveUtils() { } +public final class ILUtils { + public static class Options { + @Option(gloss = "Execute these commands before starting") + public String JSONLogPath = "./int-output/json/"; + } + + public static Options opts = new Options(); + private ILUtils() { } public static Derivation stripDerivation(Derivation deriv) { while (deriv.rule.sem instanceof IdentityFn) { @@ -123,8 +135,8 @@ public final class InteractiveUtils { Parser parser, Params params, String sessionId, Ref refEx) { ActionFormula.Mode blockmode = command.equals(":def")? ActionFormula.Mode.block : ActionFormula.Mode.blockr; - Derivation bodyDeriv = InteractiveUtils.combine( - InteractiveUtils.derivsfromJson(jsonDef, parser, params), blockmode); + Derivation bodyDeriv = ILUtils.combine( + ILUtils.derivsfromJson(jsonDef, parser, params), blockmode); Example.Builder b = new Example.Builder(); b.setId("session:" + sessionId); @@ -138,14 +150,14 @@ public final class InteractiveUtils { LogInfo.begin_track("Definition"); LogInfo.logs("mode: %s", blockmode); LogInfo.logs("head: %s", exHead.getTokens()); - LogInfo.logs("body: %s", InteractiveUtils.utterancefromJson(jsonDef)); + LogInfo.logs("body: %s", ILUtils.utterancefromJson(jsonDef)); LogInfo.logs("defderiv: %s", bodyDeriv.toLispTree()); BeamFloatingParserState state = (BeamFloatingParserState)parser.parse(params, exHead, true); LogInfo.logs("anchored: %s", state.chartList); LogInfo.logs("exHead: %s", exHead.getTokens()); - return InteractiveUtils.induceRules(exHead.getTokens(), - InteractiveUtils.utterancefromJson(jsonDef), bodyDeriv, state.chartList); + return ILUtils.induceRules(exHead.getTokens(), + ILUtils.utterancefromJson(jsonDef), bodyDeriv, state.chartList); } public static void logRawDef(String utt, String jsonDef, String sessionId) { @@ -163,6 +175,31 @@ public final class InteractiveUtils { out.close(); } + public static void logJSONExample(Example ex, String sessionId, String command) { + + Map jsonMap = new HashMap<>(); + jsonMap.put("time", LocalDateTime.now().toString()); + try { + jsonMap.put("cmd", command); + jsonMap.put("sessionId", sessionId); + jsonMap.put("utterance", ex.utterance); + jsonMap.put("targetFormula", ex.targetFormula); + jsonMap.put("context", FlatWorld.fromContext("BlocksWorld", ex.context).toJSON()); + if (ex.targetValue instanceof StringValue) + jsonMap.put("targetValue", ((StringValue)ex.targetValue).toString()); + else + jsonMap.put("targetValue", ex.targetValue); + + } catch (Exception e) { + jsonMap.put("exception", e.toString()); + } finally { + PrintWriter out = IOUtils.openOutAppendHard(Paths.get(ILUtils.opts.JSONLogPath, sessionId + ".json").toString()); + String jsonStr = Json.prettyWriteValueAsStringHard(jsonMap) + "\n"; + out.write(jsonStr); + out.close(); + } + } + public static synchronized void addRuleInteractive(Rule rule, Parser parser) { LogInfo.logs("addRuleInteractive: %s", rule); parser.grammar.addRule(rule); diff --git a/src/edu/stanford/nlp/sempre/Master.java b/src/edu/stanford/nlp/sempre/Master.java index fca836d..06774f5 100644 --- a/src/edu/stanford/nlp/sempre/Master.java +++ b/src/edu/stanford/nlp/sempre/Master.java @@ -457,13 +457,18 @@ public class Master { ex.preprocess(); // Parse! - ParserState state; - state = builder.parser.parse(builder.params, ex, false); - Learner.addToAutocomplete(ex, builder.params); + builder.parser.parse(builder.params, ex, false); + Learner.addToAutocomplete(ex, builder.params); + response.ex = ex; - if (ex.predDerivations.size() > 0) response.candidateIndex = 0; + if (response.ex.predDerivations.size() > 0) { + response.candidateIndex = 0; + response.ex.setTargetFormula(response.ex.predDerivations.get(0).formula); + response.ex.setTargetValue(response.ex.predDerivations.get(0).value); + } + ILUtils.logJSONExample(response.ex, session.id, line); } else if (command.equals(":accept")) { String utt = tree.children.get(1).value; @@ -495,35 +500,47 @@ public class Master { learner.onlineLearnExample(ex); LogInfo.end_track(); } + + if (response.ex.predDerivations.size() > 0) { + response.candidateIndex = 0; + response.ex.setTargetFormula(response.ex.predDerivations.get(0).formula); + response.ex.setTargetValue(response.ex.predDerivations.get(0).value); + } + ILUtils.logJSONExample(response.ex, session.id, line); } else if (command.equals(":def") || command.equals(":def_ret")) { if (tree.children.size() == 3) { String head = tree.children.get(1).value; String jsonDef = tree.children.get(2).value; - InteractiveUtils.logRawDef(head, jsonDef, session.id); + ILUtils.logRawDef(head, jsonDef, session.id); Ref refExHead = new Ref<>(); - List inducedRules = InteractiveUtils.induceRulesHelper(command, head, jsonDef, + List inducedRules = ILUtils.induceRulesHelper(command, head, jsonDef, builder.parser, builder.params, session.id, refExHead); - - + if (inducedRules.size() > 0) { for (Rule rule : inducedRules) { - InteractiveUtils.addRuleInteractive(rule, builder.parser); + ILUtils.addRuleInteractive(rule, builder.parser); } - + // TODO : should not have to parse again, I guess just set the formula or something builder.parser.parse(builder.params, refExHead.value, false); response.ex = refExHead.value; - response.candidateIndex = response.ex.predDerivations.size() > 0 ? 0 : -1; + // write out the grammar PrintWriter out = IOUtils.openOutAppendHard(Paths.get(Master.opts.newGrammarPath, session.id + ".grammar").toString()); for (Rule rule : inducedRules) { out.println(rule.toLispTree().toStringWrap()); } - out.flush(); out.close(); } + + if (response.ex.predDerivations.size() > 0) { + response.candidateIndex = 0; + response.ex.setTargetFormula(response.ex.predDerivations.get(0).formula); + response.ex.setTargetValue(response.ex.predDerivations.get(0).value); + } + ILUtils.logJSONExample(response.ex, session.id, line); } else { LogInfo.logs("Invalid format for def"); } @@ -561,6 +578,7 @@ public class Master { else { LogInfo.log("Invalid command: " + tree); } + } private void defineAccept(Session session, String query, String formula, Response response) { diff --git a/src/edu/stanford/nlp/sempre/interactive/actions/GrammarInducerTest.java b/src/edu/stanford/nlp/sempre/interactive/actions/GrammarInducerTest.java index 02d95b0..b751fc4 100644 --- a/src/edu/stanford/nlp/sempre/interactive/actions/GrammarInducerTest.java +++ b/src/edu/stanford/nlp/sempre/interactive/actions/GrammarInducerTest.java @@ -74,10 +74,10 @@ public class GrammarInducerTest { allRules = new ArrayList<>(); } public void def(String head, String def) { - List induced = InteractiveUtils.induceRulesHelper(":def", head, def, parser, params, "testsession", null); + List induced = ILUtils.induceRulesHelper(":def", head, def, parser, params, "testsession", null); allRules.addAll(induced); LogInfo.logs("Defining %s := %s, added %s", head, def, induced); - induced.forEach(r -> InteractiveUtils.addRuleInteractive(r, parser)); + induced.forEach(r -> ILUtils.addRuleInteractive(r, parser)); } public boolean match(String head, String def) { Example.Builder b = new Example.Builder(); @@ -88,14 +88,14 @@ public class GrammarInducerTest { // LogInfo.logs("Parsing definition: %s", ex.utterance); parser.parse(params, exHead, true); - Derivation defDeriv = InteractiveUtils.combine(InteractiveUtils.derivsfromJson(def, parser, params), ActionFormula.Mode.block); + Derivation defDeriv = ILUtils.combine(ILUtils.derivsfromJson(def, parser, params), ActionFormula.Mode.block); boolean found = false; int ind = 0; for (Derivation d : exHead.predDerivations) { //LogInfo.logs("considering: %s", d.formula.toString()); - LogInfo.logs("Comparing %s vs %s", InteractiveUtils.stripBlock(d).formula.toString(), InteractiveUtils.stripBlock(defDeriv).formula.toString()); - if (InteractiveUtils.stripBlock(d).formula.toString().equals(InteractiveUtils.stripBlock(defDeriv).formula.toString())) { + LogInfo.logs("Comparing %s vs %s", ILUtils.stripBlock(d).formula.toString(), ILUtils.stripBlock(defDeriv).formula.toString()); + if (ILUtils.stripBlock(d).formula.toString().equals(ILUtils.stripBlock(defDeriv).formula.toString())) { found = true; LogInfo.logs("found %s at %d", d.formula, ind); } @@ -115,7 +115,7 @@ public class GrammarInducerTest { Example exHead = b.createExample(); exHead.preprocess(); - Derivation defDeriv = InteractiveUtils.combine(InteractiveUtils.derivsfromJson(def, parser, params), ActionFormula.Mode.block); + Derivation defDeriv = ILUtils.combine(ILUtils.derivsfromJson(def, parser, params), ActionFormula.Mode.block); // LogInfo.logs("Parsing definition: %s", ex.utterance); parser.parse(params, exHead, true);