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

405
LINES

< > BotCompany Repo | #1002841 // Prolog Bot (LIVE!)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (7809L/50K/164K).

1  
!759
2  
3  
!include #1002884 // Prolog with shared clauses
4  
!include #1002933 // Natives
5  
6  
static boolean showLog, printTimings = true;
7  
static Prolog p;
8  
static Prolog parsingInterpreter;
9  
//static O theoryBot;
10  
static Method getTheoryMethod;
11  
12  
p {
13  
  new Prolog p;
14  
  parsingInterpreter = p;
15  
  p.addNatives(new IntMul, new IntDiv, new IntAdd, new IntMinus);
16  
  p.addNatives(new GreaterThan, new HeadExists, new TheoriesList);
17  
  p.addNatives(new tocons, new fromcons, new LessThan, new arg, new Arity);
18  
  p.addNatives(new operator, new Unquote, new IsQuoted, new IsWord, new RemoveWord, new GetTheory, new TextOfTheory);
19  
  p.addNatives(new Solve1, new Think, new MemorizeImpl, new RewriteWithTheory, new NLSafeParse);
20  
  p.addNatives(new StartsWith);
21  
}
22  
23  
static class CacheEntry {
24  
  S text;
25  
  Lisp parsed;
26  
  L<Prolog.Clause> program;
27  
  
28  
  *(S *text) {
29  
  }
30  
  
31  
  Lisp getParsed() {
32  
    if (parsed == null)
33  
      parsed = nlParse(text);
34  
    ret parsed;
35  
  }
36  
  
37  
  L<Prolog.Clause> getProgram() {
38  
    if (program == null)
39  
      program = parsingInterpreter.parseProgram(text);
40  
    ret program;
41  
  }
42  
}
43  
44  
static new Map<CIString, CacheEntry> parseCache;
45  
46  
static S getTheoryFromBot(S name) ctex {
47  
  if (getTheoryMethod != null)
48  
    ret (S) getTheoryMethod.invoke(null, name);
49  
  ret (S) callOpt(theoryBot(), "getTheoryOpt", name);
50  
}
51  
52  
static void cacheGetTheoryMethod() {
53  
  getTheoryMethod = findMethod(theoryBot(), "getTheoryOpt", "");
54  
}
55  
56  
static S findTheory(S name) {
57  
  ret getTheoryFromBot(name);
58  
}
59  
60  
static S saveTheory(S name, S text) {
61  
  ret (S) callOpt(theoryBot(), "saveTheory", name, text);
62  
}
63  
64  
static Lisp getParsedTheory(S name) {
65  
  CacheEntry entry = getCacheEntry(name);
66  
  ret entry == null ? null : entry.getParsed();
67  
}
68  
69  
static L<Prolog.Clause> getProgram(S name) {
70  
  CacheEntry entry = getCacheEntry(name);
71  
  ret entry == null ? null : entry.getProgram();
72  
}
73  
74  
static CacheEntry getCacheEntry(S name) {
75  
  S text = findTheory(name);
76  
  if (text == null) ret null;
77  
  
78  
  CacheEntry entry = parseCache.get(new CIString(name));
79  
  if (entry == null || neq(entry.text, text)) {
80  
    entry = new CacheEntry(text);
81  
    parseCache.put(new CIString(name), entry);
82  
  }
83  
  ret entry;
84  
}
85  
86  
static S prettyPrintTerms(L<Lisp> l, boolean outerBrackets) {
87  
  new L<S> out;
88  
  for (Lisp term : l) {
89  
    S s = nlUnparse(term, !outerBrackets);
90  
    //out.add(outerBrackets ? "[" + s + "]" : s);
91  
    out.add(s);
92  
  }
93  
  ret joinLines(out);
94  
}
95  
96  
static void loadTheories(Prolog p, L<S> theoryNames) {
97  
  if (theoryNames.contains("signed")) {
98  
    theoryNames.remove("signed");
99  
    theoryNames.addAll(getLiveTheories());
100  
  }
101  
  
102  
  if (theoryNames.contains("signedstefan")) {
103  
    theoryNames.remove("signedstefan");
104  
    theoryNames.addAll(getLiveTheories ("stefanreich"));
105  
  }
106  
  
107  
  cacheGetTheoryMethod();
108  
  try {
109  
    for (S t : asSet(theoryNames)) { // todo: ignore case
110  
      loadTheoryImpl(p, t);
111  
      long n = getTheoryCounter(t);
112  
      for (long i = 1; i <= n; i++)
113  
        loadTheoryImpl(p, t + "." + i);
114  
    }
115  
  } finally { 
116  
    getTheoryMethod = null;
117  
  }
118  
}
119  
120  
static long getTheoryCounter(S name) {
121  
  //ret (long) call(theoryBot(), "getTheoryCounter", name);
122  
  S text = findTheory(name + ".count");
123  
  ret isEmpty(text) ? 0 : parseLong(text);
124  
}
125  
126  
static void loadTheoryImpl(Prolog p, S name) {
127  
  L<Prolog.Clause> program = getProgram(name);
128  
  if (program != null)
129  
    p.addProgram(program, name);
130  
}
131  
132  
static S solutionPrettyPrint(Map<S, Lisp> solution) {
133  
  S s = "FALSE";
134  
  if (solution != null) {
135  
    new L<S> l;
136  
    solution = new TreeMap(solution); // sort
137  
    for (S var : solution.keySet())
138  
      l.add(var + " = " + nlUnparse(solution.get(var), false));
139  
    s = "TRUE.\n" + slackSnippetOpt(joinLines(l));
140  
  }
141  
  /*if (showStack)
142  
    s += "\nStack:" + slackSnippetOpt(prettyPrintTerms(p.getStackTerms(), false));*/
143  
  if (showLog) {
144  
    L<S> usedTheories = p.getUsedTheories();
145  
    L<S> lines = litlist("Used theories: " + join(", ", usedTheories));
146  
    L<Lisp> mem = p.getMemorizedStatements();
147  
    if (nempty(mem)) {
148  
      lines.add("Thoughts:");
149  
      for (Lisp x : mem)
150  
        lines.add("  " + nlUnparse(x));
151  
    }
152  
    lines.addAll(p.log);
153  
    s += "\n" + slackSnippet(lines);
154  
  }
155  
  ret s;
156  
}
157  
158  
static Prolog newProlog(L<S> theoryNames) {
159  
  ret p = newSubProlog(theoryNames, showLog);
160  
}
161  
162  
static Prolog newProlog(L<S> theoryNames, boolean showLog) {
163  
  ret p = newSubProlog(theoryNames, showLog);
164  
}
165  
166  
static Prolog newSubProlog(L<S> theoryNames, boolean showLog) {
167  
  long startTime = now();
168  
  int parses = nlParse_count.get();
169  
  
170  
  Prolog p = new Prolog;
171  
  if (showLog)
172  
    p.logOn();
173  
  
174  
  p.copyProgramFrom(parsingInterpreter); // natives!
175  
  
176  
  long t2 = now();
177  
  loadTheories(p, theoryNames);
178  
  if (printTimings) {
179  
    parses = nlParse_count.get()-parses;
180  
    long end = now();
181  
    long time = end-startTime;
182  
    t2 = end-t2;
183  
    print("Making prolog interpreter with " + l(theoryNames) + " theories: " + time + " ms (" + parses + " parses, " + t2 + " ms in loadTheories)");
184  
  }
185  
  ret p;
186  
}
187  
188  
// n = how many solutions to print
189  
static S solve(Lisp question, L<S> theoryNames, int n) {
190  
  new StringBuilder buf;
191  
  
192  
  question = new EvalTransform().evalTransformQuestion(question);
193  
  
194  
  newProlog(theoryNames);
195  
    
196  
  time {
197  
    try {
198  
      Map<S, Lisp> solution = p.solve(question);
199  
      if (solution == null)
200  
        buf.append("FALSE in " + structure(theoryNames) + (p.log != null ? "\n" + slackSnippet(p.log) : ""));
201  
      else {
202  
        buf.append(solutionPrettyPrint(solution) + "\n");
203  
        
204  
        while (--n > 0) {
205  
          solution = p.nextSolution();
206  
          if (solution == null) break;
207  
          buf.append(solutionPrettyPrint(solution) + "\n");
208  
        }
209  
        
210  
        if (p.nextSolution() != null)
211  
          buf.append("[more]");
212  
        else
213  
          buf.append("[done]");
214  
      }
215  
    } catch (Exception e) {
216  
      ret e + "\n" + slackSnippet(p.log);
217  
    }
218  
  }
219  
  
220  
  buf.append(" " + lastTiming() + " ms");
221  
  
222  
  ret str(buf);
223  
}
224  
225  
static L<S> nlParseStringList(Lisp tree) {
226  
  if (tree.isLeaf())
227  
    ret litlist(unquote(tree.raw()));
228  
  new L<S> l;
229  
  for (Lisp t : tree) {
230  
    if (!t.isLeaf()) continue; // huh?
231  
    S s = t.head;
232  
    if (eq(s, ",") /*|| eq(s, "and")*/) continue;
233  
    l.add(unquote(s));
234  
  }
235  
  ret l;
236  
}
237  
238  
static L<S> getTheoryNames() {
239  
  ret (L) callOpt(theoryBot(), "getTheoryNames");
240  
}
241  
242  
static L<S> getLiveTheories() {
243  
  ret concatLists (
244  
    getLiveTheories (getUserName ()),
245  
    getLiveTheories ("stefanreich"));
246  
  }
