!7 set flag DynModule. sclass GazelleTree { L children; GazelleTree parent; double weight = 1, totalWeight; S line; S prediction; RuleEngine2_MatchedRule mr; transient EvalContext ctx; *() {} *(S *line) {} toString { new LS l; addIfNempty(l, prediction); if (mr != null) l.add(str(mr.qualitySum())); ret line + appendSquareBracketed(joinWithComma(l)); } } sclass EvalContext { RuleEngine2 engine; Map dataByRule; } static L gt_getChildren(GazelleTree tree) { if (tree == null) null; if (tree.children != null) ret tree.children; // make rule engine etc. if (tree.ctx == null) { new EvalContext ctx; tree.ctx = ctx; ctx.engine = new RuleEngine2; ctx.engine.addRules2(dm_allRulesFromRulesModuleWithCommentsAndIDs()); // gather data for predictor MultiMap statementsByRule = ai_gazelle_indexStatementsByRule(dm_gazelle_statementsFromAppliedRules()); ctx.dataByRule = mapValues ai_gazelle_analyzeStatementsForRule(multiMapToMap(statementsByRule)); } EvalContext ctx = tree.ctx; new L children; L l = sortByMethodDesc qualitySum(ai_ruleEngine2_rulesForInput_3(tree.ctx.engine, tree.line)); for (RuleEngine2_MatchedRule r : l) { S line = r.applyMappingTo(r.rule.out); GazelleTree child = new(line); child.parent = tree; child.ctx = tree.ctx; child.mr = r; ai_gazelle_analyzeStatementsForRule_Data data = ctx.dataByRule.get(r.rule.globalID); child. prediction = data == null ? null : ai_gazelle_predictor1_onData(r, data); children.add(child); } ret tree.children = children; } cmodule TestRuleEngine2 > DynSCP { S input, processedInput; transient ReliableSingleThread rstCalc = dm_rstWithPostDelay(this, r calc, 500); transient int maxResults = 500; transient bool skipBadPredictions = true; transient JTree jTree; transient GazelleTree root; S switchableFields() { ret "skipBadPredictions maxResults"; } visualize { JComponent tf = dm_textField('input); onChangeAndNow(tf, rstCalc); ret northCenterAndSouthWithMargins( centerAndEastWithMargin( tf, jbutton("Make rule...", rThread { dm_gazelle_newRuleDialog(input, input) })), super.visualize(), rightAlignedButtons( /*tableDependentButton(table(), "Mark good", rMark('good)), tableDependentButton(table(), "Mark bad", rMark('bad)), tableDependentButton(table(), "Mark funny", rMark('funny))*/ )); } Runnable rMark(fS judgement) { ret rThread { /*Entry e = selected(); print("Selected: " + e); e.judgement = judgement; fireDataChanged(); saveEntry(e);*/ }; } void calc { S input = this.input; root = new GazelleTree(input); setComponent(jscroll(jTree = jDynamicTree(root, func(GazelleTree tree) -> L { gt_getChildren(tree) }))); jtree_openRootNode(jTree); processedInput = input; } }