1 | bool debug; |
2 | bool imagineMode; |
3 | bool collectCheckingLog = true; |
4 | new LinkedHashSet<S> imaginedFacts; |
5 | LS checkingLog; |
6 | long processingTime; |
7 | new L<IfThen> activeTempRules; |
8 | int evalTimeout = 20000; |
9 | |
10 | void thinkAbout(S s) { |
11 | time "Processing Time For Message"{ |
12 | thinkAbout_impl(s); |
13 | } |
14 | processingTime = lastTiming(); |
15 | } |
16 | |
17 | void thinkAbout_impl(fS input) { |
18 | final new Thinking t; |
19 | final Map<S, O> tl = getMCThreadLocals(ai_staticVars()); |
20 | /*Thread thread = startThread("Think!", r { |
21 | setMCThreadLocals(tl);*/ |
22 | t.thinkAbout(input); |
23 | /*});*/ |
24 | int n = 0; |
25 | do { |
26 | while (l(t.output) > n) |
27 | postMessage(t.output.get(n++)); |
28 | //joinThread(thread, 50); |
29 | } while (!t.done); |
30 | |
31 | activeTempRules.clear(); |
32 | } |
33 | |
34 | void _postMessage(S s) { postMessage(s); } |
35 | |
36 | class Thinking { |
37 | long cancelTime = now()+20000; |
38 | new Map<S, Int> ruleScores; |
39 | new LinkedHashSet<S> rewrittenInputs; |
40 | new LinkedHashSet<S> newRewrittenInputs; |
41 | volatile bool posted, done; |
42 | new L<IfThen> rules; |
43 | replace Plan with PlanInMotion. |
44 | new Plan<Runnable> plan; |
45 | new HashSet<S> outputSet; |
46 | LS output = synchroList(); |
47 | |
48 | void postMessage(S s) { |
49 | //_postMessage(s); |
50 | if (outputSet.add(s)) |
51 | output.add(s); |
52 | posted = true; |
53 | } |
54 | |
55 | void done() { done = true; } |
56 | |
57 | void thinkAbout(S input) { |
58 | try { |
59 | thinkAbout_impl(input); |
60 | } finally { |
61 | done(); |
62 | } |
63 | } |
64 | |
65 | void thinkAbout_impl(fS input0) { |
66 | fS input1 = unixLineBreaks(input0); |
67 | plan.add(r "!initiative" { |
68 | if (!eq(input1, "!initiative")) ret; |
69 | L<IfThen> rules = mL_parsedNLRulesWithoutIDs("Initiative rules"); |
70 | for (IfThen rule : shuffledIterator(rules)) { |
71 | Pair<Exp> p = nlLogic_extractFirstCondition(rule.in); |
72 | if (p == null) continue; |
73 | if (nlLogic_isFunc(p.a, 'initiative)) { |
74 | postMessage(nlLogic_text(((Func) p.a).arg)); |
75 | IfThen temp = IfThen(p.b, rule.out); |
76 | temp.globalID = aGlobalID(); |
77 | print("Have temp rule: " + sfu(temp)); |
78 | activeTempRules.add(temp); |
79 | ret with done(); |
80 | } |
81 | } |
82 | ret with done(); |
83 | }); |
84 | |
85 | plan.add(r "!step" { |
86 | new Matches mm; |
87 | if (!startsWith_trim(input1, "!step ", mm)) ret; |
88 | // TODO |
89 | }); |
90 | |
91 | runPlanWithCheck(plan, func -> bool { !done }); |
92 | if (done) ret; |
93 | |
94 | stdCommands(input1); |
95 | |
96 | S input2 = input1; |
97 | final new LS options; |
98 | if (startsWith(input2, "[")) { |
99 | addAll(options, leadingSquareBracketOptions(input2)); |
100 | input2 = dropLeadingSquareBracketStuff(input2); |
101 | } |
102 | |
103 | fS input = input2; |
104 | ai_tg_collectRuleFeedback(ruleScores, null); |
105 | |
106 | newRewrittenInputs.add(input); |
107 | final Map msg = telegram_msg(); |
108 | |
109 | final NLLogicChecker_v3 c = new NLLogicChecker_v3 { |
110 | bool checkExpression_impl(Exp e, Matching m) { |
111 | if (e instanceof Literal) { |
112 | // TEXT CONDITIONS |
113 | |
114 | S text = nlLogic_text(e); |
115 | if (eq(text, "authorized")) |
116 | ret telegram_amIAuthorized(); |
117 | else if(eq(text, "imagineMode")) |
118 | ret imagineMode; |
119 | } |
120 | |
121 | ret super.checkExpression_impl(e, m); |
122 | } |
123 | }; |
124 | |
125 | if (collectCheckingLog) { |
126 | checkingLog = new L; |
127 | nlLogic_collectCheckingLog(c, checkingLog); |
128 | } |
129 | |
130 | Pair<L<IfThen>, LS> rulesAndFacts = getRulesAndFacts(); |
131 | c.facts = reversed(rulesAndFacts.b); |
132 | rules = concatLists_conservative(activeTempRules, reversed(rulesAndFacts.a)); // latest rules first! |
133 | rules = [IfThen r : rules | ai_ruleAccessesInput(r.originalText)]; |
134 | c.rules = rules; |
135 | |
136 | while (!posted && now() < cancelTime && nempty(newRewrittenInputs)) { |
137 | fS s = first(newRewrittenInputs); |
138 | rewrittenInputs.add(s); |
139 | newRewrittenInputs.remove(s); |
140 | |
141 | c.input = s; |
142 | c.recentHistory = recentHistory; |
143 | final new L<RuleWithParams> battleSpace; |
144 | |
145 | applyNLLogicFacts_v4_verbose.set(debug); |
146 | applyNLLogicFacts_v4(c, voidfunc(IfThen rule, NLLogicChecker_v2.Matching m) { |
147 | // Rule matches completely, add to battle space |
148 | |
149 | battleSpace.add(new RuleWithParams(rule, m.matches)); |
150 | }, rules); |
151 | |
152 | print("Have " + n2(battleSpace, "possible rule") |
153 | + (empty(battleSpace) ? "" : ": " + joinWithComma(map(func(RuleWithParams r) -> S { r.ruleID() + "/" + toInt(ruleScores.get(r.ruleID())) }, battleSpace)))); |
154 | |
155 | bool all = options.contains("all"); |
156 | if (!all) nlLogic_battleItOut(battleSpace, c.facts); |
157 | |
158 | L<RuleWithParams> winners = all ? battleSpace : nlLogic_highestScore(battleSpace, ruleScores); |
159 | |
160 | fS msgGlobalID = getString(msg, 'globalID); |
161 | //print("msgGlobalID=" + msgGlobalID); |
162 | for (RuleWithParams r : winners) { |
163 | print("Firing rule " + r.rule.globalID); |
164 | |
165 | // Save rule fire |
166 | if (nempty(msgGlobalID) && nempty(r.rule.globalID)) { |
167 | S fact = format("Rule * fired on message * at *", r.rule.globalID, msgGlobalID, localDateWithMilliseconds()); |
168 | if (nempty(r.matches)) |
169 | fact += " with vars " + dropPrefix("lhm", struct(r.matches)); |
170 | print("Saving rule fire. Mech mode: " + mechMode()); |
171 | print(addToMechList("Telegram Rule Fires", print(fact))); |
172 | } |
173 | |
174 | executeRule(c, r); |
175 | } |
176 | |
177 | if (collectCheckingLog) |
178 | print("Checking log length: " + l(checkingLog)); |
179 | } |
180 | } |
181 | |
182 | void executeRule(NLLogicChecker_v3 c, RuleWithParams r) { |
183 | // Execute rule |
184 | for (Exp e : nlLogic_unrollAnd(r.rule.out)) { |
185 | e = c.apply(e, r.matches); |
186 | if (e cast Func) { |
187 | S name = e.name, arg = nlLogic_text(e.arg); |
188 | if (eqOneOf(name, 'output, 'say)) |
189 | postMessage(arg); |
190 | else if (eq(name, 'fact)) { |
191 | S fact = arg; |
192 | if (imagineMode) { |
193 | if (!containsNL(imaginedFacts, fact)) { |
194 | imaginedFacts.add(fact); |
195 | postMessage("Storing imaginary fact: " + fact); |
196 | } |
197 | } else if (!ai_isQuestion_2(fact) && ai_storeActualFact(fact)) |
198 | postMessage("Storing fact: " + fact); |
199 | } else if (eq(name, 'storeRule)) { |
200 | S rule = arg; |
201 | if (!telegram_authorizedToStoreRule(rule)) continue; |
202 | rule = nlLogic_addGlobalID(rule); |
203 | if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule))) |
204 | postMessage("Rule stored"); |
205 | } else if (eq(name, 'imagineMode)) { |
206 | imagineMode = match("true", arg); |
207 | if (!imagineMode) imaginedFacts.clear(); |
208 | } else if (eq(name, 'input)) { |
209 | S x = arg; |
210 | if (!rewrittenInputs.contains(x) && newRewrittenInputs.add(x)) |
211 | print("New rewritten input: " + x); |
212 | } else if (c.checkHelper(e, ai_matchingWrapping(r.matches))) { |
213 | } else |
214 | ret with print("Skipping rule with unknown RHS func: " + e.name); |
215 | } else |
216 | ret with print("Skipping rule with unknown RHS element: " + e); |
217 | } |
218 | } |
219 | } // end class Thinking |
220 | |
221 | Pair<L<IfThen>, LS> getRulesAndFacts() { |
222 | ret ai_activeRulesAndFacts(imagineMode ? asList(imaginedFacts) : null); |
223 | } |
224 | |
225 | void stdCommands(S s) { |
226 | s = trim(s); |
227 | |
228 | final new Matches m; |
229 | S procedure = nlLookup(mechMap("Telegram Procedures"), s, m); |
230 | if (procedure != null) { |
231 | procedure = expandDollarRefsToMatches(procedure, m, true); |
232 | print(">> " + procedure); |
233 | postMessage(strOrNull(javaEvalOrInterpret(procedure))); |
234 | } |
235 | |
236 | print("s=" + s); |
237 | S language = 'english; |
238 | if (swic_trim(s, "!german ", m)) { |
239 | language = 'german; |
240 | s = m.rest(); |
241 | print("s=" + s); |
242 | } |
243 | ai_setLanguage(language); |
244 | |
245 | if (swic_trim(s, "!say ", m)) |
246 | postMessage(m.rest()); |
247 | |
248 | if (eq(s, "!gac")) |
249 | postMessage(random_gac36k()); |
250 | |
251 | if (swic_trim(s, "!parse ", m)) |
252 | postMessage(ai_renderCulledParseTree(ai_parseToTreeWithGuessing(m.rest()))); |
253 | |
254 | if (swic_trim(s, "!simplify ", m)) |
255 | postMessage(lines(ai_parseTree_simplifiedTexts(ai_parseToTreeWithGuessing(m.rest())))); |
256 | |
257 | if (swicOneOf_trim(s, m, "!factsFrom ", "!factsFrom\n")) { |
258 | S x = m.rest(); |
259 | ai_deriveFacts_debug = leadingSquareBracketOptions(x).contains("debug"); |
260 | temp tempSet(NLLogicChecker_v2, staticVerbose := ai_deriveFacts_debug); |
261 | fS _x = dropActuallyLeadingSquareBracketStuff(x); |
262 | postMessage(or2(evalWithTimeout_text(evalTimeout, func { |
263 | lines(ai_factsFromNewFacts(tlft(_x))) |
264 | }), "No new facts found")); |
265 | } |
266 | |
267 | if (swic_trim(s, "!askBack ", m)) { |
268 | NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts()); |
269 | c.input = m.rest(); |
270 | askBack(c); |
271 | } |
272 | |
273 | if (swic_trim(s, "!askBackAboutFact ", m)) { |
274 | NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts()); |
275 | c.facts = listPlus_inFront(c.facts, m.rest()); |
276 | askBack(c); |
277 | } |
278 | |
279 | /*if (telegram_amIAuthorized())*/ { |
280 | if (telegram_amIFullyAuthorized()) { |
281 | bool freshMe = swic_trim(s, "!fresh ", m); |
282 | if (freshMe || eq(s, "!fresh")) { dm_refreshTranspiler(); if (!freshMe) postMessage("OK"); } |
283 | |
284 | if (swic_trim(s, "!eval ", m)) |
285 | postMessage(pcallOrExceptionText(func { strOrNull(javaEvalOrInterpret(m.rest())) })); |
286 | |
287 | if (freshMe || swic_trim(s, "!real-eval ", m)) |
288 | postMessage(evalWithTimeout_text(evalTimeout, func { |
289 | javaEval(m.rest()) |
290 | })); |
291 | } |
292 | |
293 | if (swic_trim(s, "!rule ", m)) { |
294 | S rule = m.rest(); |
295 | if (!telegram_authorizedToStoreRule(rule)) ret; |
296 | LS rules = trimAll(ai_unparsedTalkRules()); |
297 | if (!contains(rules, rule)) { // TODO: ignore global IDs |
298 | rule = nlLogic_addGlobalID(rule); |
299 | appendToMechList_noUniq("NL Logic Examples", "\n" + rule); |
300 | postMessage("Rule saved as " + leadingSquareBracketOptions_id(rule) + ". Have " + n2(l(rules)+1, "rule") + "."); |
301 | } |
302 | } |
303 | |
304 | if (swic_trim(s, "!fact ", m)) { |
305 | S fact = m.rest(); |
306 | LS facts = mL("Random facts"); |
307 | if (!contains(facts, fact)) { |
308 | appendToMechList_noUniq("Random facts", fact); |
309 | postMessage("Fact saved. Have " + n2(l(facts)+1, "fact") + "."); |
310 | } |
311 | } |
312 | |
313 | if (eqic(s, "!deriveFacts")) |
314 | postMessage("Got " + n2(ai_applyFactToFactRules(), "fact") + ". Total: " + l(mL("Derived facts"))); |
315 | |
316 | // end of authorized functions |
317 | } |
318 | } |
319 | |
320 | void askBack(NLLogicChecker_v2 c) { |
321 | L<RuleFailInfo> fails = nlLogic_sortedRuleFails(nlLogic_ruleFails(c, c.rules)); |
322 | print("Have " + n2(fails, "fail")); |
323 | //pnl(fails); |
324 | postMessage(lines(nlLogic_unresolvedFactsToQuestions(fails))); |
325 | } |
Began life as a copy of #1018038
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: | #1018144 |
Snippet name: | Telegram Facts Bot [Include v2 backup] |
Eternal ID of this version: | #1018144/1 |
Text MD5: | a77f60794f9406b1c6cc2e3f6a10dbb4 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-09-02 22:19:26 |
Source code size: | 11425 bytes / 325 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 286 / 291 |
Referenced in: | [show references] |