!7 sS data = [[ ---- Rules I ate pizza with a fork. => I used a fork to eat pizza. I used a fork to eat pizza. => I used a fork. I used a fork. => A fork is a tool. I ate pizza with pepperoni. => {I ate pizza} and {the pizza had pepperoni on it}. The pizza had pepperoni on it. => Pepperoni is edible. I ate pizza with Bob. => {I ate pizza} and {Bob was with me}. Bob was with me. => Bob is a person. A and B. => A. A and B => B. nicer wording for {is it true that {Mom is a person.}?} = {is Mom a person?} nicer wording for {is it true that {Mom is edible.}?} = {is Mom edible?} ---- Input I ate pizza with mom. I ate pizza with anchovis. I ate pizza with ducks. I ate pizza with my hands. ]]; p-exp { centerBigTTConsole(); S data = mapEachLine ai_groupSimplestNounPhrases(main.data); SS sections = asCIMap(minusSignsSections(data)); LS rulesRaw = splitAtEmptyLines(sections.get("Rules")); //pnl(rulesRaw); LPair rules = mapNonNulls splitAtDoubleArrow_pair(rulesRaw); //pnlStruct(rules); print(); LS inputs = tlft(sections.get("Input")); for (S input : inputs) { print("\n" + input + "\n"); new MultiSet ms; LS tokI = defaultParse(input); for (PairS rule : rules) { LS tokR = defaultParse(rule.a); final SS map = ciMapWithoutKeysEqualToValues(zipTwoListsToCIMap_strict(tokR, tokI)); if (map == null) continue; // Found matching rule int score = l(tokR)-l(map); ms.add(rule, score+1); //print(" " + reverseMapCI_joinDuplicatesWithPlus(map) + " | " + rule.a); // Make consequence LS tokC = javaTok(rule.b); tokC = mapCodeTokens(tokC, func(S s) -> S { getOrKeep_tryUncurlied(map, s) }); print(" Interpretation (score " + strRatioToPercent(score, l(tokR)) + "): " + tok_dropCurlyBrackets(join(tokC))); } //print(" Best rules: " + renderMultiSet(msMapKeys pairA(ms))); } } static LS defaultParse(S s) { ret codeTokens_lazy_uncurly(javaTokWithBrackets_cached(s)); }