!7 set flag DynModule. sclass TelegramFactsBot > AbstractTelegramThinkBot { S evalExp(Exp e, NLLogicChecker_v2.Matching m) { S code = nlLogic_text(e); print("Eval'ing: " + code); temp tempAdd(hotwire_copyOver_after, voidfunc(Class c) { copyFields(mc(), c, 'telegram_msg_tl) }); S result = str(evalWithDollarVars(code, m.matches)); print("Result: " + shorten(result, 100)); ret result; } void thinkAbout(fS s) { final Map msg = telegram_msg(); NLLogicChecker_v2 c = new NLLogicChecker_v2 { L entities; bool checkExpression(Exp e, Matching m) { new Matches mm; if (e cast Func) { // FUNCTION CONDITIONS if (eq(e.name, "verbPhraseFromThirdPerson")) ret nlLogic_stringFunction(f ai_verbPhraseFromThirdPerson, e, m.matches); else if (eq(e.name, "singular")) ret nlLogic_stringFunction(f singular, e, m.matches); else if (eq(e.name, 'eval)) ret eq("true", evalExp(e.arg, m)); else if (eq(e.name, 'entity)) { if (entities == null) { long time = sysNow(); fS switched = switcheroo(s); print("Switched >> " + switched); entities = evalWithTimeoutOrNull(5000, func -> LS { mapMethod('text, ai_extractEntities_v1(switched)) }); print("Entities (" + elapsedMS(time) + " ms): " + joinWithComma(entities)); if (entities == null) entities = new L; } for (S entity : entities) if (matcher.match(nlLogic_text(e.arg), entity, m.matches)) true; } else if (startsWith(e.name, "line", mm) && isInteger(mm.rest())) { int n = parseInt(mm.rest())-nlLogic_numberOfLinesReferenced(checkingRule->in); S line = n == 0 ? s : getString(get(recentHistory, l(recentHistory)+n), 'text); print("Recent: " + recentHistory); S pat = nlLogic_text(e.arg); print("n=" + n + ", Matching " + e + " with " + line); ret matcher.match(pat, line, m.matches); } else if (eq(e.name, 'unknownIf)) { S statement = nlLogic_text(apply(e.arg, m)); print("Checking statement: " + statement); ret !cic(facts, statement) && !cic(facts, "Untrue: " + statement); } else if (eq(e.name, 'inputContainsTokens)) ret call_verbose jcontains(s, nlLogic_text(e.arg)); else if (eq(e.name, 'inputStartsWith)) ret call_verbose startsWith(s, nlLogic_text(e.arg)); else if (eq(e.name, 'followingUpOn)) { S text = nlLogic_text(e.arg); // e.g. "lhnshnhcklhabvmu with input=$input" if (!match("* with input=*", text, mm) || !isDollarVar(mm.get(1))) false; S ruleID = mm.unq(0), dollarInput = mm.get(1); Map /*prev = last(recentHistory),*/ prevPrev = nextToLast(recentHistory); S msgID = getString(prevPrev, 'globalID); S input = getString(prevPrev, 'text); print("followingUpOn: msgID=" + msgID + ", input=" + input); printStruct(+prevPrev); //printStruct(+prev); S pat = "Rule " + ruleID + " fired on message " + msgID + " "; print("pat=" + pat); for (S ruleFired : mL("Telegram Rule Fires")) if (swic(ruleFired, pat)) ret print("result=", strictPutIC(m.matches, dollarInput, input)); false; } } if (e cast Eq) { // EQUATION CONDITIONS Exp r = e.right; S var = nlLogic_text(e.left); if (r cast Func) pcall { if (eq(r.name, 'eval)) ret new NLStringMatcher_singleDollarVar().match(var, evalExp(r.arg, m), m.matches); } } if (e instanceof Literal) { // TEXT CONDITIONS S text = nlLogic_text(e); if (eq(text, "authorized")) ret telegram_amIAuthorized(); } ret super.checkExpression(e, m); } }; c.matcher = new NLStringMatcher_dollarVars_underscores; c.input = s; c.facts = mL_facts(); LS unparsedRules = ai_unparsedTalkRules(); for (S listName : mL("Rule & Fact Lists")) for (S x : splitAtEmptyLines(mL_raw(listName))) if (anyJavaTokens(x)) if (nlLogic_parseRule(x) != null) unparsedRules.add(x); else c.facts.add(x); unparsedRules = sortedByCalculatedField(unparsedRules, func(S s) { jcontains(s, "entity(") }); L rules = map_pcall nlLogic_parseRule(unparsedRules); for (IfThen r : rules) { continue if r == null; Exp out = r.out; if (out cast Func) if (eq(out.name, "sayIfTrue")) { r.out = Func('output, out.arg); r.in = And(r.in, Func('fact, out.arg)); print(r); } } fS msgGlobalID = getString(msg, 'globalID); if (nempty(msgGlobalID)) applyNLLogicFacts_v3_onRuleFired.set(voidfunc(IfThen rule, NLLogicChecker_v2.Matching m) { if (empty(rule.globalID)) ret; S fact = format("Rule * fired on message * at *", rule.globalID, msgGlobalID, localDateWithMilliseconds()); if (nempty(m.matches)) fact += " with vars " + dropPrefix("lhm", struct(m.matches)); addToMechList("Telegram Rule Fires", fact); }); applyNLLogicFacts_v3(c, voidfunc(Exp e) { // Rule fired! if (e cast Func) { if (eq(e.name, 'output)) postMessage(nlLogic_text(e.arg)); else if (eq(e.name, 'fact)) { S fact = nlLogic_text(e.arg); if (!contains(mL("Random facts"), fact) && mech_changed(addToMechList("Derived facts", fact))) postMessage("Storing fact: " + fact); } else if (eq(e.name, 'storeRule)) { S rule = nlLogic_text(e.arg); if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule))) postMessage("Rule stored"); } } }, rules); } }