!7 set flag DynModule. sclass Entry { //S originalRule, replacements, modifiedRule; S line; S conditions; S rule; S prediction; S judgement = ""; S struct; transient RuleEngine2_MatchedRule mr; sS _fieldOrder = "line conditions prediction judgement struct"; } cmodule TestRuleEngine2 > DynObjectTable { S input, processedInput; transient ReliableSingleThread rstCalc = dm_rstWithPostDelay(this, r calc, 500); transient int maxResults = 500; transient bool skipBadPredictions = true; S switchableFields() { ret "skipBadPredictions maxResults"; } start { set withSearcher; set fieldsInOrder; hideFields = litset('rule, 'mr); } 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; final new RuleEngine2 engine; engine.addRules2(dm_allRulesFromRulesModuleWithCommentsAndIDs()); // gather data for predictor MultiMap statementsByRule = ai_gazelle_indexStatementsByRule(dm_gazelle_statementsFromAppliedRules()); final Map dataByRule = mapValues ai_gazelle_analyzeStatementsForRule(multiMapToMap(statementsByRule)); final new LinkedHashSet queue; queue.add(input); final new Set done; final new Set lines; new L list; bool changes = true; while (l(list) < maxResults && nempty(queue)) { S input2 = popFirst(queue); done.add(input2); L l = ai_ruleEngine2_rulesForInput_3(engine, input2); l = sortByMethodDesc qualitySum(l); new L newList; for (RuleEngine2_MatchedRule r : l) { S modifiedRule = engine.formatForUser(r.applyMapping().asText()); S line = r.applyMappingTo(r.rule.out); addIfNotInOtherSet(queue, done, line); ai_gazelle_analyzeStatementsForRule_Data data = dataByRule.get(r.rule.globalID); S prediction = data == null ? null : ai_gazelle_predictor1_onData(r, data); if (skipBadPredictions && eq(prediction, 'bad)) continue; newList.add(nu(Entry, +line, conditions := join(" | " , r.remainingConditions), +prediction, rule := modifiedRule, struct := struct(r), mr := r)); } list.addAll(newList); for (Entry e : newList) { continue if e.mr == null; for (S line : ai_gazelle_makeIWantToKnows(e.mr)) { if (!lines.add(line)) continue; list.add(nu(Entry, +line, struct := "iwtk " + e.mr.rule.globalID)); // abusing the struct field addIfNotInOtherSet(queue, done, line); } } } setList(list); processedInput = input; } void saveEntry(Entry e) { dm_gazelle_saveAppliedRule( modifiedRule := e.rule, judgement := e.judgement, matchedRuleStruct := e.struct); } }