!759 !include #1003405 // LooseBot v2 static OccTree tree, botTree; static O makeBot; p { L dialogs = loadDialogs("Color Showing Bot"); tree = dialogs2occTree(dialogs); botTree = goodDialogs2occTree(dialogs); print("Tree size: " + tree.size() + ", bot tree size: " + botTree.size()); makeBot = func { new LooseBot(botTree) }; if (!canWalkTree(tree, call(makeBot))) { print("Engine not working, abort."); ret; } print("Tree walked! " + inputFed + " -> " + outputGot); print("Engine works! Trying to shrink the tree."); while (canShrinkTree()) { print("Tree shrunk, trying it again."); } print("Done shrinking tree (new size: " + botTree.size() + ")"); } static int inputFed, outputGot; sbool canShrinkTree() { L> leaves = botTree.allLeaves(); print("Leaves found: " + l(leaves)); bool anyChange = false; for (OccTree leaf : leaves) { Reattach reattach = removeLeaf(leaf); if (canWalkTree()) { print("Leaf removed successfully!"); anyChange = true; } else reattach.reattach(); } ret anyChange; } sclass Reattach { OccTree node, leaf; E key; void reattach() { leaf.parent = node; node.followUp.put(key, leaf); } } static Reattach removeLeaf(OccTree leaf) { new Reattach r; r.leaf = leaf; r.node = leaf.parent; r.key = reverseLookup(leaf.parent.followUp, leaf); leaf.parent.followUp.remove(r.key); leaf.parent = null; ret r; } sbool canWalkTree() { ret canWalkTree(tree, call(makeBot)); } sbool canWalkTree(OccTree tree, O bot) { try { walkTree(tree, bot); true; } catch { ret false; } } svoid walkTree(OccTree tree, O bot) { if (isViable(tree)) { for (E e : keys(tree.followUp)) { if (!contains(ll("good", "bad"), e.state)) { //print("Step " + structure(e)); if (isInput(e)) feed(bot, e); else checkOutput(e, getOutput(bot)); walkTree(tree.followUp(e), bot); //print("Rewind " + structure(e)); rewind(bot); } } } } svoid rewind(O bot) { call(bot, "rewind"); // rewind one step } svoid feed(O bot, E e) { call(bot, "take", e); ++inputFed; } static E getOutput(O bot) { E e = cast call(bot, "getSingleOutput"); if (e != null) ++outputGot; ret e; } svoid checkOutput(E e, E output) { assertEquals(e, output); } static bool isInput(E e) { ret e.q() //|| (e.state() && !matchStart("bot", e.state)); ; }