Uses 911K of libraries. Click here for Pure Java version (5946L/31K).
!7 cmodule PhilosophyBot extends DynPrintLog { transient S program = [[ "memory" memory can mean RAM RAM has a size I have RAM input is x & x can mean y => pretend (input is y) input is x => activate facts containing x I have x => Ask something about (my x) I have x => (my x) exists x has a y & (my x) exists => (my x) has a y assume x => x // General patterns in flight now: // my * // Ask something about * // pretend * // input is * // (and more) Procedures ---------- Ask something about x => proc { if (x exists): ask (what is x?) else: ask (does x exist?) for (y | x has a y): assume ((the y of x) exists) ask something about (the y of x) } the answer to x is y => the answer to x is known ask x & the answer to x is known => don't (ask x) Ask x => proc { print x on input: if (input is a valid answer to x): store (the answer to x is input) } (x exists) is a valid answer to (does x exist) (x doesn't exist) is a valid answer to (does x exist) (x is y) is a valid answer to (what is x) ]]; srecord LogicRule(lhs, rhs) {} srecord And(a, b) {} srecord If(condition, thenBlock, elseBlock) {} srecord For(var, condition, body) {} transient Set<S> facts = linkedCISet(); transient Set<S> originalFacts; transient new LinkedHashSet<LogicRule> logicRules; transient new AllOnAll<LogicRule, S> rulesOnFacts; transient new LS proceduresToRun; transient Set<S> vars = litciset("x", "y"); void addLogicRule(LogicRule rule) { if (logicRules.add(rule)) { print("Got logic rule", rule); rulesOnFacts.newA(rule); // to combine it with the facts } } void addFact(S fact) { fact = trim(fact); if (empty(fact)) ret; fact = tok_deRoundBracket(fact); // Check if it's a procedure LS tok = javaTokWithBrackets(fact); if (countCodeTokens(tok) == 2 && eqic(getCodeToken(tok, 0), "proc") && isCurlyBracketed(getCodeToken(tok, 1))) { // It's a procedure! S proc = uncurly_keepSpaces(getCodeToken(tok, 1)); if (proceduresToRun.add(proc)) { print("Got procedure:"); print(indentx("> ", proc)); } } else // It's a fact, not a procedure if (facts.add(fact)) { print("Got fact: " + fact); rulesOnFacts.newB(fact); // to combine it with the rules } } void runProcedure(S proc) { print("Running procedure."); L commands = parseProcedure(proc); runParsedProcedure(commands); } void runParsedProcedure(L commands) { for (O cmd : commands) { if cmd is If(O condition, O thenBlock, O elseBlock) { O blockToRun = checkCondition(condition) ? thenBlock : elseBlock; runParsedProcedure(ll(blockToRun)); } else if cmd is For(O var, O condition, O body) { // make a new logic rule and add it // assume the variable is globally declared as a variable addLogicRule(new LogicRule(condition, "proc {\n" + body + "\n}")); } else if (cmd cast S) { addFact(cmd); } else if (cmd != null) fail("Unimplemented command: " + cmd); } } bool checkCondition(O o) { ret o instanceof S && contains(facts, (S) o); } L parseProcedure(S proc) { //printStruct(proc); proc = withoutLinesEmptyAfterTrim(proc); //printStruct(proc); proc = autoUnindent(proc); //printStruct(proc); print(indentx("> ", proc)); LS l = groupPythonStyleIndents(proc); pnl("unpythonized ", l); new L out; for i over l: { S s = l.get(i); LS tok = javaTokWithBrackets(s); if (eqic(firstCodeToken(tok), "if")) { assertEquals(s, ":", getCodeToken(tok, 2)); out.add(new If(deRoundBracket(getCodeToken(tok, 1)), joinSubList(tok, 3*2), null)); } else if (eqic(firstCodeToken(tok), "else")) { O last = last(out); if (!last instanceof If) fail("Else without if"); assertEquals(s, ":", getCodeToken(tok, 1)); ((If) last).elseBlock = joinSubList(tok, 2*2); } else if (eqic(firstCodeToken(tok), "for")) { assertEquals(s, ":", getCodeToken(tok, 2)); S cond = getCodeToken(tok, 1); // cond looks like: "(y | x has a y)" cond = deRoundBracket(cond); LS tok2 = javaTok(cond); assertEquals(cond, "|", getCodeToken(tok2, 1)); S var = assertIdentifier(cond, getCodeToken(tok2, 0)); S actualCondition = trimJoinSubList(tok2, 2*2+1); out.add(new For(var, actualCondition, joinSubList(tok, 3*2))); } else out.add(s); } pnl("Parsed procedure ", out); ret out; } O splitAtAmpersand2(S s) { LS l = tok_splitAtAmpersand(s); if (l(l) == 1) ret s; ret new And(first(l), splitAtAmpersand2(join(" & ", dropFirst(l)))); } void applyLogicRuleToFact(LogicRule rule, S fact) { O lhs = rule.lhs, rhs = rule.rhs; O cond, remaining = null; if lhs is And(O a, O b) { cond = a; remaining = b; } else cond = lhs; // now we match the condition with the fact SS map = gazelle_zip((S) cond, fact); if (map == null) ret; // no match print("gazelle zip => " + map); // are only variables changed? if (!allKeysAreInSet(map, vars)) ret /*with print("Non-variable changes, exiting")*/; // Now we have a proper mapping with the keys being variables! print("Match."); // drop round brackets // XXX? map = mapValues tok_deRoundBracket(map); // Apply mapping to right hand side S rhs_replaced = join(replaceCodeTokensUsingMap(javaTok((S) rhs), map)); print(+rhs_replaced); if (remaining == null) { // Add as fact addFact(rhs_replaced); } else { // Apply mapping to remaning condition S remaining_replaced = join(replaceCodeTokensUsingMap(javaTok((S) remaining), map)); addLogicRule(new LogicRule(remaining_replaced, rhs_replaced)); } } start-thread { // split into paragraphs and unindent LS paragraphs = map autoUnindent(map rtrim(splitAtEmptyLines(program))); print("Got " + n2(paragraphs, "parapraph")); // print the parapraphs print(joinWithEmptyLines(map(s -> indentx("> ", s), paragraphs))); // throw away comment-only and quoted paragraphs (assume it's a title) LS paragraphs2 = antiFilter(paragraphs, s -> isSingleLine(trim(s)) && isQuoted(trim(s)) || countJavaTokens(s) == 0 || endsWith(rtrim(s), "----")); print("Got " + n2(paragraphs2, "filtered paragraph")); print(joinWithEmptyLines(map(s -> indentx("> ", s), paragraphs2))); // find fact paragraphs print(map allLinesAreUnindented(paragraphs2)); Pair<LS> p1 = filterAntiFilter(s -> !isSingleLine(trim(s)) && allLinesAreUnindented(s), paragraphs2); LS multiFactParagraphs = p1.a, paragraphs3 = p1.b; for (S para : multiFactParagraphs) for (S s : tlft(para)) addFact(s); // find logic rules new LS paragraphs4; for (S para : paragraphs3) { PairS p = splitAtDoubleArrow_pair(para); if (p == null) continue with paragraphs4.add(para); addLogicRule(new LogicRule(splitAtAmpersand2(p.a), splitAtAmpersand2(p.b))); } pnlStruct("Unparsed", paragraphs4); originalFacts = cloneSet(facts); // Parsing done, now THINK think(); } bool doSomeLogic() { bool anyAction; Pair<LogicRule, S> p; while not null (p = rulesOnFacts.next()) { set anyAction; //print("Combination: " + p); applyLogicRuleToFact(p.a, p.b); } ret anyAction; } void think { int round = 0; bool anyAction; while (round++ < 100) { anyAction = false; print("Logic round " + round); while (doSomeLogic() && round++ < 100) set anyAction; for (S proc : getAndClearList(proceduresToRun)) { set anyAction; runProcedure(proc); } } // We're done logicking, so print all the facts gathered LS factsToPrint = listMinusList(facts, originalFacts); pnlWithHeading("Facts I deduced", factsToPrint); // Print the actual output new LS output; for (S fact : factsToPrint) { LS tok = javaTokWithBrackets(fact); if (countCodeTokens(tok) == 2 && eqic(getCodeToken(tok, 0), "print")) // For the user, we print without all the round brackets output.add(tok_dropRoundBrackets(getCodeToken(tok, 1))); } pnlWithHeading("Bot Output", output); } }
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: | 850 / 2448 |
Version history: | 109 change(s) |
Referenced in: | [show references] |