!7 cmodule TheoryMaker > DynConvo { /* 1. measurable features (fields of object) 2. higher level features (words the user throws in) 3. make theories (random statements) 4. check theories 1. show a random line 2. user types keyword 3. assign keyword to line line $a has keyword $x & line $a's text is $bla & line $y has text $bla => line $b might have keyword $x */ L msgs; // full dialog L shownMsgs; S featuresText; new Map, Bool> msg2label; transient new Map> featureExtractors; start-thread { for (S field : fields(Msg)) featureExtractors.put(field, o -> getOpt(o, field)); if (empty(msgs)) setField(msgs := mainCruddieLog()); showRandomMsg(); } void showMsgs(L l) { setField(shownMsgs := l); setMsgs(l); if (l(shownMsgs) == 1) { new LS out; for (S name, IF1 ex : featureExtractors) pcall { out.add(name + "=" + quoteIfString(ex.get(first(shownMsgs)))); } setField(featuresText := lines_rtrim(out)); } else setField(featuresText := ""); } void showRandomMsg { showMsgs(randomElementAsList(msgs)); } @Override void sendInput2(S s) { // treat input as a label if (l(shownMsgs) == 1) { Msg shown = first(shownMsgs); new Matches m; if "not ..." { S label = m.rest(); mapPutVerbose(+msg2label, pair(shown, label), false); } else { S label = s; mapPutVerbose(+msg2label, pair(shown, label), true); } change(); } } JComponent mainPart() { ret jhsplit(super.mainPart(), jCenteredSection("Features", dm_textArea featuresText())); } visual withCenteredButtons(super, "Show random msg", rThreadEnter showRandomMsg); }