!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. Mom is edible. => fail Mom is a tool. => fail anchovis is a tool. => fail anchovis is a person. => fail ducks is a tool. => fail ducks is a person. => fail my hands is edible. => fail my hands is a person. => fail ---- Input I ate pizza with mom. I ate pizza with anchovis. I ate pizza with ducks. I ate pizza with my hands. ]]; static Set incompatible = litciset("used/ate"); static int minScore = 50; sbool printMappings, printGroupedData, printRejectedVars; static LPair rules; static Map> ruleVariables = new Map; p-exp { centerBigTTConsole(); S data = mapEachLine ai_groupSimplestNounPhrases(main.data); if (printGroupedData) print(data); SS sections = asCIMap(minusSignsSections(data)); LS rulesRaw = ai_splitEntriesWithMultipleDoubleArrows(splitAtEmptyLines(sections.get("Rules"))); rules = mapNonNulls splitAtDoubleArrow_pair(rulesRaw); for (PairS rule : rules) ruleVariables.put(rule, ai_wordsInBothSidesOfPair_uncurly(rule)); pnlStruct(ruleVariables); for (S input : tlft(sections.get("Input"))) { print("\nInput: " + tok_dropCurlyBrackets(input)); interpretRecursively(input, 5, true); } } svoid interpretRecursively(S input, int level, bool newLines) { if (level <= 0) ret; L> interpretations = interpretations(input); temp tempIndent(); for (Pair in : interpretations) { if (newLines) print(); printInterpretations(ll(in), newLines ? "Interpretation: " : " => "); interpretRecursively(in.a, level-1, false); } } svoid printInterpretations(LPair interpretations, S prefix) { for (Pair p : interpretations) print(prefix + ai_superSimpleVerbCorrector(tok_dropCurlyBrackets(p.a))); } static LS defaultParse(S s) { ret codeTokens_lazy_uncurly(javaTokWithBrackets_cached(s)); } static LPair interpretations(S input) { new MultiSet ms; LS tokI = defaultParse(input); new L> interpretations; 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)-ai_mapPenaltyWithIncompatibleWordsList(map, incompatible, 1); L nonVars = withoutDollarVars(listMinusSet(keys(map), ruleVariables.get(rule))); if (printRejectedVars && nempty(nonVars)) print("Rejected vars: " + nonVars); if (nempty(nonVars)) score = 0; //score -= l(nonVars); ms.add(rule, score+1); if (printMappings) print(" " + reverseMapCI_joinDuplicatesWithPlus(map) + " | " + rule.a); // Make consequence S c = rule.b; c = join(mapCodeTokens(javaTok(c), func(S s) -> S { getOrKeep_tryUncurlied(map, s) })); // TODO: multiple grouping levels c = join(mapCodeTokens(javaTokWithBrackets(c), func(S s) -> S { getOrKeep_tryUncurlied(map, s) })); int percent = ratioToIntPercent(score, l(tokR)); if (percent >= minScore) addPair(interpretations, c, percent); } ret sortByPairBDesc(interpretations); }