!7 /* Input: LineByUser("a * is something like *") => Assumption("* is a noun") Result: ToParse2. LineByUser(QuotedString("a * is something like *")) => Assumption("* is a noun") ToParse3. LineByUser("a * is something like *") => Assumption(QuotedString("* is a noun")) ToParse4. LineByUser(StarPattern(a * is something like *)) => Assumption("* is a noun") ToParse5. LineByUser(StarPattern(a * is something like *)) => Assumption(QuotedString("* is a noun")) ToParse6. LineByUser("a * is something like *") => Assumption(StarPattern(* is a noun)) ToParse7. LineByUser(QuotedString("a * is something like *")) => Assumption(StarPattern(* is a noun)) ...which is very good but missing the final combination LineByUser(StarPattern("a * is something like *")) => Assumption(StarPattern("* is a noun")) HOWEVER, in a previous transpilation today, THIS WORKED. Persisting the whole TransformersOnObjects object would work if we didn't make all these anonymous classes in the main script. */ srecord ToParse(O text) {} srecord StarPattern(O text) {} srecord QuotedString(O text) { toString { ret recordToString_quoted(this); }} srecord PossibleReplacement(O a, O b) {} cprint { delegate TransformationTrail to TransformersOnObjects. transient new TransformersOnObjects too; switchable long maxSteps = 10000; transient F1 starPatternWrapper, quotedStringMaker; start-thread { too.autoUnpackIterables = false; S ruleText = [[LineByUser("a * is something like *") => Assumption("* is a noun")]]; too.add(ToParse(ruleText)); // unpack ToParse too.addTransformer(func(ToParse x) { x.text }, func(O o) { ToParse(o) }); too.addTransformer(f splitAtDoubleArrow_pair, f joinPairWithDoubleArrow); too.addTransformer(f parseFunctionCall, func(Pair x) { unparseFunctionCall(x) }); too.addTransformer(f unquoteOrNull, f quote); too.addTransformer(f pairA, (p, o) -> replacePairA((Pair) p, o)); too.addTransformer(f pairB, (p, o) -> replacePairB((Pair) p, o)); // TODO: generalize to more elements. requires a change to // how backtransformers are found? too.addTransformer( f first, (list, element) -> cloneListReplacingElementAtIndex((L) list, 0, element)); too.addTransformer(f second, (list, element) -> cloneListReplacingElementAtIndex((L) list, 1, element)); // Suggest enclosing a star pattern string with StarPattern() too.addTransformer(starPatternWrapper = func(QuotedString s) { s.text instanceof S && isStarPattern((S) s.text) ? StarPattern(s.text) : null }); too.addTransformer(quotedStringMaker = func(S s) { isQuoted(s) ? QuotedString(unquote(s)) : null }, // The backtransformer may take a replacement thing // (so e.g. an instance of StarPattern). In that case // we just put it in verbatim func(O o) { o instanceof QuotedString ? quote(o/QuotedString.text) : o }); // Reintegrate replaced star patterns into rule text too.addTransformer(func(StarPattern s) { O madeFrom = too.getTrailBy(s, starPatternWrapper).argument; ret WithProbability(0.9, PossibleReplacement(madeFrom, s)); }); // Same with QuotedString too.addTransformer(func(QuotedString s) { O madeFrom = too.getTrailBy(s, quotedStringMaker).argument; ret WithProbability(0.8, PossibleReplacement(madeFrom, s)); }); too.addTransformer(func(PossibleReplacement r) { replaceInSource(r.a, r.b); null; }); stepAllWithStats(too, maxSteps); //too.printWithTrails(); print(); //too.printTransformers(); printStuff(); /*print("\nRestructuring.\n"); too = restructure_checkForProblems(too); printStuff();*/ } void printStuff { pnl("ToParse", map(instancesOf ToParse(too.getObjects()), t -> WithProbability(too.getProbability(t), t.text))); } // replace a in b inside of where a came from void replaceInSource(O a, O b) { print(formatFunctionCall_struct replaceInSource(a, b)); // Find trails of a Cl trails2 = too.getTrails(a); fOr (TransformationTrail trail2 : trails2) { F1 back = trail2.backTransformer; IF2 back2 = too.getBackTransformer(trail2.transformer); print(" Path back: " + trail2); if (back == null && back2 == null) print("NO BACK TRANSFORMER for " + trail2.transformer); else { // Backtransform b (if possible) and put in pool O c = back != null ? callFIfActuallyCallable(back, b) : callFIfActuallyCallable(back2, trail2.argument, b); if (c == null) continue; //print(" Made: " + sfu(c)); print(" Transformed " + sfu(trail2.argument) + " into " + sfu(c)); too.addObject(c, "replaceInSource"); // Follow up with more replacements back in the creation chain of a too.addObject(PossibleReplacement(trail2.argument, c), "replaceInSource"); } } } }