!7 concept DetectorEntry { S task; // e.g. "English vs German n=1000" S expression; // posNgram|posNgram|...^negNgram|negNgram|... S result; // double (0..1) } module LanguageDetectionNGramScorers > DynCRUD { start { indexConceptFieldsCI(DetectorEntry, 'task, DetectorEntry, 'expression); crud.sorter = func(Cl l) -> L { sortByCalculatedFieldDesc(l, e -> parseDoubleOpt(e.result)); }; } // API void saveResult(S task, S expression, S result) { cset(uniqCI DetectorEntry(+expression, +task), +result); } // pairs of expression + result LPairS expressionsForTask(S task) { ret map(conceptsWhereCI DetectorEntry(+task), e -> pair(e.expression, e.result)); } }