ChemPal Documentation - v1.6.0
    Preparing search index...

    Function printAstProbe

    • Prints an AstProbeResult as console tables: the parsed AST, the ranked survivors, the drops with their failed terms, and any fuzzyWords flips.

      Parameters

      • result: AstProbeResult

        The evaluated result to print.

      • Optionallimit: number

        Rows to show per table.

      Returns void

      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();
      }
      }