!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) // 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 my x) exists) ask something about (the y of my 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) ]]; record LogicRule(lhs, rhs) {} record And(a, b) {} transient new LS facts; transient new L logicRules; transient new AllOnAll rulesOnFacts; transient Set vars = litciset("x", "y"); void addFact(S fact) { print("Got fact: " + fact); facts.add(fact); rulesOnFacts.newB(fact); } 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; 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."); // Apply mapping to right hand side S rhs_replaced = join(replaceCodeTokensUsingMap(javaTok((S) rhs), map)); print(+rhs_replaced); // Add as fact } 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 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); logicRules.add(print("Got logic rule", new LogicRule(splitAtAmpersand2(p.a), splitAtAmpersand2(p.b)))); } pnlStruct("Unparsed", paragraphs4); // Parsing done, now THINK think(); } void think { rulesOnFacts.newAs(logicRules); // add logic rules Pair p; int round = 1; bool anyAction; while (round++ < 100) { print("Logic round " + round); anyAction = false; while not null (p = rulesOnFacts.next()) { set anyAction; print("Combination: " + p); applyLogicRuleToFact(p.a, p.b); } if (!anyAction) break; } } }