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

765
LINES

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

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

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

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: #1027172
Snippet name: PhilosophyBot1 (backup before trails)
Eternal ID of this version: #1027172/1
Text MD5: f1a11316257449b4d79ee3d2fd9e971e
Transpilation MD5: f8c0d0f00948dfe88a129e0ef4ee91c3
Author: stefan
Category:
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-02-24 01:15:24
Source code size: 23303 bytes / 765 lines
Pitched / IR pitched: No / No
Views / Downloads: 105 / 141
Referenced in: [show references]