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

351
LINES

< > BotCompany Repo | #1018379 // Telegram Facts Bot [Include v3, using new multi-threaded engine, dev.]

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

Author comment

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: 354 / 664
Version history: 10 change(s)
Referenced in: [show references]