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

299
LINES

< > BotCompany Repo | #1025576 // Philosophy Bot 1 [OK]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 911K of libraries. Click here for Pure Java version (5946L/31K).

1  
!7
2  
3  
cmodule PhilosophyBot extends DynPrintLog {
4  
  transient S program = [[
5  
    "memory"
6  
    
7  
    memory can mean RAM
8  
    RAM has a size
9  
    I have RAM
10  
    
11  
    input is x & x can mean y => pretend (input is y)
12  
    
13  
    input is x => activate facts containing x
14  
    
15  
    I have x => Ask something about (my x)
16  
    
17  
    I have x => (my x) exists
18  
19  
    x has a y & (my x) exists => (my x) has a y
20  
21  
    assume x => x
22  
    
23  
    // General patterns in flight now:
24  
    //   my *
25  
    //   Ask something about *
26  
    //   pretend *
27  
    //   input is *
28  
    // (and more)
29  
    
30  
    Procedures
31  
    ----------
32  
    
33  
    Ask something about x => proc {
34  
      if (x exists):
35  
        ask (what is x?)
36  
      else:
37  
        ask (does x exist?)
38  
      for (y | x has a y):
39  
        assume ((the y of x) exists)
40  
        ask something about (the y of x)
41  
    }
42  
    
43  
    the answer to x is y => the answer to x is known
44  
    
45  
    ask x & the answer to x is known => don't (ask x)
46  
    
47  
    Ask x => proc {
48  
      print x
49  
      on input:
50  
        if (input is a valid answer to x):
51  
          store (the answer to x is input)
52  
    }
53  
    
54  
    (x exists) is a valid answer to (does x exist)
55  
    (x doesn't exist) is a valid answer to (does x exist)
56  
    (x is y) is a valid answer to (what is x)
57  
  ]];
58  
59  
  srecord LogicRule(lhs, rhs) {}
60  
  srecord And(a, b) {}
61  
  srecord If(condition, thenBlock, elseBlock) {}
62  
  srecord For(var, condition, body) {}
63  
64  
  transient Set<S> facts = linkedCISet();
65  
  transient Set<S> originalFacts;
66  
  transient new LinkedHashSet<LogicRule> logicRules;
67  
  transient new AllOnAll<LogicRule, S> rulesOnFacts;
68  
  transient new LS proceduresToRun;
69  
70  
  transient Set<S> vars = litciset("x", "y");
71  
72  
  void addLogicRule(LogicRule rule) {
73  
    if (logicRules.add(rule)) {
74  
      print("Got logic rule", rule);
75  
      rulesOnFacts.newA(rule); // to combine it with the facts
76  
    }
77  
  }
78  
79  
  void addFact(S fact) {
80  
    fact = trim(fact);
81  
    if (empty(fact)) ret;
82  
    fact = tok_deRoundBracket(fact);
83  
    // Check if it's a procedure
84  
    LS tok = javaTokWithBrackets(fact);
85  
    if (countCodeTokens(tok) == 2 && eqic(getCodeToken(tok, 0), "proc")
86  
      && isCurlyBracketed(getCodeToken(tok, 1))) {
87  
        // It's a procedure!
88  
        S proc = uncurly_keepSpaces(getCodeToken(tok, 1));
89  
        if (proceduresToRun.add(proc)) {
90  
          print("Got procedure:");
91  
          print(indentx("> ", proc));
92  
        }
93  
      }
94  
    else // It's a fact, not a procedure
95  
      if (facts.add(fact)) {
96  
        print("Got fact: " + fact);
97  
        rulesOnFacts.newB(fact); // to combine it with the rules
98  
      }
99  
  }
100  
101  
  void runProcedure(S proc) {
102  
    print("Running procedure.");
103  
    L commands = parseProcedure(proc);
104  
    runParsedProcedure(commands);
105  
  }
106  
107  
  void runParsedProcedure(L commands) {
108  
    for (O cmd : commands) {
109  
      if cmd is If(O condition, O thenBlock, O elseBlock) {
110  
        O blockToRun = checkCondition(condition) ? thenBlock : elseBlock;
111  
        runParsedProcedure(ll(blockToRun));
112  
      } else if cmd is For(O var, O condition, O body) {
113  
        // make a new logic rule and add it
114  
        // assume the variable is globally declared as a variable
115  
        addLogicRule(new LogicRule(condition, "proc {\n" + body + "\n}"));
116  
      } else if (cmd cast S) {
117  
        addFact(cmd);
118  
      } else if (cmd != null)
119  
        fail("Unimplemented command: " + cmd);
120  
    }
121  
  }
122  
123  
  bool checkCondition(O o) {
124  
    ret o instanceof S && contains(facts, (S) o);
125  
  }
126  
  
127  
  L parseProcedure(S proc) {
128  
    //printStruct(proc);
129  
    proc = withoutLinesEmptyAfterTrim(proc);
130  
    //printStruct(proc);
131  
    proc = autoUnindent(proc);
132  
    //printStruct(proc);
133  
    print(indentx("> ", proc));
134  
    
135  
    LS l = groupPythonStyleIndents(proc);
136  
    pnl("unpythonized ", l);
137  
138  
    new L out;
139  
    for i over l: {
140  
      S s = l.get(i);
141  
      LS tok = javaTokWithBrackets(s);
142  
      if (eqic(firstCodeToken(tok), "if")) {
143  
        assertEquals(s, ":", getCodeToken(tok, 2));
144  
        out.add(new If(deRoundBracket(getCodeToken(tok, 1)),
145  
          joinSubList(tok, 3*2), null));
146  
      } else if (eqic(firstCodeToken(tok), "else")) {
147  
        O last = last(out);
148  
        if (!last instanceof If) fail("Else without if");
149  
        assertEquals(s, ":", getCodeToken(tok, 1));
150  
        ((If) last).elseBlock = joinSubList(tok, 2*2);
151  
      } else if (eqic(firstCodeToken(tok), "for")) {
152  
        assertEquals(s, ":", getCodeToken(tok, 2));
153  
        S cond = getCodeToken(tok, 1);
154  
        // cond looks like: "(y | x has a y)"
155  
        cond = deRoundBracket(cond);
156  
        LS tok2 = javaTok(cond);
157  
        assertEquals(cond, "|", getCodeToken(tok2, 1));
158  
        S var = assertIdentifier(cond, getCodeToken(tok2, 0));
159  
        S actualCondition = trimJoinSubList(tok2, 2*2+1);
160  
        out.add(new For(var, actualCondition, joinSubList(tok, 3*2)));
161  
      } else
162  
        out.add(s);
163  
    }
164  
    pnl("Parsed procedure ", out);
165  
    ret out;
166  
  }
167  
168  
  O splitAtAmpersand2(S s) {
169  
    LS l = tok_splitAtAmpersand(s);
170  
    if (l(l) == 1) ret s;
171  
    ret new And(first(l), splitAtAmpersand2(join(" & ", dropFirst(l))));
172  
  }
173  
174  
  void applyLogicRuleToFact(LogicRule rule, S fact) {
175  
    O lhs = rule.lhs, rhs = rule.rhs;
176  
    O cond, remaining = null;
177  
    if lhs is And(O a, O b) {
178  
      cond = a;
179  
      remaining = b;
180  
    } else
181  
      cond = lhs;
182  
    
183  
    // now we match the condition with the fact
184  
    SS map = gazelle_zip((S) cond, fact);
185  
    if (map == null) ret; // no match
186  
    print("gazelle zip => " + map);
187  
188  
    // are only variables changed?
189  
    if (!allKeysAreInSet(map, vars))
190  
      ret /*with print("Non-variable changes, exiting")*/;
191  
192  
    // Now we have a proper mapping with the keys being variables!
193  
    print("Match.");
194  
195  
    // drop round brackets
196  
    // XXX? map = mapValues tok_deRoundBracket(map);
197  
198  
    // Apply mapping to right hand side
199  
    S rhs_replaced = join(replaceCodeTokensUsingMap(javaTok((S) rhs), map));
200  
    print(+rhs_replaced);
201  
202  
    if (remaining == null) {
203  
      // Add as fact
204  
      addFact(rhs_replaced);
205  
    } else {
206  
      // Apply mapping to remaning condition
207  
      S remaining_replaced = join(replaceCodeTokensUsingMap(javaTok((S) remaining), map));
208  
      addLogicRule(new LogicRule(remaining_replaced, rhs_replaced));
209  
    }
210  
  }
211  
212  
  start-thread {
213  
    // split into paragraphs and unindent
214  
215  
    LS paragraphs = map autoUnindent(map rtrim(splitAtEmptyLines(program)));
216  
    print("Got " + n2(paragraphs, "parapraph"));
217  
218  
    // print the parapraphs
219  
    print(joinWithEmptyLines(map(s -> indentx("> ", s), paragraphs)));
220  
221  
    // throw away comment-only and quoted paragraphs (assume it's a title)
222  
    LS paragraphs2 = antiFilter(paragraphs, s -> 
223  
      isSingleLine(trim(s)) && isQuoted(trim(s)) || countJavaTokens(s) == 0
224  
      || endsWith(rtrim(s), "----"));
225  
    print("Got " + n2(paragraphs2, "filtered paragraph"));
226  
    print(joinWithEmptyLines(map(s -> indentx("> ", s), paragraphs2)));
227  
228  
    // find fact paragraphs
229  
    
230  
    print(map allLinesAreUnindented(paragraphs2));
231  
    Pair<LS> p1 = filterAntiFilter(s ->
232  
      !isSingleLine(trim(s)) && allLinesAreUnindented(s), paragraphs2);
233  
    LS multiFactParagraphs = p1.a, paragraphs3 = p1.b;
234  
235  
    for (S para : multiFactParagraphs)
236  
      for (S s : tlft(para))
237  
        addFact(s);
238  
239  
    // find logic rules
240  
241  
    new LS paragraphs4;
242  
    for (S para : paragraphs3) {
243  
      PairS p = splitAtDoubleArrow_pair(para);
244  
      if (p == null) continue with paragraphs4.add(para);
245  
      addLogicRule(new LogicRule(splitAtAmpersand2(p.a), splitAtAmpersand2(p.b)));
246  
    }
247  
248  
    pnlStruct("Unparsed", paragraphs4);
249  
    originalFacts = cloneSet(facts);
250  
251  
    // Parsing done, now THINK
252  
253  
    think();
254  
  }
255  
256  
  bool doSomeLogic() {
257  
    bool anyAction;
258  
    Pair<LogicRule, S> p;
259  
    while not null (p = rulesOnFacts.next()) {
260  
      set anyAction;
261  
      //print("Combination: " + p);
262  
      applyLogicRuleToFact(p.a, p.b);
263  
    }
264  
    ret anyAction;
265  
  }
266  
267  
  void think {
268  
    int round = 0;
269  
    bool anyAction;
270  
271  
    while (round++ < 100) {
272  
      anyAction = false;
273  
      print("Logic round " + round);
274  
      while (doSomeLogic() && round++ < 100) set anyAction;
275  
276  
      for (S proc : getAndClearList(proceduresToRun)) {
277  
        set anyAction;
278  
        runProcedure(proc);
279  
      }
280  
    }
281  
282  
    // We're done logicking, so print all the facts gathered
283  
284  
    LS factsToPrint = listMinusList(facts, originalFacts);
285  
    pnlWithHeading("Facts I deduced", factsToPrint);
286  
287  
    // Print the actual output
288  
289  
    new LS output;
290  
    for (S fact : factsToPrint) {
291  
      LS tok = javaTokWithBrackets(fact);
292  
      if (countCodeTokens(tok) == 2 && eqic(getCodeToken(tok, 0), "print"))
293  
        // For the user, we print without all the round brackets
294  
        output.add(tok_dropRoundBrackets(getCodeToken(tok, 1)));
295  
    }
296  
    
297  
    pnlWithHeading("Bot Output", output);
298  
  }
299  
}

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1025576
Snippet name: Philosophy Bot 1 [OK]
Eternal ID of this version: #1025576/110
Text MD5: 891dadfe5c6e8843c206b37fac399027
Transpilation MD5: c00a4872d43174a71ed20bd94d9af748
Author: stefan
Category:
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-10-05 22:46:17
Source code size: 9003 bytes / 299 lines
Pitched / IR pitched: No / No
Views / Downloads: 684 / 2231
Version history: 109 change(s)
Referenced in: [show references]