!7 srecord ToParse(O text) {} srecord StarPattern(O text) {} srecord QuotedString(O text) {} srecord PossibleReplacement(O a, O b) {} cprint { delegate TransformationTrail to TransformersOnObjects. transient new TransformersOnObjects too; switchable long maxSteps = 1000; transient F1 starPatternWrapper; start-thread { S ruleText = [[LineByUser("a * is something like *") => Assumption("* is a noun")]]; too.add(ToParse(ruleText)); // unpack ToParse too.addTransformer(func(ToParse x) { x.text }); too.addTransformer(f splitAtDoubleArrow_pair); too.addTransformer(f parseFunctionCall); too.addTransformer(f unquote, f quote); too.addTransformer(f pairA); too.addTransformer(f pairB); //too.addTransformer(f isStarPattern); // 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(func(S s) { isQuoted(s) ? QuotedString(unquote(s)) : null }); // Reintegrate replaced star patterns into rule text too.addTransformer(func(StarPattern s) { print("Found StarPattern: " + s); O quotedString = too.getTrailBy(s, starPatternWrapper).argument; too.PossibleReplacement(quotedString, s); null; }); too.addTransformer(voidfunc(PossibleReplacement r) { replaceInSource(r.a, r.b) }); stepAllWithStats(too, maxSteps); too.printWithTrails(); } // replace a in b inside of where a came from void replaceInSource(O a, O b) { print(formatFunctionCall replaceInSource(a, b)); // Find trails of a Cl trails2 = too.getTrails(a); fOr (TransformationTrail trail2 : trails2) { F1 back = too.getBackTransformer(trail2.transformer); print(" Path back: " + trail2 + " >> " + back); if (back != null) { // Backtransform b (if possible) and put in pool O c = callFIfActuallyCallable(back, b); print(" >> " + c); too.addObject(c, "replaceInSource"); } } } }