!7 sS data = [[ -- Rule What does a driver do? => He drives, dummie. -- Test What does a catcher do? => He catches, dummie. -- Helper Table driver, drive, drives, driving sleeper, sleep, sleeps, sleeping murderer, murder, murders, murdering catcher, catch, catches, catching ]]; p-exp { SS sections = minusSignSectionsCI(data); pnlStruct(sections); LPair rules = ai_findDoubleArrowRulesAsPairs(sections.get("Rule")); GazelleEvalContext ctx = gazelle_stdEvalContext(map(rules, func(PairS inOut) -> T3 { t3(joinPairWithDoubleArrow(inOut), "", aGlobalID()) })); pnlStruct(ctx.engine.rules); final LL helperTable = map tok_splitAtComma(tlft(sections.get("Helper Table"))); //pnlStruct(helperTable); final Map> helperIndex = indexTwoDArrayIC(helperTable); final RuleEngine2.Rule rule = first(ctx.engine.rules); rule.massageMap = func(SS map, LS tokC, LS tokI, RuleEngine2_MatchedRule matched) -> SS { print("Massaging: " + map + " " + sfu(tokC) + " / " + sfu(tokI)); for (S t : codeTokens(matched.tokenize(rule.out))) { //print("Checking: " + t); if (map.containsKey(t)) continue; Pair idx = helperIndex.get(t); if (idx == null) continue; //print("Found: " + t); for (S key, val : cloneMap(map)) { int idx2 = indexOfIC(helperTable.get(idx.a), key); if (idx2 < 0) continue; Pair idxVal = helperIndex.get(val); print("Found: " + t + " <-> " + key); mapPut(map, t, _get(_get(helperTable, idxVal.a), idx.b)); } } ret map; }; new LS out; for (PairS inOut : ai_findDoubleArrowRulesAsPairs(sections.get("Test"))) { nlPrintNL(inOut.a); out.addAll(collect line(pnl(gazelle_getChildren(GazelleTree(ctx, inOut.a))))); } assertContainsIC(out, "He catches, dummie."); print("OK!"); }