!7 concept DetectorEntry { S task; // e.g. "English vs German n=1000" S expression; // posNgram|posNgram|...^negNgram|negNgram|... S result; // double (0..1) } cmodule LanguageDetectionNGramScorers > DynCRUD { start { indexConceptFieldsCI(DetectorEntry, 'task, DetectorEntry, 'expression); crud.sorter = func(Cl l) -> L { sortByCalculatedFieldDesc(l, e -> pair(parseDoubleOpt(e.result), -l(e.expression))) }; crud.renderer = func(DetectorEntry e) -> Map { litorderedmap( "Expression" := e.expression, "Result / Length" := e.result + " / " + l(e.expression), "Task" := e.task) }; } // 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)); } LS expressionsForTaskByScore(S task) { ret pairsA(sortedByCalculatedFieldDesc(expressionsForTask(task), p -> parseDoubleOpt(p.b))); } }