bool debug; bool imagineMode; bool collectCheckingLog = true; new LinkedHashSet<S> imaginedFacts; LS checkingLog; long processingTime; new L<IfThen> activeTempRules; int evalTimeout = 20000; bool useIterate; // full iterate mode for normal rule checking O standardGrouper; // grouping function for all input *() { please include function parse3_cachedPattern. please include function parse3_cachedInput. setMaxSizeOfMRUCache(parse3_cachedPattern_cache, 10000); setMaxSizeOfMRUCache(parse3_cachedInput_cache, 10000); } void thinkAbout(S s) { time "Processing Time For Message"{ thinkAbout_impl(s); } processingTime = lastTiming(); } void thinkAbout_impl(fS input) { final new Thinking t; final Map<S, O> tl = getMCThreadLocals(ai_staticVars()); /*Thread thread = startThread("Think!", r { setMCThreadLocals(tl);*/ t.thinkAbout(input); /*});*/ int n = 0; do { while (l(t.output) > n) postMessage(t.output.get(n++)); //joinThread(thread, 50); } while (!t.done); activeTempRules.clear(); } void _postMessage(S s) { postMessage(s); } class Thinking { long cancelTime = now()+20000; new Map<S, Int> ruleScores; volatile bool posted, done; new L<IfThen> rules; replace Plan with PlanInMotion. new Plan<Runnable> plan; new HashSet<S> outputSet; LS output = synchroList(); void postMessage(S s) { //_postMessage(s); if (outputSet.add(s)) output.add(s); posted = true; } void done() { done = true; } void thinkAbout(S input) { try { thinkAbout_impl(input); } finally { done(); } } void thinkAbout_impl(fS input0) { fS input1 = unixLineBreaks(input0); plan.add(r "!initiative" { if (!eq(input1, "!initiative")) ret; L<IfThen> rules = mL_parsedNLRulesWithoutIDs("Initiative rules"); for (IfThen rule : shuffledIterator(rules)) { Pair<Exp> p = nlLogic_extractFirstCondition(rule.in); if (p == null) continue; if (nlLogic_isFunc(p.a, 'initiative)) { postMessage(nlLogic_text(((Func) p.a).arg)); IfThen temp = IfThen(p.b, rule.out); temp.globalID = aGlobalID(); print("Have temp rule: " + sfu(temp)); activeTempRules.add(temp); ret with done(); } } ret with done(); }); plan.add(r "!step" { new Matches mm; if (!startsWith_trim(input1, "!step ", mm)) ret; // TODO }); runPlanWithCheck(plan, func -> bool { !done }); if (done) ret; stdCommands(input1); S input2 = input1; final new LS options; if (startsWith(input2, "[")) { addAll(options, leadingSquareBracketOptions(input2)); input2 = dropLeadingSquareBracketStuff(input2); } fS input = callFOrKeep(standardGrouper, input2); ai_tg_collectRuleFeedback(ruleScores, null); final NLLogicChecker_v3 c = new NLLogicChecker_v3 { bool checkExpression_impl(Exp e, Matching m) { if (e instanceof Literal) { // TEXT CONDITIONS S text = nlLogic_text(e); if (eq(text, "authorized")) ret telegram_amIAuthorized(); else if(eq(text, "imagineMode")) ret imagineMode; } ret super.checkExpression_impl(e, m); } }; if (collectCheckingLog) { checkingLog = new L; nlLogic_collectCheckingLog(c, checkingLog); } Pair<L<IfThen>, LS> rulesAndFacts = getRulesAndFacts(); NLLogic_MultiThreadedEngine engine = new(rulesAndFacts); engine.unsafeEvals = true; // TODO: make sure we don't eval deep into some weird computation engine.showFailed = false; engine.makeLogicChecker = func -> NLLogicChecker_v2 { new NLLogicChecker_v2 c; c.recentHistory = recentHistory; c.useIterate = useIterate; ret c; }; engine.seedInput(input); engine.fullRun(); ExecutedRule winner = first(engine.executedRules()); if (winner != null) fireRule(assertNotNull("logic checker", winner.logicChecker), winner.rule); if (collectCheckingLog) print("Checking log length: " + l(checkingLog)); } void fireRule(NLLogicChecker_v2 c, RuleWithParams r) { print("Firing rule " + r.rule.globalID); // Save rule fire fS msgGlobalID = getString(telegram_msg(), 'globalID); if (nempty(msgGlobalID) && nempty(r.rule.globalID)) { S fact = format("Rule * fired on message * at *", r.rule.globalID, msgGlobalID, localDateWithMilliseconds()); if (nempty(r.matches)) fact += " with vars " + dropPrefix("lhm", struct(r.matches)); print("Saving rule fire. Mech mode: " + mechMode()); print(addToMechList("Telegram Rule Fires", print(fact))); } executeRule(c, r, this); } } // end class Thinking void executeRule(NLLogicChecker_v2 c, RuleWithParams r, Thinking t) { // Execute rule for (Exp e : nlLogic_unrollAnd(r.rule.out)) { e = c.apply(e, r.matches); if (e cast Func) { S name = e.name, arg = nlLogic_text(e.arg); if (eqOneOf(name, 'output, 'say)) t.postMessage(arg); else if (eq(name, 'fact)) { S fact = arg; if (imagineMode) { if (!containsNL(imaginedFacts, fact)) { imaginedFacts.add(fact); t.postMessage("Storing imaginary fact: " + fact); } } else if (!ai_isQuestion_2(fact) && ai_storeActualFact(fact)) t.postMessage("Storing fact: " + fact); } else if (eq(name, 'storeRule)) { S rule = arg; if (!telegram_authorizedToStoreRule(rule)) continue; rule = nlLogic_addGlobalID(rule); if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule))) t.postMessage("Rule stored"); } else if (eq(name, 'imagineMode)) { imagineMode = match("true", arg); if (!imagineMode) imaginedFacts.clear(); } /*else if (eq(name, 'input)) { S x = arg; if (!t.rewrittenInputs.contains(x) && t.newRewrittenInputs.add(x)) print("New rewritten input: " + x); } */ else if (c.checkHelper(e, ai_matchingWrapping(r.matches))) { } else ret with print("Skipping rule with unknown RHS func: " + e.name); } else ret with print("Skipping rule with unknown RHS element: " + e); } } Pair<L<IfThen>, LS> getRulesAndFacts() { Pair<L<IfThen>, LS> p = ai_activeRulesAndFacts(imagineMode ? asList(imaginedFacts) : null); if (debug) print("getRulesAndFacts: " + n2(p.a, "rule")); ret p; } void stdCommands(S s) { s = trim(s); final new Matches m; S procedure = nlLookup(mechMap("Telegram Procedures"), s, m); if (procedure != null) { procedure = expandDollarRefsToMatches(procedure, m, true); print(">> " + procedure); postMessage(strOrNull(javaEvalOrInterpret(procedure))); } print("s=" + s); S language = 'english; if (swic_trim(s, "!german ", m)) { language = 'german; s = m.rest(); print("s=" + s); } ai_setLanguage(language); if (swic_trim(s, "!say ", m)) postMessage(m.rest()); if (eq(s, "!gac")) postMessage(random_gac36k()); if (swic_trim(s, "!parse ", m)) postMessage(ai_renderCulledParseTree(ai_parseToTreeWithGuessing(m.rest()))); if (swic_trim(s, "!simplify ", m)) postMessage(lines(ai_parseTree_simplifiedTexts(ai_parseToTreeWithGuessing(m.rest())))); if (swicOneOf_trim(s, m, "!factsFrom ", "!factsFrom\n")) { S x = m.rest(); ai_deriveFacts_debug = leadingSquareBracketOptions(x).contains("debug"); temp tempSet(NLLogicChecker_v2, staticVerbose := ai_deriveFacts_debug); fS _x = dropActuallyLeadingSquareBracketStuff(x); postMessage(or2(evalWithTimeout_text(evalTimeout, func { lines(ai_factsFromNewFacts(tlft(_x))) }), "No new facts found")); } if (swic_trim(s, "!askBack ", m)) { NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts()); c.input = m.rest(); askBack(c); } if (swic_trim(s, "!askBackAboutFact ", m)) { NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts()); c.facts = listPlus_inFront(c.facts, m.rest()); askBack(c); } /*if (telegram_amIAuthorized())*/ { if (telegram_amIFullyAuthorized()) { if (eq(s, "!reload")) { if (!hasFunctionNamed(mc(), 'dm_reloadMe)) postMessage("Not a module"); else { postMessage("OK, reloading."); doAfter(1000, 'dm_reloadMe); ret; } } bool freshMe = swic_trim(s, "!fresh ", m); if (freshMe || eq(s, "!fresh")) { dm_refreshTranspiler(); if (!freshMe) postMessage("OK"); } if (swic_trim(s, "!eval ", m)) postMessage(pcallOrExceptionText(func { strOrNull(javaEvalOrInterpret(m.rest())) })); if (freshMe || swic_trim(s, "!real-eval ", m)) postMessage(evalWithTimeout_text(evalTimeout, func { javaEval(m.rest()) })); } if (swic_trim(s, "!rule ", m)) { S rule = m.rest(); if (!telegram_authorizedToStoreRule(rule)) ret; LS rules = trimAll(ai_unparsedTalkRules()); if (!contains(rules, rule)) { // TODO: ignore global IDs rule = nlLogic_addGlobalID(rule); appendToMechList_noUniq("NL Logic Examples", "\n" + rule); postMessage("Rule saved as " + leadingSquareBracketOptions_id(rule) + ". Have " + n2(l(rules)+1, "rule") + "."); } } if (swic_trim(s, "!fact ", m)) { S fact = m.rest(); LS facts = mL("Random facts"); if (!contains(facts, fact)) { appendToMechList_noUniq("Random facts", fact); postMessage("Fact saved. Have " + n2(l(facts)+1, "fact") + "."); } } if (eqic(s, "!deriveFacts")) postMessage("Got " + n2(ai_applyFactToFactRules(), "fact") + ". Total: " + l(mL("Derived facts"))); if (eqic(s, "!groupFacts")) if (standardGrouper != null) { appendToMechList("Derived facts", map(standardGrouper, ai_facts())); postMessage("OK"); } if (eqic(s, "!imaginaryFacts")) { Pair<L<IfThen>, LS> rulesAndFacts = getRulesAndFacts(); LS facts = reversed(rulesAndFacts.b); L<IfThen> rules = concatLists_conservative(activeTempRules, reversed(rulesAndFacts.a)); // latest rules first! final Set<S> toDrop = asHashSet(matchAll_first("$x is not a general chat rule", facts)); rules = [IfThen r : rules | !toDrop.contains(r.globalID) && !ai_ruleAccessesInput(r)]; print("Deriving from " + n2(rules, "rule") + " and " + n2(facts, "fact")); set ai_deriveFacts_debug; Set<S> newFacts = ai_deriveFacts(rules, facts); newFacts = setMinusSet(newFacts, facts); imaginedFacts.addAll(newFacts); postMessage("Got " + n2(newFacts, "imaginary fact") + ". Total: " + l(imaginedFacts)); } // end of authorized functions } } void askBack(NLLogicChecker_v2 c) { L<RuleFailInfo> fails = nlLogic_sortedRuleFails(nlLogic_ruleFails(c, c.rules)); print("Have " + n2(fails, "fail")); //pnl(fails); postMessage(lines(nlLogic_unresolvedFactsToQuestions(fails))); }
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: | #1018379 |
Snippet name: | Telegram Facts Bot [Include v3, using new multi-threaded engine, dev.] |
Eternal ID of this version: | #1018379/11 |
Text MD5: | d43a0a8c009f44fae617b483494b1b40 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-09-23 18:48:16 |
Source code size: | 12278 bytes / 351 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 353 / 663 |
Version history: | 10 change(s) |
Referenced in: | #1018381 - Baked Bot, new version (auto-generated, don't edit, see #1017703) #1018382 - Telegram Facts Bot v7 [new engine, dev.] |