!7 set flag DynModule. sclass Entry { //S originalRule, replacements, modifiedRule; S line; S conditions; S rule; S judgement = ""; S struct; transient RuleEngine2_MatchedRule mr; sS _fieldOrder = "line conditions judgement struct"; } cmodule TestRuleEngine2 > DynObjectTable { S input, processedInput; transient ReliableSingleThread rstCalc = dm_rstWithPostDelay(this, r calc, 500); transient int maxResults = 500; start { set fieldsInOrder; hideFields = litset('rule, 'mr); } visualize { JComponent tf = dm_textField('input); onChangeAndNow(tf, rstCalc); ret northCenterAndSouthWithMargins( centerAndEastWithMargin( tf, jbutton("Make rule...", rThread makeRule)), 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(); e.judgement = judgement; fireDataChanged(); saveEntry(e); }; } void calc { S input = this.input; final new RuleEngine2 engine; engine.addRules2(dm_allRulesFromRulesModuleWithCommentsAndIDs()); 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); list.addAll(map(l, func(RuleEngine2_MatchedRule r) -> Entry { S modifiedRule = engine.formatForUser(r.applyMapping().asText()); S line = r.applyMappingTo(r.rule.out); addIfNotInOtherSet(queue, done, line); ret nu(Entry, +line, conditions := join(" | " , r.remainingConditions), rule := modifiedRule, struct := struct(r), mr := r); })); for (S line : ai_gazelle_makeIWantToKnows((L) collectNonNulls mr(list))) { if (!lines.add(line)) continue; list.add(nu(Entry, +line)); addIfNotInOtherSet(queue, done, line); } } setList(list); processedInput = input; } void saveEntry(Entry e) { dm_requireAndCall("#1021413/AppliedRules", 'uniqConcept, litobjarrayAsObject( modifiedRule := e.rule, judgement := e.judgement, matchedRuleStruct := e.struct)); } void makeRule { final JTextField tf1 = jtextfield(input); final JTextField tf2 = jtextfield(input); showFormTitled("Make a rule", "When", tf1, "Then", tf2, r { Pair p = dm_gazelle_addRule(gtt(tf1), gtt(tf2)); infoBox(p.b ? "Rule " + p.a + " added" : "Rule already there: " + p.a); }); } }