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

789
LINES

< > BotCompany Repo | #1027175 // PhilosophyBot1 (backup before trails 2)

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (8848L/59K).

1  
sclass PhilosophyBot1 {
2  
  static transformable record LogicRule(lhs, rhs) {
3  
    int n; // when added
4  
    
5  
    toString {
6  
      ret (n == 0 ? "" : "[" + n + "] ") + lhs + " => " + rhs;
7  
    }
8  
  }
9  
  static transformable record And(a, b) {}
10  
  static transformable record If(condition, thenBlock, elseBlock) {}
11  
  static transformable record For(var, condition, body) {} // don't need var actually
12  
  static transformable record ForIn(var, expr, body) {}
13  
  static transformable record While(condition, body) {}
14  
15  
  replace NPRet with O. // native predicate return type (Bool/SS/null)
16  
17  
  // like a native predicate, but doesn't return anything
18  
  sclass CodeFragment {
19  
    S head;
20  
    IVF2<SS, Env> body;
21  
    bool keepBrackets;
22  
    
23  
    *(S *head, IVF2<SS, Env> *body, bool *keepBrackets) {}
24  
    *(S *head, IVF2<SS, Env> *body) {}
25  
    
26  
    toString { ret stdToString(this); }
27  
  }
28  
29  
  sclass Env {
30  
    bool wantAlternatives;
31  
32  
    bool wantAlternatives() { ret wantAlternatives; }
33  
  }
34  
35  
  srecord WithAlternative(IF0<O> alternative, O result) {}
36  
  
37  
  // body takes variable mapping
38  
  // body can return
39  
  //   Bool => immediate result (ok or fail)
40  
  //   SS   => variable mapping
41  
  //   WithAlternative
42  
  //   Iterator<NPRet>
43  
  //   null => not applicable
44  
  // For "for $x in ..." statements, return a Iterable<stringable>?
45  
  srecord NativePredicate(S head, IF2<SS, Env, NPRet> body) {}
46  
  
47  
  replace ProcedureToRun with Proc.
48  
  replace Proc with L. // procedures are a list of statements
49  
  
50  
  // trail of a transformed fact
51  
  srecord TTransformed(S fact, IF1<S> transformer) {}
52  
53  
  transient S program;
54  
  transient bool programLoaded;
55  
  transient int maxRounds = 1000;
56  
  transient int maxFacts = 1000;
57  
  transient Set<S> facts = linkedCISet();
58  
  transient Set<S> originalFacts = ciSet();
59  
  transient new LinkedHashSet<LogicRule> logicRules; // modified with sync
60  
  transient new AllOnAll<LogicRule, S> rulesOnFacts;
61  
  transient new AllOnAll<CodeFragment, S> codeOnFacts;
62  
  transient new AllOnAll<IVF1<S>, S> anyCodeOnFacts;
63  
  transient new L<ProcedureToRun> proceduresToRun;
64  
 // parsed procedures
65  
  transient long proceduresExecuted;
66  
  transient new L<NativePredicate> nativePredicates;
67  
  transient bool debugNativeCalls = true, debugAllCmds = true;
68  
  transient bool verbose = true;
69  
  transient new L onProcedureEnded;
70  
  transient new L<IVF1<LogicRule>> onLogicRuleAdded;
71  
  transient new L<IVF1<S>> onFactAdded;
72  
  transient bool printNonMatches, debugContradictionChecks;
73  
  transient bool standardImportsLoaded;
74  
  transient bool curryAllRules = true; // rewrite "a & b => c" to a => b => c
75  
  transient int logicRulesCounter;
76  
  transient bool thoughtBegun;
77  
  transient bool printFactsAfterThinking = true;
78  
79  
  // return true when you handled adding the rule
80  
  transient new L<IPred<LogicRule>> logicRulePreprocessors;
81  
  
82  
  // return true when you handled adding the fact
83  
  transient new L<IPred<S>> factPreprocessors;
84  
  
85  
  // extra stuff that is done every round
86  
  transient new L<Runnable> extraLogicOperations;
87  
88  
  transient Set<S> vars = litciset("x", "y", "z");
89  
  
90  
  // phrase replacements that are made in every fact.
91  
  // functionality is enabled by philosophyBot1_addDeepReplacement
92  
  transient SS deepReplacements;
93  
  
94  
  transient L<IF1<S>> deepTransformers;
95  
  
96  
  // fact -> trail. to enable, initialize with ciMap()
97  
  transient MapSO trails;
98  
  
99  
  Map extensions;
100  
  
101  
  *() {
102  
    // find contradictions
103  
    anyCodeOnFacts.newA(fact -> {
104  
      Bool b = checkNativeCondition(fact);
105  
      if (debugContradictionChecks)
106  
        print("Fact check: " + b + " - " + fact);
107  
      if (isFalse(b))
108  
        addFactWithTrail("contradiction", trails == null ? null : fact);
109  
    });
110  
    
111  
    _standardHandlers();
112  
  }
113  
  *(S *program) { this(); }
114  
  
115  
  void addRule(S s) {
116  
    PairS p = splitAtFirstDoubleArrow(javaTokWithBrackets(s));
117  
    if (p == null) if (verbose) print("addRule failed: " + s);
118  
    addLogicRule(new LogicRule(splitAtAmpersand2(p.a), p.b));
119  
  }
120  
  
121  
  void addRules(Iterable<S> l) {
122  
    fOr (S s : l) addRule(s);
123  
  }
124  
  
125  
  O splitRuleRHS(O rhs) {
126  
    if (rhs cast S) {
127  
      PairS p = splitAtFirstDoubleArrow(javaTokWithBrackets(rhs));
128  
      if (p != null) ret splitRuleRHS(new LogicRule(splitAtAmpersand2(p.a), splitRuleRHS(p.b)));
129  
    
130  
      ret splitAtAmpersand2(rhs);
131  
    }
132  
    ret rhs;
133  
  }
134  
  
135  
  LogicRule curryLHS(LogicRule rule) {
136  
    while licensed {
137  
      O lhs = rule.lhs;
138  
      if lhs is And(O a, O b)
139  
        rule = new LogicRule(a, new LogicRule(b, rule.rhs));
140  
      else break;
141  
    }
142  
    ret rule;
143  
  }
144  
145  
  void addLogicRule(LogicRule rule) {
146  
    rule.rhs = splitRuleRHS(rule.rhs);
147  
    
148  
    if (curryAllRules)
149  
      rule = curryLHS(rule);
150  
151  
    for (IPred<LogicRule> p : logicRulePreprocessors)
152  
      if (p.get(rule)) ret; // has been preprocessed
153  
      
154  
    rule.n = ++logicRulesCounter;
155  
      
156  
    // is LHS a native predicate? then eval immediately
157  
    // TODO: multiple conditions
158  
    Bool b = checkConditionOpt(rule.lhs);
159  
    if (isFalse(b)) ret; // drop rule
160  
    if (isTrue(b))
161  
      addRewrittenRHS(rule.rhs, rule);
162  
163  
    if (syncAdd(logicRules, rule)) {
164  
      if (verbose) print("Got logic rule", rule);
165  
      pcallFAll(onLogicRuleAdded, rule);
166  
      rulesOnFacts.newA(rule); // to combine it with the facts
167  
    }
168  
  }
169  
  
170  
  void addFacts(Iterable<S> l) {
171  
    fOr (S fact : l) addFact(fact);
172  
  }
173  
  
174  
  void addFactWithTrail(S fact, O trail) {
175  
    addFact(fact);
176  
    mapPut(trails, fact, trail);
177  
  }
178  
179  
  void addFact(S fact) {
180  
    ping();
181  
    fact = trim(fact);
182  
    if (empty(fact)) ret;
183  
    
184  
    if (l(facts) >= maxFacts) ret;
185  
    
186  
    fact = tok_deRoundBracket(fact);
187  
    
188  
    for (IPred<S> p : factPreprocessors)
189  
      if (p.get(fact)) ret; // has been preprocessed
190  
191  
    // Check if it's a procedure
192  
    LS tok = mainTokenize(fact);
193  
    if (countCodeTokens(tok) == 2 && firstTokenEqic(tok, "proc")
194  
      && isCurlyBracketed(getCodeToken(tok, 1))) pcall {
195  
        // It's a procedure!
196  
        S proc = uncurly_keepSpaces(getCodeToken(tok, 1));
197  
        if (proceduresToRun.add(parseProcedure(proc))) {
198  
          if (verbose) print("Got procedure:");
199  
          if (verbose) print(indentx("> ", proc));
200  
        }
201  
    } /*else if (countCodeTokens(tok) == 2 && firstTokenEqic(tok, "java")
202  
      && isCurlyBracketed(getCodeToken(tok, 1))) pcall {
203  
        // It's Java code
204  
        
205  
    }*/ else // It's a fact, not a procedure
206  
      if (facts.add(fact)) {
207  
        if (verbose) print("Got fact: " + fact);
208  
        pcallFAll(onFactAdded, fact);
209  
        rulesOnFacts.newB(fact); // to combine it with the rules
210  
        codeOnFacts.newB(fact);
211  
        anyCodeOnFacts.newB(fact);
212  
      }
213  
  }
214  
215  
  void addRewrittenRHS(O o, O trail) {
216  
    if (o cast LogicRule)
217  
      addLogicRule(o);
218  
    else if o is And(O a, O b) {
219  
      addRewrittenRHS(a, o);
220  
      addRewrittenRHS(b, o);
221  
    } else if (o != null)
222  
      addFactWithTrail((S) o, trail);
223  
  }
224  
225  
  void addFactFromProgram(S fact) {  
226  
    if (countJavaTokens(fact) == 0) ret;
227  
    fact = javaDropAllComments(fact);
228  
    originalFacts.add(fact);
229  
    addFact(fact);
230  
  }
231  
232  
  void runProcedure(S proc) pcall {
233  
    if (verbose) print("Running procedure.");
234  
    runParsedProcedure(parseProcedure(proc));
235  
  }
236  
237  
  void runParsedProcedure(Proc commands) {
238  
    runParsedProcedure(commands, proceduresToRun);
239  
  }
240  
  
241  
  void runParsedProcedure(Proc commands, L<Proc> whereToPostCode) {
242  
    ++proceduresExecuted;
243  
    new Env env;
244  
    L remainingCommands = cloneLinkedList(commands);
245  
    O cmd;
246  
    while not null (cmd = popFirst_ping(remainingCommands)) {
247  
      if (cmd cast L) continue with runParsedProcedure(cmd);
248  
      if (cmd cast Runnable) continue with cmd.run();
249  
      if (debugAllCmds)
250  
        print("Running cmd: " + sfu(cmd));
251  
      if cmd is If(O condition, O thenBlock, O elseBlock) {
252  
        O blockToRun = checkCondition(condition) ? thenBlock : elseBlock;
253  
        runParsedProcedure(ll(blockToRun));
254  
      } else if cmd is For(O var, O condition, O body) {
255  
        // make a new logic rule and add it
256  
        // assume the variable is globally declared as a variable
257  
        addLogicRule(new LogicRule(condition, "proc {\n" + body + "\n}"));
258  
      } else if cmd is While(O condition, O body) {
259  
        bool b = checkCondition(condition);
260  
        if (!b) continue;
261  
        whereToPostCode.add(ll(body, cmd));
262  
      } else if cmd is ForIn(S var, S expr, O body) {
263  
        // XXX
264  
        O result = runNativePredicate(expr, new Env);
265  
        if (!result instanceof Iterable) {
266  
          if (verbose) print("Warning: result of " + expr + " not iterable (" + shortClassName(result) + ")");
267  
          continue;
268  
        }
269  
        Iterator it = iterator((Iterable) result);
270  
        Runnable step = r {
271  
          if (!it.hasNext()) ret;
272  
          S value = str(it.next());
273  
          SS map = litcimap(var, value);
274  
          O body2 = replaceVars(body, map);
275  
          //print("ForIn: " + map + " => " + body2);
276  
          whereToPostCode.add(ll(body2, this));
277  
        };
278  
        step.run();
279  
      } else if (cmd cast S) {
280  
        O result = runNativePredicate(cmd, env);
281  
        if (result != null) {
282  
          result = unpackWithAlternativeOrIterator(result);
283  
          if (isFalse(result)) ret;
284  
          if (isTrueOpt(result)) continue;
285  
          SS mapping = cast result; // assume it's a variable mapping
286  
          // apply to all remaining commands and continue
287  
          L remainingCommands2 = mapToLinkedList(remainingCommands,
288  
            c -> replaceVars(c, mapValues optRound(mapping)));
289  
          if (verbose) print("Applying var mapping " + mapping + " to " + remainingCommands
290  
            + " => " + remainingCommands2);
291  
          remainingCommands = remainingCommands2;
292  
        } else
293  
          addFact(cmd);
294  
      } else if (cmd != null)
295  
        fail("Unimplemented command: " + cmd);
296  
    }
297  
    pcallFAll(onProcedureEnded, commands); // notify listeners
298  
  }
299  
300  
  // return var mapping (SS), Bool or null for no matching predicate
301  
  // or result verbatim (e.g. Iterable)
302  
  O runNativePredicate(S s, Env env) {
303  
    for (NativePredicate np : nativePredicates) {
304  
      SS map = zipIt(np.head, s);
305  
      if (map != null) {
306  
        O result = np.body.get(mapValues tok_deRoundBracket(map), env);
307  
        if (debugNativeCalls)
308  
          print("Native predicate result: " + np.head + " => " + result);
309  
        if (result instanceof Map && nempty(map)) {
310  
          result = mapKeys((SS) result, var -> lookupOrKeep(map, var));
311  
          if (debugNativeCalls)
312  
            print("Rewrote native predicate result: " + result);
313  
        }
314  
        try object result;
315  
      } else
316  
        if (printNonMatches)
317  
          print("Non-match: " + quote(np.head) + " / " + quote(s));
318  
    }
319  
    null;
320  
  }
321  
322  
  // returns false if unknown
323  
  bool checkCondition(O o) {
324  
    ret isTrue(checkConditionOpt(o));
325  
  }
326  
  
327  
  // returns null if unknown
328  
  Bool checkConditionOpt(O o) {
329  
    if (o cast S) {
330  
      if (contains(facts, o)) true;
331  
      try object Bool b = checkNativeCondition(o);
332  
    }
333  
    //print("Ignoring condition: " + o);
334  
    null;
335  
  }
336  
  
337  
  Bool checkNativeCondition(S o) {
338  
    O result = runNativePredicate(o, new Env);
339  
    result = unpackWithAlternativeOrIterator(result);
340  
    if (result cast Bool) ret result;
341  
    if (result instanceof Map) true; // TODO
342  
    null;
343  
  }
344  
345  
  !include #1025614 // parsePythonesqueProcedure
346  
347  
  Proc parseProcedure(S s) {
348  
    ret parsePythonesqueProcedure(s);
349  
  }
350  
351  
  O splitAtAmpersand2(S s) {
352  
    LS l = tok_splitAtAmpersand(s);
353  
    if (l(l) == 1) ret s;
354  
    ret new And(first(l), splitAtAmpersand2(join(" & ", dropFirst(l))));
355  
  }
356  
357  
  // "zip" a condition with a fact (match word-by-word)
358  
  SS zipIt(S cond, S fact) {
359  
    SS map = zipIt_keepBrackets(cond, fact);
360  
    if (map == null) null; // no match
361  
    ret mapValues tok_deRoundOrCurlyBracket(map);
362  
  }
363  
  
364  
  SS zipIt_deBracket(S pat, S s) {
365  
    SS map = zipIt(pat, s);
366  
    ret map == null ? null : mapValues tok_deRoundOrCurlyBracket(map);
367  
  }
368  
369  
  // "zip" a condition with a fact (match word-by-word)
370  
  SS zipIt_keepBrackets(S cond, S fact) {
371  
    SS map = gazelle_deepZip_keepBrackets(cond, fact);
372  
    if (map == null) null; // no match
373  
    if (!all(keys(map), s -> isVar(s))) null; /*with print("Non-variable changes, exiting")*/;
374  
    ret map;
375  
  }
376  
377  
  bool isVar(S s) {
378  
    ret s != null &&
379  
      (vars.contains(s) || s.startsWith("var_") || isDollarVar(s));
380  
  }
381  
382  
  O replaceVars(O o, SS map) {
383  
    if (empty(map)) ret o;
384  
    ret transform(x -> replaceVars_base(x, map), o);
385  
  }
386  
  
387  
  O replaceVars_base(O o, SS map) {
388  
    if (o cast S)
389  
      ret replaceCodeTokensUsingMap(o, map);
390  
    null;
391  
  }
392  
  
393  
  S format(S s, SS map) {
394  
    ret replaceCodeTokensUsingMap(s, mapValues optRound(map));
395  
  }
396  
  
397  
  // if f returns null, go through structure
398  
  O transform(IF1 f, O o) {
399  
    if (o == null) null;
400  
    ping();
401  
    try object f.get(o);
402  
    
403  
    if (o cast Transformable)
404  
      ret o.transformUsing(x -> transform(f, x));
405  
    
406  
    if (o cast L)
407  
      ret map(x -> transform(f, x), o);
408  
      
409  
    fail("Don't know how to transform: " + className(o));
410  
  }
411  
412  
  void applyLogicRuleToFact(LogicRule rule, S fact) {
413  
    O lhs = rule.lhs, rhs = rule.rhs;
414  
    O cond, remaining = null;
415  
    if lhs is And(O a, O b) {
416  
      cond = a;
417  
      remaining = b;
418  
    } else
419  
      cond = lhs;
420  
    
421  
    // now we match the condition with the fact
422  
    SS map = zipIt_keepBrackets((S) cond, fact);
423  
    if (map == null) {
424  
      if (printNonMatches)
425  
        print("Non-match: " + quote(cond) + " / " + quote(fact));
426  
      ret; // no match
427  
    }
428  
429  
    // Now we have a proper mapping with the keys being variables!
430  
    if (verbose) print("Match: " + quote(cond) + " / " + quote(fact));
431  
432  
    // drop round brackets
433  
    // XXX? map = mapValues tok_deRoundBracket(map);
434  
435  
    // Apply mapping to right hand side
436  
    O rhs_replaced = replaceVars(rhs, map);
437  
    if (verbose) print(+rhs_replaced);
438  
439  
    if (remaining == null) {
440  
      // Add as fact / new rule
441  
      addRewrittenRHS(rhs_replaced, rule);
442  
    } else {
443  
      // Apply mapping to remaining condition
444  
      O remaining_replaced = replaceVars(remaining, map);
445  
      addLogicRule(new LogicRule(remaining_replaced, rhs_replaced));
446  
    }
447  
  }
448  
  
449  
  run { think(); }
450  
451  
  !include #1025615 // smartParser1
452  
  
453  
  void parseProgram {
454  
    if (programLoaded) ret;
455  
    set programLoaded;
456  
    loadProgram(program);
457  
  }
458  
  
459  
  void loadProgram(S program) {
460  
    smartParser1(program);
461  
  }
462  
463  
  bool doSomeLogic() {
464  
    bool anyAction;
465  
    Pair<LogicRule, S> p;
466  
    while not null (p = rulesOnFacts.next()) {
467  
      ping();
468  
      set anyAction;
469  
      //print("Combination: " + p);
470  
      applyLogicRuleToFact(p.a, p.b);
471  
    }
472  
    Pair<CodeFragment, S> p2;
473  
    while not null (p2 = codeOnFacts.next()) {
474  
      ping();
475  
      set anyAction;
476  
      //print("Combination: " + p2);
477  
      applyCodeFragmentToFact(p2.a, p2.b);
478  
    }
479  
    Pair<IVF1<S>, S> p3;
480  
    while not null (p3 = anyCodeOnFacts.next()) {
481  
      ping();
482  
      set anyAction;
483  
      //print("Combination: " + p3);
484  
      pcallF(p3.a, p3.b);
485  
    }
486  
    ret anyAction;
487  
  }
488  
489  
  void applyCodeFragmentToFact(CodeFragment cf, S fact) {
490  
    SS map = cf.keepBrackets ? zipIt_keepBrackets(cf.head, fact) : zipIt(cf.head, fact);
491  
    if (map != null)
492  
      cf.body.get(mapValues tok_deRoundBracket(map), new Env);
493  
  }
494  
  
495  
  // indicator for end of thought process (when this stays stable)
496  
  long size() {
497  
    ret l(logicRules) + l(facts) + proceduresExecuted;
498  
  }
499  
500  
  void think {
501  
    parseProgram();
502  
    
503  
    set thoughtBegun;
504  
    
505  
    int round = 0;
506  
 
507  
    while ping (round++ < maxRounds) {
508  
      long lastSize = size();
509  
      if (verbose) print("Logic round " + round + ", size: " + lastSize);
510  
      while (doSomeLogic() && round++ < maxRounds && l(facts) < maxFacts) {}
511  
512  
      for ping (Proc proc : getAndClearList(proceduresToRun))
513  
        runParsedProcedure(proc);
514  
        
515  
      callFAll(extraLogicOperations);
516  
        
517  
      if (size() == lastSize) {
518  
        if (verbose) print("No changes, exiting");
519  
        break;
520  
      }
521  
    }
522  
523  
    // We're done logicking, so print all the facts gathered
524  
525  
    Cl<S> madeFacts = factsDeduced();
526  
    if (printFactsAfterThinking)
527  
      pnlWithHeading("Facts I deduced", madeFacts);
528  
529  
    // Print say () and print () separately
530  
531  
    new LS output;
532  
    for (S fact : madeFacts) {
533  
      LS tok = mainTokenize(fact);
534  
      if (countCodeTokens(tok) == 2 && eqicOneOf(getCodeToken(tok, 0), "print", "say"))
535  
        // For the user, we print without all the round brackets
536  
        output.add(tok_dropRoundBrackets(getCodeToken(tok, 1)));
537  
    }
538  
    
539  
    pnlWithHeadingIfNempty("Bot Output", output);
540  
  }
541  
542  
  void addNativePredicate(S head, IF0 body) {
543  
    nativePredicates.add(new NativePredicate(head, (map, env) -> body!));
544  
  }
545  
  
546  
  void addNativePredicate(S head, IF1<SS, O> body) {
547  
    nativePredicates.add(new NativePredicate(head, (map, env) -> body.get(map)));
548  
  }
549  
550  
  void addNativePredicate(S head, IF2<SS, Env, NPRet> body) {
551  
    nativePredicates.add(new NativePredicate(head, body));
552  
  }
553  
554  
  // when you only need one result
555  
  O unpackWithAlternativeOrIterator(O result) {
556  
    if (result instanceof Iterator) ret first((Iterator) result);
557  
    if (result instanceof WithAlternative) ret ((WithAlternative) result).result;
558  
    ret result;
559  
  }
560  
561  
  void onFactDo(S head, IVF2<SS, Env> body) {
562  
    codeOnFacts.newA(new CodeFragment(head, body));
563  
  }
564  
565  
  void onFactDo_keepBrackets(S head, IVF2<SS, Env> body) {
566  
    codeOnFacts.newA(new CodeFragment(head, body, true));
567  
  }
568  
  
569  
  LS filterByPattern(S pat, Iterable<S> items) {
570  
    ret filter(items, i -> zipIt(pat, i) != null);
571  
  }
572  
573  
  // pat = pattern with variables
574  
  // results are mappings with debracketed values
575  
  L<SS> matchFacts(S pat) {
576  
    ret matchStrings(pat, facts);
577  
  }
578  
  
579  
  SS matchString(S pat, S input) {
580  
    ret zipIt_deBracket(pat, input);
581  
  }
582  
  
583  
  L<SS> matchStrings(S pat, Iterable<S> items) {
584  
    new L<SS> out;
585  
    for (S s : items) {
586  
      SS map = zipIt_deBracket(pat, s);
587  
      if (map != null)
588  
        out.add(map);
589  
    }
590  
    ret out;
591  
  }
592  
  
593  
  LPair<S, SS> matchFacts2(S pat) {
594  
    ret matchStrings2(pat, facts);
595  
  }
596  
  
597  
  // returns items too
598  
  LPair<S, SS> matchStrings2(S pat, Iterable<S> items) {
599  
    new LPair<S, SS> out;
600  
    for (S s : items) {
601  
      SS map = zipIt_deBracket(pat, s);
602  
      if (map != null)
603  
        out.add(pair(s, map));
604  
    }
605  
    ret out;
606  
  }
607  
  
608  
  LS matchFacts(S var, S pat) {
609  
    ret map(matchFacts(pat), map -> map.get(var));
610  
  }
611  
  
612  
  // pat = pattern with variables
613  
  // results are mappings with debracketed values
614  
  L<SS> matchFacts_keepBrackets(S pat) {
615  
    new L<SS> out;
616  
    for (S fact : facts) {
617  
      SS map = zipIt_keepBrackets(pat, fact);
618  
      if (map != null)
619  
        out.add(map);
620  
    }
621  
    ret out;
622  
  }
623  
624  
  void openAllTheories {  
625  
    for (SS map : matchFacts_keepBrackets("theory $x $y"))
626  
      openTheory(tok_deRoundOrCurlyBracket(map.get("$x")), map.get("$y"));
627  
  }
628  
  
629  
  void openTheory(S name) {
630  
    for (SS map : matchFacts_keepBrackets("theory $x $y"))
631  
      if (eqic(properUnquote(tok_deRoundBracket($x(map))), name))
632  
        ret with openTheory(name, $y(map));
633  
    fail("Theory not defined: " + quote(name));
634  
  }
635  
636  
  void openTheory(S name, S body) {
637  
    //print("Raw theory: " + quote(s));
638  
    loadProgram(withoutLeadingLinesEmptyAfterTrim_autoUnindent(tok_deRoundOrCurlyBracket_keepFirstSpacing(body)));
639  
    if (verbose) print("Opened theory " + name);
640  
  }
641  
  
642  
  void autoOpenTheories {
643  
    onFactDo_keepBrackets("theory $x $y", (map, env) -> openTheory(tok_deRoundOrCurlyBracket(map.get("$x")), map.get("$y")));
644  
  }
645  
  
646  
  // returns number of expectations checked
647  
  int checkExpectations() {
648  
    int n = 0;
649  
    // check if all expect (...) facts are met
650  
    for (SS map : matchFacts("expect $x")) {
651  
      assertContains(facts, firstValue(map));
652  
      ++n;
653  
    }
654  
    // check if all don't expect (...) facts are met
655  
    for (SS map : matchFacts("don't expect $x")) {
656  
      assertDoesntContain(facts, firstValue(map));
657  
      ++n;
658  
    }
659  
    ret n;
660  
  }
661  
  
662  
  void standardImports() {
663  
    if (standardImportsLoaded) ret;
664  
    set standardImportsLoaded;
665  
    registerImport("math", () -> philosophyBot1_math(this));
666  
    registerImport("bool", () -> philosophyBot1_bool(this));
667  
    registerImport("or", () -> philosophyBot1_orHandler(this));
668  
    registerImport("iota", () -> philosophyBot1_iotaHandler(this));
669  
    registerImport("tlft_honoringBrackets", () -> 
670  
      addNativePredicate("tlft_honoringBrackets $x",
671  
        map -> printIf(verbose, "tlft output",
672  
          tlft_honoringBrackets($x(map)))));
673  
    addNativePredicate("printNonMatches", () -> { printNonMatches = true; true; });
674  
675  
    philosophyBot1_enableAddSimplifier(this);
676  
  }
677  
  
678  
  void addFactPreprocessor(IPred<S> f) {
679  
    factPreprocessors.add(f);
680  
  }
681  
      
682  
  void addLogicRulePreprocessor(IPred<LogicRule> f) {
683  
    logicRulePreprocessors.add(f);
684  
  }
685  
  
686  
  void registerImport(S name, Runnable handler) {
687  
    S line = "import " + name;
688  
    factPreprocessors.add(s -> {
689  
      if (eqic(s, line)) {
690  
        if (verbose) print("Importing " + name);
691  
        handler.run();
692  
        true;
693  
      }
694  
      false;
695  
    });
696  
  }
697  
  
698  
  bool hasFact(S fact) {
699  
    ret contains(facts, fact);
700  
  }
701  
  
702  
  bool hasContradiction() { ret hasFact("contradiction"); }
703  
  
704  
  LS mainTokenize(S s) {
705  
    ret javaTokWithBrackets(s);
706  
  }
707  
  
708  
  // sanitize untrusted input - overly safe version
709  
  S sanitizeInput(S s) {
710  
    ret joinWithSpace(antiFilter(words2_plusApostrophe(s), w -> isVar(w)));
711  
  }
712  
  
713  
  void deleteFacts(Iterable<S> l) {
714  
    Set<S> set = asCISet(l);
715  
    facts = filterCISet(facts, f -> !contains(set, f));
716  
  }
717  
  
718  
  Cl<S> factsDeduced() {
719  
    ret listMinusList(facts, originalFacts);
720  
  }
721  
  
722  
  bool containsDollarVars(O o) {
723  
    // abuse transform function
724  
    new Flag flag;
725  
    withCancelPoint(cp -> {
726  
      transform(x -> {
727  
        if (x cast S) {
728  
          if (main containsDollarVars(x)) {
729  
            flag.raise();
730  
            cancelTo(cp);
731  
          }
732  
          ret x;
733  
        }
734  
        null;
735  
      }, o);
736  
    });
737  
    ret flag!;
738  
  }
739  
  
740  
  L<LogicRule> allLogicRulesWithoutLHSVars() {
741  
    ret filter(logicRules, r -> !containsDollarVars(leftmostCondition(r.lhs)));
742  
  }
743  
  
744  
  O leftmostCondition(O o) {
745  
    while (o instanceof And) o = ((And) o).a;
746  
    ret o;
747  
  }
748  
  
749  
  void _standardHandlers {
750  
    philosophyBot_autoOpenTheoriesHandler(this);
751  
    addFactPreprocessor(s -> { if (eqic(s, "standard imports")) ret true with standardImports(); false; });
752  
  }
753  
  
754  
  void runAndCheckExpectations {
755  
    run();
756  
    checkExpectations();
757  
  }
758  
  
759  
  void addDeepTransformer(IF1<S> transformer) {
760  
    if (deepTransformers == null) {
761  
      deepTransformers = new L;
762  
      // enable transformers
763  
      anyCodeOnFacts.newA(fact ->
764  
        addFactWithTrail(gazelle_deepTransform(
765  
          s -> firstTransformersResult(deepTransformers, s), fact),
766  
          trails == null ? null : new TTransformed(fact, transformer)));
767  
    }
768  
    deepTransformers.add(transformer);
769  
  }
770  
  
771  
  O getExtension(O key) { ret mapGet(extensions, key); }
772  
  
773  
  void addExtension(O key, O value) {
774  
    if (extensions == null) extensions = new Map;
775  
    extensions.put(key, value);
776  
  }
777  
  
778  
  void enableTrails() { if (trails == null) trails = ciMap(); }
779  
  
780  
  O getTrail(S fact) { ret mapGet(trails, fact); }
781  
  
782  
  void printDeducedFactsWithTrails() {
783  
    printAsciiHeading("Deduced facts with trails");
784  
    for (S fact : factsDeduced()) {
785  
      print(fact);
786  
      printUnlessNull("  << ", getTrail(fact));
787  
    }
788  
  }
789  
}

Author comment

Began life as a copy of #1025597

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1027175
Snippet name: PhilosophyBot1 (backup before trails 2)
Eternal ID of this version: #1027175/1
Text MD5: 5c4f33bceecbb530d384bd9f65e781aa
Transpilation MD5: 3486156abffc500c92eb7767e43952dc
Author: stefan
Category:
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-02-24 11:35:00
Source code size: 24093 bytes / 789 lines
Pitched / IR pitched: No / No
Views / Downloads: 164 / 233
Referenced in: [show references]