package edu.stanford.nlp.sempre.interactive.test;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.testng.Assert;
import org.testng.annotations.Test;
import edu.stanford.nlp.sempre.ContextValue;
import edu.stanford.nlp.sempre.Executor;
import edu.stanford.nlp.sempre.Formulas;
import edu.stanford.nlp.sempre.Json;
import edu.stanford.nlp.sempre.NaiveKnowledgeGraph;
import edu.stanford.nlp.sempre.StringValue;
import edu.stanford.nlp.sempre.interactive.DALExecutor;
import edu.stanford.nlp.sempre.interactive.Item;
import edu.stanford.nlp.sempre.interactive.World;
import edu.stanford.nlp.sempre.interactive.voxelurn.Color;
import edu.stanford.nlp.sempre.interactive.voxelurn.Voxel;
import fig.basic.LispTree;
import fig.basic.LogInfo;
/**
* Tests the DALExecutor
*
* @author sidaw
*/
public class DALExecutorTest {
DALExecutor executor = new DALExecutor();
protected static void runFormula(DALExecutor executor, String formula, ContextValue context,
Predicate<World> checker) {
LogInfo.begin_track("formula: %s", formula);
DALExecutor.opts.worldType = "VoxelWorld";
Executor.Response response = executor.execute(Formulas.fromLispTree(LispTree.proto.parseFromString(formula)),
context);
NaiveKnowledgeGraph graph = (NaiveKnowledgeGraph) context.graph;
String wallString = ((StringValue) graph.triples.get(0).e1).value;
String jsonStr = ((StringValue) response.value).value;
LogInfo.logs("Start:\t%s", wallString);
LogInfo.logs("Result:\t%s", jsonStr);
LogInfo.end_track();
if (checker != null) {
if (!checker.test(World.fromContext("VoxelWorld", getContext(jsonStr)))) {
LogInfo.end_track();
Assert.fail(jsonStr);
}
}
}
private static ContextValue getContext(String blocks) {
// a hack to pass in the world state without much change to the code
String strigify2 = Json.writeValueAsStringHard(blocks); // some parsing
// issue inside
// lisptree parser
return ContextValue.fromString(
String.format("(context (graph NaiveKnowledgeGraph ((string \"%s\") (name b) (name c))))", strigify2));
}
public Predicate<World> selectedSize(int n) {
return x -> {
LogInfo.logs("Got %d, expected %d", x.selected().size(), n);
return x.selected().size() == n;
};
}
@Test(groups = { "Interactive" })
public void testJoin() {
String defaultBlocks = "[[1,1,1,\"Green\",[]],[1,2,1,\"Blue\",[]],[2,2,1,\"Red\",[]],[3,2,2,\"Yellow\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testJoin");
runFormula(executor, "(: select *)", context, selectedSize(4));
runFormula(executor, "(: select (or (color red) (color green)))", context, selectedSize(2));
runFormula(executor, "(: select (or (row (number 1)) (row (number 2))))", context, selectedSize(3));
runFormula(executor, "(: select (col ((reverse row) (color red))))", context, null);
runFormula(executor, "(: select (color ((reverse color) (row 3))))", context, null);
runFormula(executor, "(: select (color ((reverse color) (color ((reverse color) (color red))))))", context,
x -> x.selected().iterator().next().get("color").equals("red"));
runFormula(executor, "(: select (and (row 1) (not (color green))))", context, x -> x.selected().isEmpty());
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testSpecialSets() {
String defaultBlocks = "[[1,1,1,\"Green\",[\"S\"]],[1,2,1,\"Blue\",[\"S\"]],[2,2,1,\"Red\",[\"S\"]],[2,2,2,\"Yellow\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testSpecial");
runFormula(executor, "(: select nothing)", context, selectedSize(0));
runFormula(executor, "(: select *)", context, selectedSize(4));
runFormula(executor, "(: select this)", context, selectedSize(3));
runFormula(executor, "(: select (and this nothing))", context, selectedSize(0));
runFormula(executor, "(: select (not this))", context, selectedSize(1));
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testMerge() {
{
String defaultBlocks = "[[1,1,1,\"Green\",[]],[1,2,1,\"Blue\",[]],[2,2,1,\"Red\",[]],[2,2,2,\"Yellow\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testMerge");
runFormula(executor, "(: select (or (color red) (color blue)))", context, selectedSize(2));
runFormula(executor, "(: select (and (color red) (color blue)))", context, selectedSize(0));
runFormula(executor, "(: select (not (color red)))", context, selectedSize(3));
runFormula(executor, "(: select (not *))", context, selectedSize(0));
}
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testBasicActions() {
String defaultBlocks = "[[1,1,1,\"Green\",[]],[1,2,1,\"Blue\",[]],[2,2,1,\"Red\",[]],[2,2,3,\"Yellow\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testBasicActions");
runFormula(executor, "(:s (: select *) (: remove))", context, x -> real(x.allItems).size() == 0);
runFormula(executor, "(:s (: select (row (number 1))) (: add red top) (: add red top))", context,
x -> real(x.allItems).size() == 8);
runFormula(executor, "(:for * (: remove))", context, x -> real(x.allItems).size() == 0);
runFormula(executor, "(:foreach * (: remove))", context, x -> real(x.allItems).size() == 0);
runFormula(executor, "(:s (: select (or (color red) (color orange))) (: remove))", context,
x -> real(x.allItems).size() == 3);
runFormula(executor, "(:foreach (or (color red) (color orange)) (:loop (number 5) (: add red top)))", context,
x -> x.allItems.size() == 9);
runFormula(executor,
"(:for (or (color red) (color blue)) (:loop (number 5) (:s (: move left) (: move right) (: move left))))",
context, null);
LogInfo.end_track();
}
private Set<Item> real(Set<Item> all) {
return all.stream().filter(c -> !((Voxel) c).color.equals(Color.Fake)).collect(Collectors.toSet());
}
@Test(groups = { "Interactive" })
public void testRemove() {
// this is a green stick
String defaultBlocks = "[[1,1,1,\"Green\",[]],[1,1,2,\"Green\",[\"S\"]],[1,1,3,\"Red\",[\"S\"]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testMoreActions");
runFormula(executor, "(: remove)", context, x -> real(x.allItems).size() == 2 && x.selected.size() == 2);
runFormula(executor, "(:for * (: remove))", context, x -> x.selected.size() == 2 && real(x.allItems).size() == 0);
runFormula(executor, "(:for (color green) (: remove))", context,
x -> x.selected.size() == 2 && real(x.allItems).size() == 1);
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testMoreActions() {
// this is a green stick
String defaultBlocks = "[[1,1,1,\"Green\",[]],[1,1,2,\"Green\",[]],[1,1,3,\"Green\",[]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testMoreActions");
runFormula(executor, "(:s (: select *) (:for (call veryx left this) (: remove)))", context,
x -> x.allItems.stream().allMatch(c -> ((Voxel) c).color.equals(Color.Fake)));
runFormula(executor,
"(:for * (:for (call veryx bot) (:loop (number 2) (:s (: add red left) (: select (call adj top))))))", context,
x -> x.allItems.size() == 6);
runFormula(executor, "(:s (: select *) (: select (call veryx bot selected)) (: remove selected) )", context,
x -> real(x.allItems).size() == 3);
// x -> x.selected().iterator().next().get("height") == new Integer(3)
runFormula(executor, "(:loop (count (color green)) (: add red left *))", context, x -> x.allItems.size() == 20);
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void troubleCases() {
// this is a green stick
String defaultBlocks = "[[1,1,1,\"Green\",[\"S\"]],[1,1,2,\"Green\",[]],[1,1,3,\"Green\",[]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("troubleCases");
runFormula(executor, "(:s (: select *) (: select (or (call veryx top this) (call veryx bot this))))", context,
selectedSize(2));
runFormula(executor, " (: select (or (call veryx top (color green)) (call veryx bot (color green))))", context,
selectedSize(2));
runFormula(executor, " (: select (and (call veryx top (color green)) (call veryx bot (color green))))", context,
selectedSize(0));
runFormula(executor, " (: select (call adj top this))", context, selectedSize(1));
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testFake() {
// this is a green stick
String defaultBlocks = "[[1,1,0,\"Fake\",[\"S\"]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testAnchors");
runFormula(executor, "(: add red top)", context, selectedSize(1));
runFormula(executor, "(: add red left)", context, selectedSize(1));
runFormula(executor, "(: add red here)", context, selectedSize(1));
runFormula(executor, "(:loop (number 3) (: add red left))", context, selectedSize(1));
runFormula(executor, "(:loop (number 3) (: add red top))", context, x -> x.allItems.size() == 4);
runFormula(executor, "(:loop (number 3) (: add red left))", context, x -> x.allItems.size() == 4);
runFormula(executor, "(:loop (number 3) (: select (or this (call adj top this))))", context, selectedSize(4));
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testIsolation() {
// this is a green stick
String defaultBlocks = "[[1,1,1,\"Green\",[\"S\"]],[1,1,2,\"Green\",[]],[1,1,3,\"Green\",[]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testIsolation");
runFormula(executor, "(:isolate (:loop (number 4) (: add red top)))", context, x -> x.allItems.size() == 5);
runFormula(executor, "(:isolate (:loop (number 2) (: add red top)))", context, x -> x.allItems.size() == 4);
runFormula(executor, "(:isolate (:loop (number 5) (: add red top)))", context, x -> x.allItems.size() == 6);
runFormula(executor, "(:s (:isolate (:loop (number 5) (: add red top))) (: select (color red)))", context,
selectedSize(5));
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testUpdate() {
String defaultBlocks = "[[1,1,1,\"Green\",[\"S\"]],[1,1,2,\"Red\",[]],[1,1,3,\"Green\",[]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testUpdate");
runFormula(executor, "(:s (: update color red) (: select (color red)))", context, selectedSize(2));
runFormula(executor, "(:s (: update height (number 0)) (: select (height (number 0))))", context, selectedSize(1));
LogInfo.end_track();
}
@Test(groups = { "Interactive" })
public void testScoping() {
// this is a green stick
String defaultBlocks = "[[1,1,1,\"Green\",[\"S\"]],[1,1,2,\"Green\",[]],[1,1,3,\"Green\",[]],[1,1,4,\"Green\",[]]]";
ContextValue context = getContext(defaultBlocks);
LogInfo.begin_track("testIsolation");
runFormula(executor, "(:blk (: select (call veryx top this)))", context,
x -> (Integer) x.selected.iterator().next().get("height") == 1);
runFormula(executor, "(:blkr (: select (call adj top this)))", context,
x -> (Integer) x.selected.iterator().next().get("height") == 2);
runFormula(executor,
"(:s (:blk (: add red here ) (: select (call adj top this)) (: add red here )) (: select (color red)))",
context, x -> x.selected.size() == 2);
runFormula(executor,
"(:s (:blkr (: add red here ) (: select (call adj top this)) (: add red here )) (: select (color red)))",
context, x -> x.selected.size() == 2);
LogInfo.end_track();
}
}