247  
248  
static L<S> getLiveTheories(S user) {
249  
  ret empty(user) ? litlist() : (L) callOpt(theoryBot(), "getTheoriesSignedByAs", user, "live");
250  
}
251  
252  
static S solve(S s, boolean showLog) {
253  
  main.showLog = showLog;
254  
  
255  
  s = s.trim();
256  
  int n = 1;
257  
  int i = s.indexOf(']');
258  
  if (i >= 2) {
259  
    S s2 = dropPrefix("[", substring(s, 0, i));
260  
    if (isInteger(s2)) {
261  
      n = parseInt(s2);
262  
      s = s.substring(i+1).trim();
263  
    }
264  
  }
265  
  
266  
  Lisp tree = nlParse(s);
267  
  
268  
  //ret structure(tree);
269  
  
270  
  new Map<S, Lisp> m;
271  
  if (nlMatch("$text in $theory", tree, m)) {
272  
    print("text in theory");
273  
    Lisp question = m.get("text");
274  
    Lisp t = m.get("theory");
275  
    L<S> theoryNames = nlParseStringList(t);
276  
    ret solve(question, theoryNames, n);
277  
  }
278  
  
279  
  if (nlMatch("theory $t", tree, m)) {
280  
    print("theory");
281  
    S theoryName = unquote(m.get("t").raw());
282  
    ret solve(nlParse(findTheory(theoryName)), litstringlist("signed"), n);
283  
  }
284  
  
285  
  if (nlMatch("$text", tree, m)) {
286  
    print("text");
287  
    Lisp question = m.get("text");
288  
    ret solve(question, litstringlist("signed"), n);
289  
  }
290  
  
291  
  ret "hm?";
292  
}
293  
294  
synchronized answer {
295  
  if "top unifications"
296  
    ret p == null ? "-" : str(p.topUnifications);
297  
    
298  
  if (!attn()) ret null;
299  
  
300  
  if (swic(s, "solve ")) exceptionToUser {
301  
    s = dropPrefixIgnoreCase("solve ", s);
302  
    ret solve(s, false);
303  
  }
304  
  
305  
  if (swic(s, "eval ")) exceptionToUser {
306  
    s = trim(dropPrefixIgnoreCase("eval ", s));
307  
    S var = nlMakeUnusedVar(s);
308  
    s = var + " = " + s;
309  
    ret solve(s, false);
310  
  }
311  
  
312  
  if (swic(s, "log ")) exceptionToUser {
313  
    s = dropPrefixIgnoreCase("log ", s);
314  
    ret solve(s, true);
315  
  }
316  
  
317  
  if (swic(s, "say ")) exceptionToUser {
318  
    s = dropPrefixIgnoreCase("say ", s);
319  
    
320  
    new Map<S, Lisp> mm;
321  
    if (nlMatch("$text in $theory", s, mm)) {
322  
      Lisp question = mm.get("text");
323  
      Lisp t = mm.get("theory");
324  
      s = "[[think [user says " + nlUnparse(question, false) + "]] and [say $x]] in " + nlUnparse(t, false);
325  
      print("s = " + s);
326  
      ret solve(s, true);
327  
    }
328  
    ret "woot syntax";
329  
  }
330  
  
331  
  if "produce *" exceptionToUser {
332  
    ret produce(m.unq(0));
333  
  }
334  
  
335  
  if "my program" exceptionToUser {
336  
    S user = getUserName();
337  
    if (empty(user)) ret "go to slack please";
338  
    p = new Prolog;
339  
    loadTheories(p, getLiveTheories());
340  
    ret p.showProgram();
341  
  }
342  
  
343  
  if "log" exceptionToUser {
344  
    ret slackSnippet(p.log);
345  
  }
346  
  
347  
  if "rewrite * with *" exceptionToUser {
348  
    ret rewrite(m.unq(0), m.unq(1), null);
349  
  }
350  
  
351  
  if "rewrite * with * as *" exceptionToUser {
352  
    ret rewrite(m.unq(0), m.unq(1), m.unq(2));
353  
  }
354  
  
355  
  if "time findTheory" exceptionToUser {
356  
    time {
357  
      //theoryBot = getBot("#1002762");
358  
      cacheGetTheoryMethod();
359  
      try {
360  
        for (int i = 0; i < 1000; i++)
361  
          findTheory("and");
362  
      } finally {
363  
        //theoryBot = null;
364  
        getTheoryMethod = null;
365  
      }
366  
    }
367  
    ret (lastTiming()/1000.0) + " ms";
368  
  }
369  
}
370  
371  
static S rewrite(S tname1, S tname2, S tname3) {
372  
  newProlog(litlist(tname1, "signed"), true);
373  
  L<Prolog.Clause> rewriteTheory = p.parseProgram(findTheory(tname2));
374  
  L<Lisp> rewritten = p.rewriteWith(rewriteTheory);
375  
  S text = prettyPrintTerms(rewritten, true);
376  
  if (tname3 == null)
377  
    ret slackSnippet(text) + "\n" + slackSnippet(p.log);
378  
  ret saveTheory(tname3, text);
379  
}
380  
381  
static S produce(S theoryName) {
382  
  S outName = theoryName + ".out";
383  
  
384  
  showLog = false;
385  
  newProlog(litlist(theoryName));
386  
  S question = "say $x";
387  
  Lisp out = lisp("[]");
388  
  p.start(question);
389  
  int max = 100;
390  
  while (out.size() < max) {
391  
    Map<S, Lisp> solution = p.nextSolution();
392  
    if (solution == null) break;
393  
    out.add(solution.get("$x"));
394  
  }
395  
  
396  
  ret (out.size() >= max ? "WARNING MAXED OUT\n" : "") + saveTheory(outName, nlUnparse(out));
397  
}
398  
399  
static void incrementTheory(S name, Lisp value) {
400  
  call(theoryBot(), "incrementTheory", name, nlUnparse(value));
401  
}
402  
403  
static O theoryBot() {
404  
  ret /*or(theoryBot,*/ getBot("#1002762")/*)*/;
405  
}

Author comment

Began life as a copy of #1002837

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002841
Snippet name: Prolog Bot (LIVE!)
Eternal ID of this version: #1002841/1
Text MD5: 4dfaa70d562d8b64a2960c408c85c4d2
Transpilation MD5: 203c344b63b31321293fa6752eea54bd
Author: stefan
Category: eleu / nl
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-10-19 02:03:03
Source code size: 10756 bytes / 405 lines
Pitched / IR pitched: No / No
Views / Downloads: 1378 / 1872
Referenced in: [show references]