!7 sS regexpActivator = "."; // always !include once #1017764 // VirtualMechLists sS mechLibID = #1400124; static O onOutput; // VF1 static bool authorized; static L bots; abstract sclass AbstractThinkBot { transient VF1 postMessage; transient new L recentHistory; abstract void thinkAbout(S input); void postMessage(S s) { callF(postMessage, s); } JComponent visualize() { ret jpanel(); } } p { mech_useLibrary(mechLibID); L> classes = botClasses(); print("Have think classes: " + classNames(classes)); makeBots(); bot(); } static L> botClasses() { ret myNonAbstractClassesImplementing(AbstractThinkBot); } svoid makeBots() { bots = map nuWithoutArguments(botClasses()); } sbool telegram_amIAuthorized() { ret authorized; } sS answer(S s) { temp tempSetThreadLocal(telegram_msg_tl(), new Map); final new L output; for (AbstractThinkBot bot : bots) pcall { bot.postMessage = voidfunc(S s) { print(">> " + s); pcallF(onOutput, s); output.add(s); }; bot.thinkAbout(s); } ret rtrim(lines(output)); } svoid setDebug(bool b) { for (O bot : unnull(bots)) setOpt(bot, debug := b); } sclass TelegramThinkBot > AbstractThinkBot { void thinkAbout(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 (telegram_amIAuthorized()) { if (eq(s, "!fresh")) { dm_refreshTranspiler(); postMessage("OK"); } if (swic_trim(s, "!eval ", m)) postMessage(pcallOrExceptionText(func { strOrNull(javaEvalOrInterpret(m.rest())) })); if (swic_trim(s, "!real-eval ", m)) postMessage(pcallOrExceptionText(func { strOrNull(javaEval(m.rest())) })); if (swic_trim(s, "!rule ", m)) { S rule = m.rest(); 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"))); // end of authorized functions } } } sclass TelegramFactsBot > AbstractThinkBot { bool debug; bool imagineMode; bool collectCheckingLog = true; new LinkedHashSet imaginedFacts; LS checkingLog; long processingTime; visualize { ret withCenteredButtons(super.visualize(), "Checking Log", r { showText("Checking Log", lines(checkingLog)) }); } 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, 'telegram_recentHistory_tl) }); S result = str(evalWithDollarVars(code, m.matches)); print("Result: " + shorten(result, 100)); ret result; } void thinkAbout(S s) { time "Processing Time For Message"{ thinkAbout_impl(s); } processingTime = lastTiming(); } void thinkAbout_impl(fS s) { final Map msg = telegram_msg(); NLLogicChecker_v3 c = new NLLogicChecker_v3 { L entities; 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); } }; c.input = s; c.recentHistory = recentHistory; c.evaluator = func(Exp e, NLLogicChecker_v2.Matching m) -> S { evalExp(e, m) }; if (collectCheckingLog) { checkingLog = new L; nlLogic_collectCheckingLog(c, checkingLog); } Pair, LS> rulesAndFacts = getRulesAndFacts(); c.facts = rulesAndFacts.b; L rules = rulesAndFacts.a; final new L battleSpace; applyNLLogicFacts_v4_verbose.set(debug); applyNLLogicFacts_v4(c, voidfunc(IfThen rule, NLLogicChecker_v2.Matching m) { // Rule fired! battleSpace.add(new RuleWithParams(rule, m.matches)); }, rules); print("Have " + n2(battleSpace, "possible rule")); nlLogic_battleItOut(battleSpace); fS msgGlobalID = getString(msg, 'globalID); print("msgGlobalID=" + msgGlobalID); for (RuleWithParams r : battleSpace) { print("Firing rule " + r.rule.globalID); // Save rule fire 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(addToMechList("Telegram Rule Fires", print(fact))); } // Execute rule for (Exp e : nlLogic_unrollAnd(r.rule.out)) { e = c.apply(e, r.matches); if (e cast Func) { S name = e.name; if (eqOneOf(name, 'output, 'say)) postMessage(nlLogic_text(e.arg)); else if (eq(name, 'fact)) { S fact = nlLogic_text(e.arg); if (imagineMode) { if (!containsNL(imaginedFacts, fact)) { imaginedFacts.add(fact); postMessage("Storing imaginary fact: " + fact); } } else if (ai_storeActualFact(fact)) postMessage("Storing fact: " + fact); } else if (eq(name, 'storeRule)) { S rule = nlLogic_text(e.arg); rule = nlLogic_addGlobalID(rule); if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule))) postMessage("Rule stored"); } else if (eq(name, 'imagineMode)) { imagineMode = match("true", nlLogic_text(e.arg)); if (!imagineMode) imaginedFacts.clear(); } } } } if (collectCheckingLog) print("Checking log length: " + l(checkingLog)); } Pair, LS> getRulesAndFacts() { LS facts = imagineMode ? concatLists(imaginedFacts, mL_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 facts.add(x); unparsedRules = sortedByCalculatedField(unparsedRules, func(S s) { jcontains(s, "entity(") }); L rules = map_pcall nlLogic_parseRule(unparsedRules); for (S listName : mL("Default active scripts")) addAll(rules, nlLogic_loadMechScript(listName)); nlLogic_expandMacros(rules); ret pair(rules, facts); } } sclass TelegramInitiativeBot > AbstractThinkBot { new L> activeTempRules; void thinkAbout(S s) { if (eq(s, "!initiative")) { L rules = mL_parsedNLRulesWithoutIDs("Initiative rules"); for (IfThen rule : shuffledIterator(rules)) { Pair 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); print("Have temp rule: " + sfu(temp)); activeTempRules.add(pair(aGlobalID(), temp)); ret; } } } applyNLLogicFacts_v2(s, voidfunc(S s) { postMessage(s) }, new L, activeTempRules); activeTempRules.clear(); } }