bool debug; bool imagineMode; bool collectCheckingLog = true; new LinkedHashSet imaginedFacts; LS checkingLog; long processingTime; new L activeTempRules; int evalTimeout = 20000; 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 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 ruleScores; new LinkedHashSet rewrittenInputs; new LinkedHashSet newRewrittenInputs; volatile bool posted, done; new L rules; replace Plan with PlanInMotion. new Plan plan; new HashSet 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 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); 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 = input2; ai_tg_collectRuleFeedback(ruleScores, null); newRewrittenInputs.add(input); final Map msg = telegram_msg(); 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, LS> rulesAndFacts = getRulesAndFacts(); c.facts = reversed(rulesAndFacts.b); rules = concatLists_conservative(activeTempRules, reversed(rulesAndFacts.a)); // latest rules first! rules = [IfThen r : rules | ai_ruleAccessesInput(r.originalText)]; c.rules = rules; while (!posted && now() < cancelTime && nempty(newRewrittenInputs)) { fS s = first(newRewrittenInputs); rewrittenInputs.add(s); newRewrittenInputs.remove(s); c.input = s; c.recentHistory = recentHistory; final new L battleSpace; applyNLLogicFacts_v4_verbose.set(debug); applyNLLogicFacts_v4(c, voidfunc(IfThen rule, NLLogicChecker_v2.Matching m) { // Rule matches completely, add to battle space battleSpace.add(new RuleWithParams(rule, m.matches)); }, rules); print("Have " + n2(battleSpace, "possible rule") + (empty(battleSpace) ? "" : ": " + joinWithComma(map(func(RuleWithParams r) -> S { r.ruleID() + "/" + toInt(ruleScores.get(r.ruleID())) }, battleSpace)))); bool all = options.contains("all"); if (!all) nlLogic_battleItOut(battleSpace, c.facts); L winners = all ? battleSpace : nlLogic_highestScore(battleSpace, ruleScores); fS msgGlobalID = getString(msg, 'globalID); //print("msgGlobalID=" + msgGlobalID); for (RuleWithParams r : winners) { 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("Saving rule fire. Mech mode: " + mechMode()); print(addToMechList("Telegram Rule Fires", print(fact))); } executeRule(c, r); } if (collectCheckingLog) print("Checking log length: " + l(checkingLog)); } } void executeRule(NLLogicChecker_v3 c, RuleWithParams r) { // 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)) postMessage(arg); else if (eq(name, 'fact)) { S fact = arg; if (imagineMode) { if (!containsNL(imaginedFacts, fact)) { imaginedFacts.add(fact); postMessage("Storing imaginary fact: " + fact); } } else if (!ai_isQuestion_2(fact) && ai_storeActualFact(fact)) 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))) 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 (!rewrittenInputs.contains(x) && 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); } } } // end class Thinking Pair, LS> getRulesAndFacts() { ret ai_activeRulesAndFacts(imagineMode ? asList(imaginedFacts) : null); } 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()) { 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"))); // end of authorized functions } } void askBack(NLLogicChecker_v2 c) { L fails = nlLogic_sortedRuleFails(nlLogic_ruleFails(c, c.rules)); print("Have " + n2(fails, "fail")); //pnl(fails); postMessage(lines(nlLogic_unresolvedFactsToQuestions(fails))); }