Download Jar. Libraryless. Click here for Pure Java version (14537L/111K).
1 | !7 |
2 | |
3 | !include once #1017764 // VirtualMechLists |
4 | |
5 | sS mechLibID = #1400124; |
6 | static O onOutput; // VF1<S> |
7 | static bool authorized; |
8 | |
9 | static L<AbstractThinkBot> bots; |
10 | |
11 | abstract sclass AbstractThinkBot { |
12 | transient VF1<? super S> postMessage; |
13 | transient new L<Map> recentHistory; |
14 | |
15 | abstract void thinkAbout(S input); |
16 | |
17 | void postMessage(S s) { |
18 | callF(postMessage, s); |
19 | } |
20 | } |
21 | |
22 | p { |
23 | mech_useLibrary(mechLibID); |
24 | L<Class<? extends AbstractThinkBot>> classes = botClasses(); |
25 | print("Have think classes: " + classNames(classes)); |
26 | makeBots(); |
27 | bot(); |
28 | } |
29 | |
30 | static L<Class<? extends AbstractThinkBot>> botClasses() { |
31 | ret myNonAbstractClassesImplementing(AbstractThinkBot); |
32 | } |
33 | |
34 | svoid makeBots() { |
35 | bots = map nuWithoutArguments(botClasses()); |
36 | } |
37 | |
38 | sbool telegram_amIAuthorized() { |
39 | ret authorized; |
40 | } |
41 | |
42 | sS answer(S s) { |
43 | temp tempSetThreadLocal(telegram_msg_tl(), new Map); |
44 | final new L<S> output; |
45 | for (AbstractThinkBot bot : bots) pcall { |
46 | bot.postMessage = voidfunc(S s) { |
47 | print(">> " + s); |
48 | pcallF(onOutput, s); |
49 | output.add(s); |
50 | }; |
51 | bot.thinkAbout(s); |
52 | } |
53 | ret rtrim(lines(output)); |
54 | } |
55 | |
56 | |
57 | |
58 | |
59 | sclass TelegramThinkBot > AbstractThinkBot { |
60 | void thinkAbout(S s) { |
61 | s = trim(s); |
62 | |
63 | final new Matches m; |
64 | S procedure = nlLookup(mechMap("Telegram Procedures"), s, m); |
65 | if (procedure != null) { |
66 | procedure = expandDollarRefsToMatches(procedure, m, true); |
67 | print(">> " + procedure); |
68 | postMessage(strOrNull(javaEvalOrInterpret(procedure))); |
69 | } |
70 | |
71 | print("s=" + s); |
72 | S language = 'english; |
73 | if (swic_trim(s, "!german ", m)) { |
74 | language = 'german; |
75 | s = m.rest(); |
76 | print("s=" + s); |
77 | } |
78 | ai_setLanguage(language); |
79 | |
80 | if (swic_trim(s, "!say ", m)) |
81 | postMessage(m.rest()); |
82 | |
83 | if (eq(s, "!gac")) |
84 | postMessage(random_gac36k()); |
85 | |
86 | if (swic_trim(s, "!parse ", m)) |
87 | postMessage(ai_renderCulledParseTree(ai_parseToTreeWithGuessing(m.rest()))); |
88 | |
89 | if (swic_trim(s, "!simplify ", m)) |
90 | postMessage(lines(ai_parseTree_simplifiedTexts(ai_parseToTreeWithGuessing(m.rest())))); |
91 | |
92 | if (telegram_amIAuthorized()) { |
93 | if (eq(s, "!fresh")) dm_refreshTranspiler(); |
94 | |
95 | if (swic_trim(s, "!eval ", m)) |
96 | postMessage(pcallOrExceptionText(func { strOrNull(javaEvalOrInterpret(m.rest())) })); |
97 | |
98 | if (swic_trim(s, "!rule ", m)) { |
99 | S rule = m.rest(); |
100 | LS rules = trimAll(ai_unparsedTalkRules()); |
101 | if (!contains(rules, rule)) { // TODO: ignore global IDs |
102 | appendToMechList_noUniq("NL Logic Examples", "\n" + rule); |
103 | postMessage("Rule saved. Have " + n2(l(rules)+1, "rule") + "."); |
104 | } |
105 | } |
106 | |
107 | if (swic_trim(s, "!fact ", m)) { |
108 | S fact = m.rest(); |
109 | LS facts = mL("Random facts"); |
110 | if (!contains(facts, fact)) { |
111 | appendToMechList_noUniq("Random facts", fact); |
112 | postMessage("Fact saved. Have " + n2(l(facts)+1, "fact") + "."); |
113 | } |
114 | } |
115 | } |
116 | } |
117 | } |
118 | |
119 | |
120 | |
121 | |
122 | sclass TelegramFactsBot > AbstractThinkBot { |
123 | S evalExp(Exp e, NLLogicChecker_v2.Matching m) { |
124 | S code = nlLogic_text(e); |
125 | print("Eval'ing: " + code); |
126 | temp tempAdd(hotwire_copyOver_after, voidfunc(Class c) { copyFields(mc(), c, 'telegram_msg_tl) }); |
127 | S result = str(evalWithDollarVars(code, m.matches)); |
128 | print("Result: " + shorten(result, 100)); |
129 | ret result; |
130 | } |
131 | |
132 | void thinkAbout(fS s) { |
133 | final Map msg = telegram_msg(); |
134 | |
135 | NLLogicChecker_v2 c = new NLLogicChecker_v2 { |
136 | L<S> entities; |
137 | |
138 | bool checkExpression(Exp e, Matching m) { |
139 | new Matches mm; |
140 | if (e cast Func) { |
141 | // FUNCTION CONDITIONS |
142 | |
143 | if (eq(e.name, "verbPhraseFromThirdPerson")) |
144 | ret nlLogic_stringFunction(f ai_verbPhraseFromThirdPerson, e, m.matches); |
145 | else if (eq(e.name, "singular")) |
146 | ret nlLogic_stringFunction(f singular, e, m.matches); |
147 | else if (eq(e.name, 'eval)) |
148 | ret eq("true", evalExp(e.arg, m)); |
149 | else if (eq(e.name, 'entity)) { |
150 | if (entities == null) { |
151 | long time = sysNow(); |
152 | fS switched = switcheroo(s); |
153 | print("Switched >> " + switched); |
154 | entities = evalWithTimeoutOrNull(5000, func -> LS { |
155 | mapMethod('text, ai_extractEntities_v1(switched)) |
156 | }); |
157 | print("Entities (" + elapsedMS(time) + " ms): " + joinWithComma(entities)); |
158 | if (entities == null) entities = new L; |
159 | } |
160 | for (S entity : entities) |
161 | if (matcher.match(nlLogic_text(e.arg), entity, m.matches)) true; |
162 | } else if (startsWith(e.name, "line", mm) && isInteger(mm.rest())) { |
163 | int n = parseInt(mm.rest())-nlLogic_numberOfLinesReferenced(checkingRule->in); |
164 | S line = n == 0 ? s : getString(get(recentHistory, l(recentHistory)+n), 'text); |
165 | print("Recent: " + recentHistory); |
166 | S pat = nlLogic_text(e.arg); |
167 | print("n=" + n + ", Matching " + e + " with " + line); |
168 | ret matcher.match(pat, line, m.matches); |
169 | } else if (eq(e.name, 'unknownIf)) { |
170 | S statement = nlLogic_text(apply(e.arg, m)); |
171 | print("Checking statement: " + statement); |
172 | ret !cic(facts, statement) && !cic(facts, "Untrue: " + statement); |
173 | } else if (eq(e.name, 'inputContainsTokens)) |
174 | ret call_verbose jcontains(s, nlLogic_text(e.arg)); |
175 | else if (eq(e.name, 'inputStartsWith)) |
176 | ret call_verbose startsWith(s, nlLogic_text(e.arg)); |
177 | else if (eq(e.name, 'followingUpOn)) { |
178 | S text = nlLogic_text(e.arg); |
179 | // e.g. "lhnshnhcklhabvmu with input=$input" |
180 | if (!match("* with input=*", text, mm) || !isDollarVar(mm.get(1))) false; |
181 | S ruleID = mm.unq(0), dollarInput = mm.get(1); |
182 | Map /*prev = last(recentHistory),*/ prevPrev = nextToLast(recentHistory); |
183 | S msgID = getString(prevPrev, 'globalID); |
184 | S input = getString(prevPrev, 'text); |
185 | print("followingUpOn: msgID=" + msgID + ", input=" + input); |
186 | printStruct(+prevPrev); |
187 | //printStruct(+prev); |
188 | S pat = "Rule " + ruleID + " fired on message " + msgID + " "; |
189 | print("pat=" + pat); |
190 | for (S ruleFired : mL("Telegram Rule Fires")) |
191 | if (swic(ruleFired, pat)) |
192 | ret print("result=", strictPutIC(m.matches, dollarInput, input)); |
193 | false; |
194 | } |
195 | } |
196 | |
197 | if (e cast Eq) { |
198 | // EQUATION CONDITIONS |
199 | |
200 | Exp r = e.right; |
201 | S var = nlLogic_text(e.left); |
202 | if (r cast Func) pcall { |
203 | if (eq(r.name, 'eval)) |
204 | ret new NLStringMatcher_singleDollarVar().match(var, evalExp(r.arg, m), m.matches); |
205 | } |
206 | } |
207 | |
208 | if (e instanceof Literal) { |
209 | // TEXT CONDITIONS |
210 | |
211 | S text = nlLogic_text(e); |
212 | if (eq(text, "authorized")) |
213 | ret telegram_amIAuthorized(); |
214 | } |
215 | |
216 | ret super.checkExpression(e, m); |
217 | } |
218 | }; |
219 | c.matcher = new NLStringMatcher_dollarVars_underscores; |
220 | c.input = s; |
221 | c.facts = mL_facts(); |
222 | |
223 | LS unparsedRules = ai_unparsedTalkRules(); |
224 | |
225 | for (S listName : mL("Rule & Fact Lists")) |
226 | for (S x : splitAtEmptyLines(mL_raw(listName))) |
227 | if (anyJavaTokens(x)) |
228 | if (nlLogic_parseRule(x) != null) |
229 | unparsedRules.add(x); |
230 | else |
231 | c.facts.add(x); |
232 | |
233 | unparsedRules = sortedByCalculatedField(unparsedRules, func(S s) { jcontains(s, "entity(") }); |
234 | L<IfThen> rules = map_pcall nlLogic_parseRule(unparsedRules); |
235 | |
236 | for (IfThen r : rules) { |
237 | continue if r == null; |
238 | Exp out = r.out; |
239 | if (out cast Func) |
240 | if (eq(out.name, "sayIfTrue")) { |
241 | r.out = Func('output, out.arg); |
242 | r.in = And(r.in, Func('fact, out.arg)); |
243 | print(r); |
244 | } |
245 | } |
246 | |
247 | fS msgGlobalID = getString(msg, 'globalID); |
248 | if (nempty(msgGlobalID)) |
249 | applyNLLogicFacts_v3_onRuleFired.set(voidfunc(IfThen rule, NLLogicChecker_v2.Matching m) { |
250 | if (empty(rule.globalID)) ret; |
251 | S fact = format("Rule * fired on message * at *", rule.globalID, msgGlobalID, localDateWithMilliseconds()); |
252 | if (nempty(m.matches)) |
253 | fact += " with vars " + dropPrefix("lhm", struct(m.matches)); |
254 | addToMechList("Telegram Rule Fires", fact); |
255 | }); |
256 | |
257 | applyNLLogicFacts_v3(c, voidfunc(Exp e) { |
258 | // Rule fired! |
259 | |
260 | if (e cast Func) { |
261 | if (eq(e.name, 'output)) |
262 | postMessage(nlLogic_text(e.arg)); |
263 | else if (eq(e.name, 'fact)) { |
264 | S fact = nlLogic_text(e.arg); |
265 | if (!contains(mL("Random facts"), fact) && mech_changed(addToMechList("Derived facts", fact))) |
266 | postMessage("Storing fact: " + fact); |
267 | } else if (eq(e.name, 'storeRule)) { |
268 | S rule = nlLogic_text(e.arg); |
269 | if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule))) |
270 | postMessage("Rule stored"); |
271 | } |
272 | } |
273 | }, rules); |
274 | } |
275 | } |
276 | |
277 | |
278 | |
279 | |
280 | sclass TelegramInitiativeBot > AbstractThinkBot { |
281 | new L<Pair<S, IfThen>> activeTempRules; |
282 | |
283 | void thinkAbout(S s) { |
284 | if (eq(s, "!initiative")) { |
285 | L<IfThen> rules = mL_parsedNLRulesWithoutIDs("Initiative rules"); |
286 | for (IfThen rule : shuffledIterator(rules)) { |
287 | Pair<Exp> p = nlLogic_extractFirstCondition(rule.in); |
288 | if (p == null) continue; |
289 | if (nlLogic_isFunc(p.a, 'initiative)) { |
290 | postMessage(nlLogic_text(((Func) p.a).arg)); |
291 | IfThen temp = IfThen(p.b, rule.out); |
292 | print("Have temp rule: " + sfu(temp)); |
293 | activeTempRules.add(pair(aGlobalID(), temp)); |
294 | ret; |
295 | } |
296 | } |
297 | } |
298 | |
299 | applyNLLogicFacts_v2(s, voidfunc(S s) { postMessage(s) }, |
300 | new L, activeTempRules); |
301 | activeTempRules.clear(); |
302 | } |
303 | } |
Began life as a copy of #1017706
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1017805 |
Snippet name: | Baked Bot Backup 1 |
Eternal ID of this version: | #1017805/1 |
Text MD5: | df9b93e8135970424c693eb93ae01e65 |
Transpilation MD5: | d2ad0af00b1acfb7103941ef9523c9ef |
Author: | stefan |
Category: | javax / a.i. |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-08-14 10:59:20 |
Source code size: | 10249 bytes / 303 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 639 / 1104 |
Referenced in: | [show references] |