Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

382
LINES

< > BotCompany Repo | #1018038 // Telegram Facts Bot [Include v2]

JavaX fragment (include)

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  
  bool useIterate; // full iterate mode for normal rule checking
10  
  O standardGrouper; // grouping function for all input
11  
  S ruleFired, lastRuleFired;
12  
  
13  
  *() {
14  
    please include function parse3_cachedPattern.
15  
    please include function parse3_cachedInput.
16  
    setMaxSizeOfMRUCache(parse3_cachedPattern_cache, 10000);
17  
    setMaxSizeOfMRUCache(parse3_cachedInput_cache, 10000);
18  
  }
19  
  
20  
  void thinkAbout(S s) {
21  
    time "Processing Time For Message"{
22  
      thinkAbout_impl(s);
23  
    }
24  
    processingTime = lastTiming();
25  
  }
26  
  
27  
  void thinkAbout_impl(fS input) {
28  
    final new Thinking t;
29  
    final Map<S, O> tl = getMCThreadLocals(ai_staticVars());
30  
    /*Thread thread = startThread("Think!", r {
31  
      setMCThreadLocals(tl);*/
32  
      t.thinkAbout(input);
33  
    /*});*/
34  
    int n = 0;
35  
    do {
36  
      while (l(t.output) > n)
37  
        postMessage(t.output.get(n++));
38  
      //joinThread(thread, 50);
39  
    } while (!t.done);
40  
    
41  
    activeTempRules.clear();
42  
    lastRuleFired = ruleFired;
43  
    //print("lastRuleFired := " + lastRuleFired);
44  
    /*if (lastRuleFired != null) {
45  
      lastRuleFired = null;
46  
      print("lastRuleFired := null");
47  
    }*/
48  
  }
49  
  
50  
  void _postMessage(S s) { postMessage(s); }
51  
  
