Libraryless. Click here for Pure Java version (2771L/17K/58K).
1 | !752 |
2 | |
3 | static boolean equipWithSigned = true; // add Stefan's signed theories to all AIs |
4 | |
5 | static new Map<S, AI> aiMap; |
6 | static O prolog; |
7 | |
8 | static class AI { |
9 | S theory; |
10 | boolean enabled; |
11 | S icon; |
12 | long iconFetched; |
13 | |
14 | *() {} |
15 | *(S *theory) {} |
16 | } |
17 | |
18 | p { |
19 | load("aiMap"); |
20 | } |
21 | |
22 | static S createAI(S name, S theory) { |
23 | if (getTheory(theory) == null) |
24 | ret format("Theory * not found", theory); |
25 | AI ai = new AI(theory); |
26 | ai.enabled = true; |
27 | aiMap.put(name, ai); |
28 | logStructure("log", litlist("add", name, ai)); |
29 | save("aiMap"); |
30 | ret format("OK, AI * is created & enabled!", name); |
31 | } |
32 | |
33 | synchronized answer { exceptionToUser { |
34 | if "create ai * *" { |
35 | S name = m.unq(0), theory = m.unq(1); |
36 | ret createAI(name, theory); |
37 | } |
38 | |
39 | if "create ai *" { |
40 | S name = m.unq(0); |
41 | ret createAI(name, name); |
42 | } |
43 | |
44 | if "update ai * *" { |
45 | S name = m.unq(0), theory = m.unq(1); |
46 | if (getTheory(theory) == null) |
47 | ret format("Theory * not found", theory); |
48 | AI ai = lookupPossiblyIgnoreCase(aiMap, name); |
49 | if (ai == null) ret format("AI * not found", name); |
50 | ai.theory = theory; |
51 | save("aiMap"); |
52 | ret format("AI * updated to *", name, theory); |
53 | } |
54 | |
55 | if "disable ai *" { |
56 | S name = m.unq(0); |
57 | AI ai = lookupPossiblyIgnoreCase(aiMap, name); |
58 | if (ai == null) ret format("AI * not found", name); |
59 | if (!ai.enabled) ret "AI not enabled anyway"; |
60 | ai.enabled = false; |
61 | save("aiMap"); |
62 | ret "AI disabled."; |
63 | } |
64 | |
65 | if "enable ai *" { |
66 | S name = m.unq(0); |
67 | AI ai = lookupPossiblyIgnoreCase(aiMap, name); |
68 | if (ai == null) ret format("AI * not found", name); |
69 | if (ai.enabled) ret "AI already enabled"; |
70 | ai.enabled = true; |
71 | save("aiMap"); |
72 | ret "AI enabled."; |
73 | } |
74 | |
75 | if "rename ai * to *" { |
76 | S name = m.unq(0), newName = m.unq(1); |
77 | AI ai = lookupPossiblyIgnoreCase(aiMap, name); |
78 | if (ai == null) ret format("AI * not found", name); |
79 | name = reverseLookup(aiMap, ai); |
80 | AI ai2 = lookupPossiblyIgnoreCase(aiMap, newName); |
81 | if (ai2 != null) |
82 | ret format("Target name * exists!", newName); |
83 | aiMap.remove(name); |
84 | aiMap.put(newName, ai); |
85 | save("aiMap"); |
86 | ret format("AI * renamed to *", name, newName); |
87 | } |
88 | |
89 | if "list ais" { |
90 | ret slackSnippet(structureLines(aiMap)); |
91 | } |
92 | |
93 | if "theory of *" { |
94 | S name = m.unq(0); |
95 | AI ai = lookupPossiblyIgnoreCase(aiMap, name); |
96 | |
97 | if (ai != null) { |
98 | L<S> names = getTheoryNames(name, ai); |
99 | |
100 | new StringBuilder buf; |
101 | for (S theory : names) |
102 | buf.append(getTheory(theory) + "\n"); |
103 | ret reverseLookup(aiMap, ai) + " / " + quote(ai.theory) + "\n" + slackSnippet(buf); |
104 | } |
105 | } |
106 | |
107 | if "test ai * *" exceptionToUser { |
108 | S name = m.unq(0), input = m.unq(1); |
109 | AI ai = aiMap.get(name); |
110 | if (ai == null) ret format("AI * not found", name); |
111 | S answer = queryAI(name, input, nlParse(input), true); |
112 | S x = answer + "\n" + slackSnippet((L) get(prolog, "log")); |
113 | prolog = null; |
114 | ret x; |
115 | } |
116 | |
117 | if "time ai * *" exceptionToUser { |
118 | S name = m.unq(0), input = m.unq(1); |
119 | AI ai = aiMap.get(name); |
120 | if (ai == null) ret format("AI * not found", name); |
121 | S answer; |
122 | time { |
123 | answer = queryAI(name, input, nlParse(input), false); |
124 | } |
125 | S x = answer + "\n" + lastTiming() + " ms"; |
126 | prolog = null; |
127 | ret x; |
128 | } |
129 | |
130 | if "ai program *" exceptionToUser { |
131 | S name = m.unq(0); |
132 | AI ai = aiMap.get(name); |
133 | if (ai == null) ret format("AI * not found", name); |
134 | makeProlog(name, ai, false); |
135 | S x = cast call(prolog, "showProgram"); |
136 | prolog = null; |
137 | ret x; |
138 | } |
139 | |
140 | // do the job |
141 | |
142 | Lisp input = null; |
143 | for (S name : aiMap.keySet()) pcall { |
144 | AI ai = aiMap.get(name); |
145 | if (!ai.enabled) continue; |
146 | if (input == null) |
147 | input = nlParse(s); |
148 | S answer = queryAI(name, s, input, false); |
149 | prolog = null; // clean up prolog interpreter |
150 | if (nempty(answer)) { |
151 | callOpt(getMainBot(), "postAs", name); |
152 | |
153 | if ((ai.icon == null || ai.iconFetched < now()-(empty(ai.icon) ? 1 : 24)*60*60*1000) && canGetIcons()) { |
154 | if (ai.icon == null) ai.icon = ""; // for safety if request fails |
155 | ai.iconFetched = now(); |
156 | pcall { makeIcon(name, ai); } |
157 | save("aiMap"); |
158 | } |
159 | |
160 | if (nempty(ai.icon)) |
161 | callOpt(getMainBot(), "botIcon", ai.icon); |
162 | ret answer; |
163 | } |
164 | } |
165 | }} |
166 | |
167 | static boolean makeProlog(S name, AI ai, boolean logOn) { |
168 | L<S> theoryNames = getTheoryNames(name, ai); |
169 | if (empty(theoryNames)) ret false; |
170 | prolog = call(prologBot(), "newProlog", theoryNames, logOn); |
171 | ret true; |
172 | } |
173 | |
174 | // input = nlParse(s) |
175 | static S queryAI(S name, S s, Lisp input, boolean logOn) { |
176 | AI ai = aiMap.get(name); |
177 | if (!makeProlog(name, ai, logOn)) ret null; |
178 | set(prolog, "outTheory", name + ".data"); |
179 | //S in = "user says " + nlUnparse(input, false); |
180 | /*call(prolog, "addClause", in); |
181 | S question = "say $x";*/ |
182 | S question = "[think [user says " + nlUnparse(nlEscapeVariables(input), false) + "]] and [say $x]"; |
183 | Map<S, Lisp> solution = cast quickImport(call(prolog, "solve", question)); |
184 | if (solution != null) { |
185 | print("SOLUTION: " + structure(solution)); |
186 | Lisp x = solution.get("$x"); |
187 | if (x != null) |
188 | ret nlUnparse(x); |
189 | } |
190 | ret null; |
191 | } |
192 | |
193 | static L<S> getTheoryNames(S name, AI ai) { |
194 | new L<S> l; |
195 | l.add(name + ".data"); |
196 | if (equipWithSigned) |
197 | l.add("signedstefan"); |
198 | |
199 | S theory = getTheory(ai.theory); |
200 | if (theory == null) ret litlist(); |
201 | |
202 | // hack to make directly linked theories work |
203 | L<S> tok = codeTokens(snlTok(theory)); |
204 | if (eq(get(tok, 0), "if") || eq(get(tok, 1), "if")) |
205 | l.add(ai.theory); |
206 | else { |
207 | Lisp t = nlParse(theory); |
208 | for (Lisp x : t.args) |
209 | if (neq(x.head, ",")) |
210 | l.add(unquote(x.head)); |
211 | } |
212 | |
213 | ret l; |
214 | } |
215 | |
216 | static O prologBot() { |
217 | ret getBot("#1002841"); |
218 | } |
219 | |
220 | static S getTheory(S name) { |
221 | ret (S) callOpt(getBot("#1002762"), "getTheoryOpt", name); |
222 | } |
223 | |
224 | static boolean canGetIcons() { |
225 | ret getBot("#1002511") != null; |
226 | } |
227 | |
228 | static void makeIcon(S name, AI ai) { |
229 | print("Making icon for AI: " + name); |
230 | S url = cast call(getBot("#1002511"), "findImageNoShorten", name); |
231 | if (nempty(url)) ai.icon = url; |
232 | } |
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1002861 |
Snippet name: | AI Management Bot |
Eternal ID of this version: | #1002861/1 |
Text MD5: | 347152ec43829661ea31e0ef58587643 |
Transpilation MD5: | 843488b0955b8e1f1488a67e3e79c0f1 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-04-21 22:44:31 |
Source code size: | 6353 bytes / 232 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 784 / 868 |
Referenced in: | [show references] |