The evaluated result to print.
Optionallimit: numberRows to show per table.
Nothing; writes to the console.
printAstProbe(evaluateCorpusAst("acid OR base", corpus), 10);
export function printAstProbe(result: AstProbeResult, limit?: number): void {
const rows = resolveLimit(limit);
console.info(
[
`[astTest] query="${result.query}"`,
` parsed: ${result.astText}${result.isAdvanced ? '' : ' (plain query — single term, not advanced syntax)'}`,
` options: scorer=${result.scorer} threshold=${result.threshold} fuzzyWords=${result.fuzzyWords}`,
` corpus: ${result.corpusSize} titles → ${result.matched.length} matched, ${result.dropped.length} dropped`,
` note: the scorer only ranks survivors; fuzzyWords/threshold decide who survives`,
].join('\n'),
);
// A NOT branch scores exactly `threshold`, and AND takes the min — so an
// `X AND NOT Y` query pins every survivor to the floor and the ranking is
// meaningless. Worth saying out loud rather than letting it look like a tie.
const distinctScores = new Set(result.matched.map((row) => row.score));
if (result.matched.length > 1 && distinctScores.size === 1) {
console.warn(
`[astTest] every survivor scored ${[...distinctScores][0]} — ranking is degenerate.` +
` A NOT branch contributes exactly the threshold and AND takes the min, so` +
` "X AND NOT Y" flattens all scores to the floor.`,
);
}
console.groupCollapsed(
`Matched — top ${Math.min(rows, result.matched.length)} of ${result.matched.length}`,
);
console.table(
result.matched.slice(0, rows).map((row) => ({
score: row.score,
title: row.title,
supplier: row.supplier,
source: row.source,
})),
);
console.groupEnd();
console.groupCollapsed(
`Dropped — top ${Math.min(rows, result.dropped.length)} of ${result.dropped.length}`,
);
console.table(
result.dropped.slice(0, rows).map((row) => ({
title: row.title,
supplier: row.supplier,
failedTerms: row.failedTerms.join(', '),
})),
);
console.groupEnd();
if (result.fuzzyWordsDelta.length > 0) {
console.groupCollapsed(`fuzzyWords flips — ${result.fuzzyWordsDelta.length} titles`);
console.table(
result.fuzzyWordsDelta.slice(0, rows).map((row) => ({
title: row.title,
supplier: row.supplier,
onlyWith: row.onlyWith,
})),
);
console.groupEnd();
}
}
Prints an AstProbeResult as console tables: the parsed AST, the ranked survivors, the drops with their failed terms, and any
fuzzyWordsflips.