52  
  class Thinking {
53  
    long cancelTime = now()+20000;
54  
    new Map<S, Int> ruleScores;
55  
    new LinkedHashSet<S> rewrittenInputs;
56  
    new LinkedHashSet<S> newRewrittenInputs;
57  
    volatile bool posted, done;
58  
    new L<IfThen> rules;
59  
    replace Plan with PlanInMotion.
60  
    new Plan<Runnable> plan;
61  
    new HashSet<S> outputSet;
62  
    LS output = synchroList();
63  
64  
    void postMessage(S s) {
65  
      //_postMessage(s);
66  
      if (outputSet.add(s))
67  
        output.add(s);
68  
      posted = true;
69  
    }
70  
    
71  
    void done() { done = true; }
72  
    
73  
    void thinkAbout(S input) {
74  
      try {
75  
        thinkAbout_impl(input);
76  
      } finally {
77  
        done();
78  
      }
79  
    }
80  
    
81  
    void thinkAbout_impl(fS input0) {
82  
      if (ruleFired != null) {
83  
        ruleFired = null;
84  
        //print("ruleFired := null");
85  
      }
86  
      fS input1 = unixLineBreaks(input0);
87  
      plan.add(r "!initiative" {
88  
        if (!eq(input1, "!initiative")) ret;
89  
        L<IfThen> rules = mL_parsedNLRulesWithoutIDs("Initiative rules");
90  
        for (IfThen rule : shuffledIterator(rules)) {
91  
          Pair<Exp> p = nlLogic_extractFirstCondition(rule.in);
92  
          if (p == null) continue;
93  
          if (nlLogic_isFunc(p.a, 'initiative)) {
94  
            postMessage(nlLogic_text(((Func) p.a).arg));
95  
            IfThen temp = IfThen(p.b, rule.out);
96  
            temp.globalID = aGlobalID();
97  
            print("Have temp rule: " + sfu(temp));
98  
            activeTempRules.add(temp);
99  
            ret with done();
100  
          }
101  
        }
102  
        ret with done();
103  
      });
104  
      
105  
      plan.add(r "!step" {
106  
        new Matches mm;
107  
        if (!startsWith_trim(input1, "!step ", mm)) ret;
108  
        // TODO
109  
      });
110  
      
111  
      runPlanWithCheck(plan, func -> bool { !done });
112  
      if (done) ret;
113  
      
114  
      stdCommands(input1);
115  
      
116  
      S input2 = input1;
117  
      final new LS options;
118  
      if (startsWith(input2, "[")) {
119  
        addAll(options, leadingSquareBracketOptions(input2));
120  
        input2 = dropLeadingSquareBracketStuff(input2);
121  
      }
122  
      
123  
      fS input = callFOrKeep(standardGrouper, input2);
124  
      ai_tg_collectRuleFeedback(ruleScores, null);
125  
      
126  
      newRewrittenInputs.add(input);
127  
      final Map msg = telegram_msg();
128  
      
129  
      final NLLogicChecker_v3 c = new NLLogicChecker_v3 {
130  
        bool checkExpression_impl(Exp e, Matching m) {
131  
          if (e instanceof Literal) {
132  
            // TEXT CONDITIONS
133  
            
134  
            S text = nlLogic_text(e);
135  
            if (eq(text, "authorized"))
136  
              ret telegram_amIAuthorized();
137  
            else if(eq(text, "imagineMode"))
138  
              ret imagineMode;
139  
          }
140  
          
141  
          ret super.checkExpression_impl(e, m);
142  
        }
143  
      };
144  
      c.followingUpOn = lastRuleFired;
145  
146  
      if (collectCheckingLog) {
147  
        checkingLog = new L;
148  
        nlLogic_collectCheckingLog(c, checkingLog);
149  
      }
150  
      
151  
      Pair<L<IfThen>, LS> rulesAndFacts = getRulesAndFacts();
152  
      c.facts = reversed(rulesAndFacts.b);
153  
      rules = concatLists_conservative(activeTempRules, reversed(rulesAndFacts.a)); // latest rules first!
154  
      final Set<S> toDrop = asHashSet(matchAll_first("$x is not a general chat rule", c.facts));
155  
      rules = [IfThen r : rules | !toDrop.contains(r.globalID)
156  
        && ai_ruleAccessesInput(r)];
157  
      c.rules = rules;
158  
159  
      while (!posted && now() < cancelTime && nempty(newRewrittenInputs)) {
160  
        fS s = first(newRewrittenInputs);
161  
        rewrittenInputs.add(s);
162  
        newRewrittenInputs.remove(s);
163  
        
164  
        c.input = s;
165  
        c.recentHistory = recentHistory;
166  
        c.useIterate = useIterate;
167  
        
168  
        final new L<RuleWithParams> battleSpace;
169  
        
170  
        nlLogic_fillBattleSpace(c, battleSpace, debug);
171  
        
172  
        print("Have " + n2(battleSpace, "possible rule")
173  
          + (empty(battleSpace) ? "" : ": " + joinWithComma(map(func(RuleWithParams r) -> S { r.ruleID() + "/" + toInt(ruleScores.get(r.ruleID())) }, battleSpace))));
174  
        
175  
        bool all = options.contains("all");
176  
        if (!all) nlLogic_battleItOut(battleSpace, c.facts);
177  
        
178  
        L<RuleWithParams> winners = all ? battleSpace : nlLogic_highestScore(battleSpace, ruleScores);
179  
    
180  
        fS msgGlobalID = getString(msg, 'globalID);
181  
        //print("msgGlobalID=" + msgGlobalID);
182  
        for (RuleWithParams r : winners) {
183  
          print("Firing rule " + r.rule.globalID);
184  
          
185  
          // Save rule fire
186  
          ruleFired = r.rule.globalID;
187  
          if (nempty(msgGlobalID) && nempty(r.rule.globalID)) {
188  
            S fact = format("Rule * fired on message * at *", r.rule.globalID, msgGlobalID, localDateWithMilliseconds());
189  
             if (nempty(r.matches))
190  
               fact += " with vars " + dropPrefix("lhm", struct(r.matches));
191  
            print("Saving rule fire. Mech mode: " + mechMode());
192  
            print(addToMechList("Telegram Rule Fires", print(fact)));
193  
          }
194  
          
195  
          executeRule(c, r, this);
196  
        }
197  
        
198  
        if (collectCheckingLog)
199  
          print("Checking log length: " + l(checkingLog));
200  
      }
201  
    }
202  
  } // end class Thinking
203  
204  
  void executeRule(NLLogicChecker_v3 c, RuleWithParams r, Thinking t) {
205  
    // Execute rule
206  
    for (Exp e : nlLogic_unrollAnd(r.rule.out)) {
207  
      e = c.apply(e, r.matches);
208  
      if (e cast Func) {
209  
        S name = e.name, arg = nlLogic_text(e.arg);
210  
        if (eqOneOf(name, 'output, 'say))
211  
          t.postMessage(arg);
212  
        else if (eq(name, 'fact)) {
213  
          S fact = arg;
214  
          if (imagineMode) {
215  
            if (!containsNL(imaginedFacts, fact)) {
216  
              imaginedFacts.add(fact);
217  
              t.postMessage("Storing imaginary fact: " + fact);
218  
            }
219  
          } else if (!ai_isQuestion_2(fact) && ai_storeActualFact(fact))
220  
            t.postMessage("Storing fact: " + fact);
221  
        } else if (eq(name, 'storeRule)) {
222  
          S rule = arg;
223  
          if (!telegram_authorizedToStoreRule(rule)) continue;
224  
          rule = nlLogic_addGlobalID(rule);
225  
          if (mech_changed(appendToMechList_noUniq("NL Logic Examples", "\n" + rule)))
226  
            t.postMessage("Rule stored");
227  
        } else if (eq(name, 'imagineMode)) {
228  
          imagineMode = match("true", arg);
229  
          if (!imagineMode) imaginedFacts.clear();
230  
        } else if (eq(name, 'input)) {
231  
          S x = arg;
232  
          if (!t.rewrittenInputs.contains(x) && t.newRewrittenInputs.add(x))
233  
            print("New rewritten input: " + x);
234  
        } else if (c.checkHelper(e, ai_matchingWrapping(r.matches))) {
235  
        } else
236  
          ret with print("Skipping rule with unknown RHS func: " + e.name);
237  
      } else
238  
        ret with print("Skipping rule with unknown RHS element: " + e);
239  
    }
240  
  }
241  
 
242  
  Pair<L<IfThen>, LS> getRulesAndFacts() { 
243  
    Pair<L<IfThen>, LS> p = ai_activeRulesAndFacts(imagineMode ? asList(imaginedFacts) : null);
244  
    if (debug)
245  
      print("getRulesAndFacts: " + n2(p.a, "rule"));
246  
    ret p;
247  
  }
248  
249  
  void stdCommands(S s) {
250  
    s = trim(s);
251  
    
252  
    final new Matches m;
253  
    S procedure = nlLookup(mechMap("Telegram Procedures"), s, m);
254  
    if (procedure != null) {
255  
      procedure = expandDollarRefsToMatches(procedure, m, true);
256  
      print(">> " + procedure);
257  
      postMessage(strOrNull(javaEvalOrInterpret(procedure)));
258  
    }
259  
    
260  
    print("s=" + s);
261  
    S language = 'english;
262  
    if (swic_trim(s, "!german ", m)) {
263  
      language = 'german;
264  
      s = m.rest();
265  
      print("s=" + s);
266  
    }
267  
    ai_setLanguage(language);
268  
269  
    if (swic_trim(s, "!say ", m))
270  
      postMessage(m.rest());
271  
    
272  
    if (eq(s, "!gac"))
273  
      postMessage(random_gac36k());
274  
    
275  
    if (swic_trim(s, "!parse ", m))
276  
      postMessage(ai_renderCulledParseTree(ai_parseToTreeWithGuessing(m.rest())));
277  
    
278  
    if (swic_trim(s, "!simplify ", m))
279  
      postMessage(lines(ai_parseTree_simplifiedTexts(ai_parseToTreeWithGuessing(m.rest()))));
280  
      
281  
    if (swicOneOf_trim(s, m, "!factsFrom ", "!factsFrom\n")) {
282  
      S x = m.rest();
283  
      ai_deriveFacts_debug = leadingSquareBracketOptions(x).contains("debug");
284  
      temp tempSet(NLLogicChecker_v2, staticVerbose := ai_deriveFacts_debug);
285  
      fS _x = dropActuallyLeadingSquareBracketStuff(x);
286  
      postMessage(or2(evalWithTimeout_text(evalTimeout, func {
287  
        lines(ai_factsFromNewFacts(tlft(_x)))
288  
      }), "No new facts found"));
289  
    }
290  
    
291  
    if (swic_trim(s, "!askBack ", m)) {
292  
      NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts());
293  
      c.input = m.rest();
294  
      askBack(c);
295  
    }
296  
297  
    if (swic_trim(s, "!askBackAboutFact ", m)) {
298  
      NLLogicChecker_v2 c = nlLogicCheckerWithRulesAndFacts(getRulesAndFacts());
299  
      c.facts = listPlus_inFront(c.facts, m.rest());
300  
      askBack(c);
301  
    }
302  
303  
    /*if (telegram_amIAuthorized())*/ {
304  
      if (telegram_amIFullyAuthorized()) {
305  
        if (eq(s, "!reload")) {
306  
          if (!hasFunctionNamed(mc(), 'dm_reloadMe))
307  
            postMessage("Not a module");
308  
          else {
309  
            postMessage("OK, reloading.");
310  
            doAfter(1000, 'dm_reloadMe);
311  
            ret;
312  
          }
313  
        }
314  
          
315  
        bool freshMe = swic_trim(s, "!fresh ", m);
316  
        if (freshMe || eq(s, "!fresh")) { dm_refreshTranspiler(); if (!freshMe) postMessage("OK"); }
317  
      
318  
        if (swic_trim(s, "!eval ", m))
319  
          postMessage(pcallOrExceptionText(func { strOrNull(javaEvalOrInterpret(m.rest())) }));
320  
        
321  
        if (freshMe || swic_trim(s, "!real-eval ", m))
322  
          postMessage(evalWithTimeout_text(evalTimeout, func {
323  
            javaEval(m.rest())
324  
          }));
325  
      }
326  
        
327  
      if (swic_trim(s, "!rule ", m)) {
328  
        S rule = m.rest();
329  
        if (!telegram_authorizedToStoreRule(rule)) ret;
330  
        LS rules = trimAll(ai_unparsedTalkRules());
331  
        if (!contains(rules, rule)) { // TODO: ignore global IDs
332  
          rule = nlLogic_addGlobalID(rule);
333  
          appendToMechList_noUniq("NL Logic Examples", "\n" + rule);
334  
          postMessage("Rule saved as " + leadingSquareBracketOptions_id(rule) + ". Have " + n2(l(rules)+1, "rule") + ".");
335  
        }
336  
      }
337  
      
338  
      if (swic_trim(s, "!fact ", m)) {
339  
        S fact = m.rest();
340  
        LS facts = mL("Random facts");
341  
        if (!contains(facts, fact)) {
342  
          appendToMechList_noUniq("Random facts", fact);
343  
          postMessage("Fact saved. Have " + n2(l(facts)+1, "fact") + ".");
344  
        }
345  
      }
346  
      
347  
      if (eqic(s, "!deriveFacts"))
348  
        postMessage("Got " + n2(ai_applyFactToFactRules(), "fact") + ". Total: " + l(mL("Derived facts")));
349  
        
350  
      if (eqic(s, "!groupFacts"))
351  
        if (standardGrouper != null) {
352  
          appendToMechList("Derived facts", map(standardGrouper, ai_facts()));
353  
          postMessage("OK");
354  
        }
355  
356  
      if (eqic(s, "!imaginaryFacts")) {
357  
        Pair<L<IfThen>, LS> rulesAndFacts = getRulesAndFacts();
358  
        LS facts = reversed(rulesAndFacts.b);
359  
        L<IfThen> rules = concatLists_conservative(activeTempRules, reversed(rulesAndFacts.a)); // latest rules first!
360  
        final Set<S> toDrop = asHashSet(matchAll_first("$x is not a general chat rule", facts));
361  
        rules = [IfThen r : rules | !toDrop.contains(r.globalID)
362  
          && !ai_ruleAccessesInput(r)];
363  
        print("Deriving from " + n2(rules, "rule") + " and " + n2(facts, "fact"));
364  
        set ai_deriveFacts_debug;
365  
        Set<S> newFacts = ai_deriveFacts(rules, facts);
366  
        newFacts = setMinusSet(newFacts, facts);
367  
        imaginedFacts.addAll(newFacts);
368  
        postMessage("Got " + n2(newFacts, "imaginary fact") + ". Total: " + l(imaginedFacts));
369  
      }
370  
        
371  
      // end of authorized functions
372  
    }
373  
  }
374  
375  
  void askBack(NLLogicChecker_v2 c) {  
376  
    L<RuleFailInfo> fails = nlLogic_sortedRuleFails(nlLogic_ruleFails(c, c.rules));
377  
    print("Have " + n2(fails, "fail"));
378  
    //pnl(fails);
379  
    postMessage(lines(nlLogic_unresolvedFactsToQuestions(fails)));
380  
  }
381  
  
382  
  int numRules() { ret l(first(getRulesAndFacts())); }

Author comment

Began life as a copy of #1017946

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: #1018038
Snippet name: Telegram Facts Bot [Include v2]
Eternal ID of this version: #1018038/63
Text MD5: a9fea91f459236e4f299c92088c577ec
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-10-05 18:07:43
Source code size: 13633 bytes / 382 lines
Pitched / IR pitched: No / No
Views / Downloads: 391 / 1092
Version history: 62 change(s)
Referenced in: [show references]