!7 concept Sentence { S text; S action; } sclass Example { L tok; int start, end; *() {} *(L *tok, IntRange subjectTokens) { start = subjectTokens.start; end = subjectTokens.end; } } abstract sclass Guesser { abstract IntRange getSubjectTokens(L tok); void learn(L material) { for (Example e : material) learn(e); } void learn(Example e) {} } Guesser > G1 { IntRange getSubjectTokens(L tok) { ret new IntRange(0, 1); } } Guesser > G2 { new StringTree1 skipTree; IntRange getSubjectTokens(L tok) { int n = walkStringTreeToLeaf(allToLower(tok)); if (n >= 0) ret new IntRange(n, n+1); null; } void learn(Example e) { if (e.start > 0) addToTree(skipTree, allToLower(takeFirst(tok, e.start))); } } p { loadConceptsFrom(#1008607); L material = learningMaterial(); pnlStruct(material); checkGuesser(material, new G1); checkGuesserAfterFullLearn(material, new G2); } svoid checkGuesser(L testMaterial, Guesser g) { int score = 0, n = 0; for (Example e : testMaterial) { IntRange r = cast pcall(g, "getSubjectTokens", e.tok); if (eq(e.subjectTokens, r)) ++score; ++n; } printScore(struct(g), score, n); } svoid checkGuesserAfterFullLearn(L testMaterial, Guesser g) { g.learn(testMaterial); checkGuesser(testMaterial, g); } static L learningMaterial() { L out = new L; for (Sentence s) { if (s.action == null) continue; IntRange r = ai_parseSubjectAction(s.action); if (r != null) { L tok = codeTokens(nlTok5(s.text)); out.add(Example(tok, charRangeToTokenRange(tok, r))); } } ret out; }