1 | abstract sclass Adapter { |
2 | void learn(S in, S out) {} |
3 | S get(S in) { ret in; } |
4 | O remember() { null; } |
5 | void rewind(O o) {} |
6 | } |
7 | |
8 | abstract sclass DialogBot { |
9 | sbool debug, repeat = true; |
10 | OccTree2 tree; |
11 | new L<OccTree2> nodes; |
12 | new L<L> rewindStack; |
13 | new L adapterRewind; |
14 | Adapter adapter; |
15 | |
16 | *(OccTree2 *tree) { nodes.add(tree); } |
17 | *(OccTree2 tree, Adapter adapter) { |
18 | this(tree); |
19 | this.adapter = adapter; |
20 | } |
21 | |
22 | void take(E in) { |
23 | remember(); |
24 | if (repeat) setAdd(nodes, tree); |
25 | new L<OccTree2> l; |
26 | for (OccTree2 node : nodes) |
27 | for (OccTree2 n : node.next) |
28 | if (matchE(adapt(n.e), in)) |
29 | l.add(n); |
30 | |
31 | if (adapter != null) |
32 | for (OccTree2 n : l) |
33 | adapter.learn(adapt(n.e).text(), in.text()); |
34 | |
35 | nodes = l; |
36 | } |
37 | |
38 | E adapt(E e) { |
39 | if (adapter != null) |
40 | ret new E(adapter.get(e.text()), e.type()); // TODO: security when rewriting states |
41 | ret e; |
42 | } |
43 | |
44 | void remember() { |
45 | if (rewindStack != null) { |
46 | rewindStack.add(cloneList(nodes)); |
47 | if (adapter != null) |
48 | adapterRewind.add(adapter.remember()); |
49 | } |
50 | } |
51 | |
52 | E getSingleOutput() { |
53 | remember(); |
54 | new L<OccTree2> l; |
55 | for (OccTree2 node : nodes) |
56 | for (OccTree2 n : node.next) |
57 | if (n.e.a() || isCommand(n.e)) |
58 | l.add(n); |
59 | nodes = l; |
60 | ret nempty(nodes) ? adapt(first(nodes).e) : null; |
61 | } |
62 | |
63 | void rewind() { |
64 | nodes = popLast(rewindStack); |
65 | if (adapter != null) |
66 | adapter.rewind(popLast(adapterRewind)); |
67 | } |
68 | |
69 | abstract bool matchE(E a, E b); |
70 | |
71 | bool isCommand(E e) { |
72 | ret e.state() && matchStart("bot", e.state); |
73 | } |
74 | |
75 | void noRewind() { |
76 | rewindStack = null; |
77 | } |
78 | } |
79 | |
80 | sclass LooseBot extends DialogBot { |
81 | *(OccTree2 node) { super(node); } |
82 | *(OccTree2 tree, Adapter adapter) { super(tree, adapter); } |
83 | |
84 | bool matchE(E a, E b) { |
85 | // standard NL matching |
86 | ret eq(a.type(), b.type()) && match(a.text(), b.text()); |
87 | } |
88 | } |
89 | |
90 | sclass WordAdapter extends Adapter { |
91 | new Map<S, S> wordMap; |
92 | |
93 | void learn(S in, S out) { |
94 | L<S> t1 = nlTok2(dropPunctuation2(in)); |
95 | L<S> t2 = nlTok2(dropPunctuation2(out)); |
96 | if (l(t1) != l(t2)) ret; |
97 | |
98 | for (int i = 1; i < l(t1); i += 2) { |
99 | S w1 = t1.get(i), w2 = t2.get(i); |
100 | if (!eqic(w1, w2)) |
101 | // just overwrite - be flexible! |
102 | wordMap.put(w1.toLowerCase(), w2.toLowerCase()); |
103 | } |
104 | } |
105 | |
106 | S get(S s) { |
107 | L<S> tok = nlTok2(s); |
108 | for (int i = 1; i < l(tok); i += 2) { |
109 | S w = wordMap.get(tok.get(i).toLowerCase()); |
110 | if (nempty(w)) |
111 | tok.set(i, w); |
112 | } |
113 | ret join(tok); |
114 | } |
115 | |
116 | O remember() { ret cloneMap(wordMap); } |
117 | void rewind(O o) { wordMap = (Map) o; } |
118 | |
119 | } |
Began life as a copy of #1003410
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003412 |
Snippet name: | Tree-Walking DialogBot + LooseBot v4 (parallel walk) |
Eternal ID of this version: | #1003412/1 |
Text MD5: | a26eeb5b0f9ec4656209db032357234c |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-07-01 03:24:36 |
Source code size: | 2798 bytes / 119 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 581 / 938 |
Referenced in: | [show references] |