persistable sclass NLABlock { S text; // original text LS lines; // same, split into lines Set entities; // entities L parsedLines; sclass Line { S text; int index; Entity introducedEntity; L proposition; // fragments toString { ret joinWithSpace(proposition) + (introducedEntity == null ? "" : " => " + introducedEntity); } } sclass Entity extends Cluster { S definedInLine; *(S name, S *definedInLine) { addSynonym(name); } } *(S *text) {} bool isParsed() { ret parsedLines != null; } toString { ret !isParsed() ? text : lines_rtrim(parsedLines); } L propositions() { ret filter(parsedLines, line -> line.introducedEntity == null); } }