sclass GazelleTree { L children; GazelleTree parent; double weight = 1, totalWeight; S line, lineType; S prediction, judgement; RuleEngine2_MatchedRule mr; bool isSplitNode; transient GazelleEvalContext ctx; *() {} *(S *line) {} // e.g. for rendering tree toString { new LS l; if (mr != null) for (S s : unnull(mr.remainingConditions)) l.add("if: " + s); addIfNempty(l, prediction); if (mr != null) l.add(mr.qualitySum() + " / " + formatDouble(mr.relativeQuality(), 2)); ret (isSplitNode ? "[split] " : "") + line + appendSquareBracketed(joinWithComma(l)); } // includes this node LS history() { new LS l; GazelleTree e = this; while (e != null) { l.add(e.line); e = e.parent; } ret reversed(l); } void add(GazelleTree child) { if (children == null) children = new L; child.parent = this; child.setContext(ctx); children.add(child); } void setContext(GazelleEvalContext ctx) { this.ctx = ctx; _add(ctx.linesSet, line); } }