static SS nlLogic_expandMacros_funcShortNames = litmap( 'o, 'output, 'i, 'input); // changes original rules static void nlLogic_expandMacros(L rules) { for (IfThen rule : unnull(rules)) pcall { nlLogic_expandMacros(rule); } } static IfThen nlLogic_expandMacros(IfThen r) { if (r == null) ret r; int varCount = 0; S rendered; do { ping(); rendered = str(r); nlLogic_visit(r, voidfunc(O o) { if (o cast Func) { S name = nlLogic_expandMacros_funcShortNames.get(o.name); if (name != null) o.name = name; } }); Exp out = r.out; if (out cast Func) { S name = out.name; if (eq(name, 'sayIfTrue)) { r.out = Func('output, out.arg); r.in = And(r.in, Func('fact, out.arg)); } else if (eq(name, 'inputToFact)) { r.out = Func('fact, out.arg); r.in = nlLogic_and(Func('input, restructure(out.arg)), r.in); } else if (eqOneOf(name, 'outputEval, 'evalOutput)) { S var = "$_" + ++varCount; r.out = Func('output, Sentence2(var)); r.in = And(r.in, Eq(Sentence2(var), Func('eval, out.arg))); //print("Rewritten rule => " + sfu(r)); } else if (eq(name, 'output)) { do { // in: output(... $x1, $x2 [...] and $x_n ...) S pat = "*, * [...] * *"; T3 t = jextractWithRests(pat, out.argText()); if (t == null) break; new Matches m; L tok = javaTok(t.b); if (!jmatch(pat, tok, m)) break; S x1 = m.get(0); if (!isDollarVar(x1) || !endsWith(x1, "1")) break with print("x1"); S x = dropSuffix("1", x1); if (!eq(m.get(1), x + "2")) break with print("x2"); //S lastSep = m.get(2); if (!eq(m.get(3), x + "_n")) break with print("x_n"); // out: outputEval(joinWithComma_specialLast((LS) call(ai_context(), 'getList, "x"), " and ")) out.name = 'outputEval; out.arg = Sentence2(quote(t.a) + " + joinWithComma_specialLast((LS) call(ai_context(), 'getList, " + quote(x) + "), " + quote(joinSubList(tok, l(tok)-5, l(tok)-2)) + ")" + " + " + quote(t.c)); } while (false); } } // LHS only nlLogic_visit(r.in, voidfunc(O o) { // english a/an magic if (o cast Func) if (eqOneOf(o.name, 'input, 'fact)) { if (contains(o.options, 're)) o.arg = Sentence2(ctxREToJavaRE(ctxExpandMacros(o.arg.text(), ctxMacros()))); else { S s = ai_expandPatternForAAndAn(o.arg.text()); if (s != null) o.arg = Sentence2(s); } } else if (eq(o.name, 'unresolvedFact)) { o.name = 'fact; o.arg = Sentence2("Unresolved fact: " + o.arg.text()); } else if (eq(o.name, 'evalTrue)) { o.name = 'eval; o.arg = Sentence2(tok_addSemicolon(o.arg.text()) + " ret true;"); } }); } while (neq(rendered, str(r))); ret r; }