1 | sclass DialogOptimizer { |
2 | OccTree2 tree, botTree; |
3 | bool walkTree_debug; |
4 | bool useAdapter = true; |
5 | O engine; |
6 | |
7 | *(S theme, S engineID) { |
8 | engine = run(engineID); |
9 | L<Dialog> dialogs = loadDialogs(theme); |
10 | callOpt(mc(), "expandDialogs", dialogs); // hmm. |
11 | expandEllipsis(tree = makeOccTree(dialogs)); |
12 | expandEllipsis(botTree = makeOccTree(withoutSecretDialogs(dialogs))); |
13 | printOccTree2(botTree); |
14 | print("Tree size: " + tree.size() + ", bot tree size: " + botTree.size()); |
15 | //walkTree_debug = true; |
16 | try { |
17 | walkTree(); |
18 | } catch e { |
19 | print("Engine not working, abort."); |
20 | printStackTrace(e); |
21 | ret; |
22 | } |
23 | print("Tree walked! " + inputFed + " -> " + outputGot); |
24 | |
25 | int origSize = botTree.size()-1; |
26 | print("Engine works! Trying to shrink the tree."); |
27 | |
28 | while (canShrinkTree()) { |
29 | print("Tree shrunk, trying it again."); |
30 | } |
31 | |
32 | int newSize = botTree.size()-1; |
33 | printOccTree2(botTree); |
34 | if (newSize < origSize) { |
35 | long percent = newSize == 0 ? 9999 : round(origSize*100.0/newSize-100); |
36 | print("Done shrinking tree (" + origSize + " -> " + newSize + " entries - " + percent + "% shrinkage!)"); |
37 | } else |
38 | print("Tree unshrinkable."); |
39 | } |
40 | |
41 | int inputFed, outputGot; |
42 | |
43 | bool canShrinkTree() { |
44 | L<OccTree2> leaves = botTree.allLeaves(); |
45 | print("Leaves found: " + l(leaves)); |
46 | |
47 | bool anyChange = false; |
48 | for (OccTree2 leaf : leaves) { |
49 | print("Trying to remove leaf: " + leaf.e + " (level " + leaf.level() + ")"); |
50 | Reattach reattach = removeLeaf(leaf); |
51 | //printOccTree2(botTree); |
52 | if (canWalkTree()) { |
53 | print("Leaf removed successfully!"); |
54 | anyChange = true; |
55 | } else |
56 | reattach.reattach(); |
57 | } |
58 | |
59 | ret anyChange; |
60 | } |
61 | |
62 | class Reattach { |
63 | OccTree2 node, leaf; |
64 | int idx; |
65 | |
66 | void reattach() { |
67 | leaf.parent = node; |
68 | node.next.add(idx, leaf); |
69 | } |
70 | } |
71 | |
72 | Reattach removeLeaf(OccTree2 leaf) { |
73 | new Reattach r; |
74 | r.leaf = leaf; |
75 | r.node = leaf.parent; |
76 | r.idx = leaf.parent.next.indexOf(leaf); |
77 | leaf.parent.next.remove(r.idx); |
78 | leaf.parent = null; |
79 | ret r; |
80 | } |
81 | |
82 | bool canWalkTree() { |
83 | ret canWalkTree(tree, makeBot()); |
84 | } |
85 | |
86 | bool canWalkTree(OccTree2 tree, O bot) { |
87 | try { walkTree(tree, bot); true; } catch e { |
88 | if (walkTree_debug) |
89 | printStackTrace(e); |
90 | ret false; |
91 | } |
92 | } |
93 | |
94 | void walkTree() { |
95 | walkTree(tree, makeBot()); |
96 | } |
97 | |
98 | L<S> statesToIgnore = ll("good", "bad", "end"); |
99 | |
100 | void walkTree(OccTree2 tree, O bot) { |
101 | if (tree.isLeaf()) |
102 | assertNull(getOutput(bot)); |
103 | else |
104 | for (E e : tree.followUpKeys()) { |
105 | if (!contains(statesToIgnore, e.state)) { |
106 | bool input = isInput(e); |
107 | if (walkTree_debug) |
108 | print((input ? "FEED " : "CHECK ") + structure(e)); |
109 | if (input) { |
110 | assertNull(getOutput(bot)); |
111 | feed(bot, e); |
112 | } else |
113 | checkOutput(e, getOutput(bot), bot); |
114 | walkTree(tree.followUp(e), bot); |
115 | if (walkTree_debug) |
116 | print("Rewind " + structure(e)); |
117 | rewind(bot); |
118 | } |
119 | } |
120 | } |
121 | |
122 | void rewind(O bot) { |
123 | call(bot, "rewind"); // rewind one step |
124 | } |
125 | |
126 | void feed(O bot, E e) { |
127 | call(bot, "take", quickExport(e, bot)); |
128 | ++inputFed; |
129 | } |
130 | |
131 | E getOutput(O bot) { |
132 | E e = cast quickImport(call(bot, "getSingleOutput")); |
133 | if (e != null) ++outputGot; |
134 | ret e; |
135 | } |
136 | |
137 | void checkOutput(E e, E output, O bot) { |
138 | //if (e.state() && matchStart("result is", e.text())) ret; |
139 | //assertEquals(e, output); |
140 | if (neq(e, output)) { |
141 | print(asciiHeading("THOUGHTS")); |
142 | print(callOpt(bot, "thoughts")); |
143 | print(); |
144 | fail("Bot fail: Expected " + e + ", got: " + output); |
145 | } |
146 | } |
147 | |
148 | // should match isCommand() in LooseBot |
149 | bool isInput(E e) { |
150 | ret e.q() |
151 | || e.state() && matchStart("result is ", e.text()); |
152 | } |
153 | |
154 | O makeBot() { |
155 | setOpt(engine, "botTree", quickExport(botTree, engine)); |
156 | ret callF(get(engine, "makeBot")); |
157 | } |
158 | } |
Began life as a copy of #1003500
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003533 |
Snippet name: | class DialogOptimizer |
Eternal ID of this version: | #1003533/1 |
Text MD5: | 9fd2542732e528af4a88979f8f0f1c96 |
Author: | stefan |
Category: | javax / talking robots |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-07-19 18:05:18 |
Source code size: | 4212 bytes / 158 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 521 / 893 |
Referenced in: | [show references] |