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)) { new Matches m; // in: output($x1, $x2 [...] and $x_n) do { L tok = out.argText(); if (!jmatch("*, * [...] * *", 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("joinWithComma_specialLast((LS) call(ai_context(), 'getList, " + quote(x) + "), " + quote(joinSubList(tok, l(tok)-5, l(tok)-2)) + ")"); } 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)) { S s = ai_expandPatternForAAndAn(o.arg.text()); if (s != null) o.arg = Sentence2(s); } }); } while (neq(rendered, str(r))); ret r; }