Skip to content

Commit 26a1868

Browse files
andre15silvaclaude
andcommitted
paper: rename probes, add median stats, fix figure labels
- Rename probe properties: Well-formedness, Full Correctness, Partial Correctness, Regression - Add median steps/edits columns (incl. pooled total) to dataset stats table - layer_auc_grid: per-series legend markers, x/y tick numbers on all panels, greyer random baseline clear of annotations - dataset turns barplot: horizontal, shortened model labels Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent a364580 commit 26a1868

3 files changed

Lines changed: 77 additions & 31 deletions

File tree

paper/dataset_stats_table.tex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
\begin{table}[t]
22
\centering
33
\footnotesize
4-
\caption{Dataset statistics per model and benchmark. \#Traj.\ counts all agent runs; $\geq$50 counts trajectories reaching that turn threshold (the length filter used in the lookahead experiments). \#Edits is the total number of code edits across all trajectories. $\geq$2 edits counts trajectories with at least two edits. $\#h_t$ is the total number of collected hidden-state vectors.}
4+
\caption{Dataset statistics per model and benchmark. \#Traj.\ counts all agent runs; $\geq$50 counts trajectories reaching that turn threshold (the length filter used in the lookahead experiments). Med.\ steps is the median number of turns per trajectory. \#Edits is the total number of code edits across all trajectories. $\geq$2 edits counts trajectories with at least two edits. Med.\ edits is the median number of edits per trajectory. $\#h_t$ is the total number of collected hidden-state vectors.}
55
\label{tab:dataset_stats}
66
\resizebox{\columnwidth}{!}{
7-
\begin{tabular}{llrrrrr}
7+
\begin{tabular}{llrrrrrrr}
88
\toprule
9-
Model & Benchmark & \#Traj. & $\geq$50 steps & \#Edits & $\geq$2 edits & $\#h_t$ \\
9+
Model & Benchmark & \#Traj. & $\geq$50 steps & Med.\ steps & \#Edits & $\geq$2 edits & Med.\ edits & $\#h_t$ \\
1010
\midrule
11-
\multirow{2}{*}{\texttt{Laguna}} & Verified & 4,991 & 2,837 & 14,545 & 2,974 & 7.5M \\
12-
& Pro & 6,921 & 4,159 & 36,648 & 5,273 & 7.6M \\
11+
\multirow{2}{*}{\texttt{Laguna}} & Verified & 4,991 & 2,837 & 55 & 14,545 & 2,974 & 2 & 7.5M \\
12+
& Pro & 6,921 & 4,159 & 56 & 36,648 & 5,273 & 4 & 7.6M \\
1313
\addlinespace
14-
\multirow{2}{*}{\texttt{Qwen3.6}} & Verified & 4,998 & 2,001 & 9,730 & 2,161 & 3.8M \\
15-
& Pro & 5,804 & 3,186 & 18,557 & 3,682 & 3.5M \\
14+
\multirow{2}{*}{\texttt{Qwen3.6}} & Verified & 4,998 & 2,001 & 39 & 9,730 & 2,161 & 1 & 3.8M \\
15+
& Pro & 5,804 & 3,186 & 54 & 18,557 & 3,682 & 2 & 3.5M \\
1616
\midrule
17-
\multicolumn{2}{l}{Total} & 22,714 & 12,183 & 79,480 & 14,090 & 22.4M \\
17+
\multicolumn{2}{l}{Total} & 22,714 & 12,183 & 52 & 79,480 & 14,090 & 2 & 22.4M \\
1818
\bottomrule
1919
\end{tabular}
2020
}

paper/style.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@
5858
"regressions": "◆",
5959
}
6060
PROPERTY_LABELS = {
61-
"syntactic": "Syntactic Correctness",
62-
"semantic": "Semantic Correctness",
63-
"reduced": "Reduced Failing Tests",
64-
"regressions": "Introduced Regressions",
61+
"syntactic": "Well-formedness",
62+
"semantic": "Full Correctness",
63+
"reduced": "Partial Correctness",
64+
"regressions": "Regression",
6565
}
6666

6767
# --- Heatmap ---

run_paper_figures.py

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,12 +1057,17 @@ def plot_layer_auc_grid(
10571057
)
10581058
axes_flat = axes.flatten()
10591059

1060+
# Per-dataset-series markers: encode the legend entries (the data series),
1061+
# NOT the program property. Chosen distinct from the property markers
1062+
# ({^, o, s, D} used for the probe names) so the two encodings don't clash.
1063+
SERIES_MARKERS = ["P", "X", "*", "h"] # filled plus, filled x, star, hexagon
1064+
10601065
legend_handles: list = []
10611066
legend_built = False
10621067

1063-
for ax, probe in zip(axes_flat, probes):
1064-
prop_key = PROBE_TO_PROPERTY.get(probe)
1065-
prop_marker = _style.PROPERTY_MARKERS[prop_key] if prop_key else "o"
1068+
for idx, (ax, probe) in enumerate(zip(axes_flat, probes)):
1069+
row, col = idx // 2, idx % 2
1070+
series_i = 0
10661071

10671072
for run_id, label in zip(run_ids, run_labels):
10681073
all_res = _load(results_dir, run_id, probe)
@@ -1074,7 +1079,9 @@ def plot_layer_auc_grid(
10741079

10751080
is_qwen = "qwen" in run_id
10761081
color = _style.COLORS["qwen_verified" if is_qwen else "laguna_verified"]
1077-
line, = ax.plot(xs, ys, linestyle="-", marker=prop_marker, markersize=4,
1082+
marker = SERIES_MARKERS[series_i % len(SERIES_MARKERS)]
1083+
series_i += 1
1084+
line, = ax.plot(xs, ys, linestyle="-", marker=marker, markersize=5,
10781085
color=color, linewidth=1.4, label=label)
10791086
if not legend_built:
10801087
legend_handles.append(line)
@@ -1086,14 +1093,16 @@ def plot_layer_auc_grid(
10861093
layer_aucs = _layer_means(all_res, "test_auc", layers)
10871094
xs = [l for l in layers if not math.isnan(layer_aucs.get(l, float("nan")))]
10881095
ys = [layer_aucs[l] for l in xs]
1089-
color = _style.COLORS["qwen_pro" if "qwen" in extra_run_id else "laguna_pro"]
1090-
line, = ax.plot(xs, ys, linestyle="--", marker=prop_marker, markersize=4,
1096+
color = _style.COLORS["qwen_pro" if "qwen" in extra_run_id else "laguna_pro"]
1097+
marker = SERIES_MARKERS[series_i % len(SERIES_MARKERS)]
1098+
series_i += 1
1099+
line, = ax.plot(xs, ys, linestyle="--", marker=marker, markersize=5,
10911100
color=color, alpha=0.85, linewidth=1.4, label=extra_label)
10921101
if not legend_built:
10931102
legend_handles.append(line)
10941103

1095-
rand_line = ax.axhline(0.5, linestyle=":", color=_style.COLORS["baseline"],
1096-
linewidth=1.0, label="Random")
1104+
rand_line = ax.axhline(0.5, linestyle=(0, (1, 1.5)), color="#C2C2C2",
1105+
linewidth=1.4, zorder=0.5, label="Random")
10971106
if not legend_built:
10981107
legend_handles.append(rand_line)
10991108
legend_built = True
@@ -1102,14 +1111,28 @@ def plot_layer_auc_grid(
11021111
ax.set_xticks(layers)
11031112
ax.set_xticklabels([str(_layer_label(l)) for l in layers])
11041113
ax.set_ylim(bottom=0.45, top=1.0)
1105-
ax.set_ylabel("AUC")
11061114

1107-
# n_test annotation — top-right of each panel
1115+
# Keep tick numbers readable on each panel without crossing the grid:
1116+
# x-numbers on the top row too, y-numbers ("units") on the right column.
1117+
ax.tick_params(labelbottom=True)
1118+
if col == 1:
1119+
ax.tick_params(labelright=True, labelleft=False)
1120+
if col == 0:
1121+
ax.set_ylabel("AUC")
1122+
1123+
# n_test annotation — top-right corner, clear of the 0.5 baseline
11081124
for run_id in run_ids:
11091125
if "shuffled" not in run_id:
11101126
res = _load(results_dir, run_id, probe)
11111127
if res:
1112-
_annotate_n_test(ax, _n_test_from_results(res))
1128+
n = _n_test_from_results(res)
1129+
s = _fmt_n(n)
1130+
if s:
1131+
ax.annotate(f"n = {s} $h_t$",
1132+
xy=(1, 1), xycoords="axes fraction",
1133+
xytext=(-4, -4), textcoords="offset points",
1134+
ha="right", va="top", fontsize=7,
1135+
color="#999999", annotation_clip=False)
11131136
break
11141137

11151138
# x-label only on bottom row
@@ -1350,7 +1373,7 @@ def _compute_edit_stats(label_dir: Path, cache_path: Path | None = None) -> dict
13501373
continue
13511374
counts.append(sum(1 for e in d.get("edits", []) if e.get("cmd_idx") != -1))
13521375
if not counts:
1353-
result = {"total": 0, "ge2": 0, "median": 0, "q25": 0, "q75": 0}
1376+
result = {"total": 0, "ge2": 0, "median": 0, "q25": 0, "q75": 0, "counts": []}
13541377
else:
13551378
s = sorted(counts)
13561379
n = len(s)
@@ -1360,6 +1383,7 @@ def _compute_edit_stats(label_dir: Path, cache_path: Path | None = None) -> dict
13601383
"median": s[n // 2],
13611384
"q25": s[n // 4],
13621385
"q75": s[3 * n // 4],
1386+
"counts": s, # raw per-trajectory edit counts, for pooled medians
13631387
}
13641388
if cache_path:
13651389
cache_path.parent.mkdir(parents=True, exist_ok=True)
@@ -1486,7 +1510,13 @@ def plot_dataset_turns(
14861510
ax.axhline(15, color="#555555", linestyle="--", linewidth=0.9, label="15 turns")
14871511
ax.axhline(50, color="#222222", linestyle=":", linewidth=0.9, label="50 turns")
14881512
ax.set_xticks(range(1, len(all_labels) + 1))
1489-
ax.set_xticklabels(all_labels, fontsize=8)
1513+
# Shorten the model name (e.g. "Qwen3.6-35B-A3B" -> "Qwen3.6") so the
1514+
# horizontal tick labels don't overlap between adjacent ticks.
1515+
def _short_label(label: str) -> str:
1516+
parts = label.split("\n")
1517+
parts[0] = parts[0].split("-")[0]
1518+
return "\n".join(parts)
1519+
ax.set_xticklabels([_short_label(l) for l in all_labels], fontsize=8)
14901520
ax.set_ylabel("Turns")
14911521
ax.set_ylim(top=100)
14921522
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
@@ -1619,8 +1649,10 @@ def build_dataset_stats_table(
16191649
r"\#Traj.\ counts all agent runs; "
16201650
r"$\geq$50 counts trajectories reaching that turn threshold "
16211651
r"(the length filter used in the lookahead experiments). "
1652+
r"Med.\ steps is the median number of turns per trajectory. "
16221653
r"\#Edits is the total number of code edits across all trajectories. "
16231654
r"$\geq$2 edits counts trajectories with at least two edits. "
1655+
r"Med.\ edits is the median number of edits per trajectory. "
16241656
r"$\#h_t$ is the total number of collected hidden-state vectors."
16251657
)
16261658

@@ -1636,14 +1668,16 @@ def _fmt_states(n: int) -> str:
16361668
r"\caption{" + caption + r"}" "\n"
16371669
r"\label{tab:dataset_stats}" "\n"
16381670
r"\resizebox{\columnwidth}{!}{" "\n"
1639-
r"\begin{tabular}{llrrrrr}" "\n"
1671+
r"\begin{tabular}{llrrrrrrr}" "\n"
16401672
r"\toprule" "\n"
1641-
r"Model & Benchmark & \#Traj. & $\geq$50 steps & \#Edits & $\geq$2 edits & $\#h_t$ \\" "\n"
1673+
r"Model & Benchmark & \#Traj. & $\geq$50 steps & Med.\ steps & \#Edits & $\geq$2 edits & Med.\ edits & $\#h_t$ \\" "\n"
16421674
r"\midrule" "\n"
16431675
)
16441676

16451677
rows = []
16461678
tot_traj = tot_gt50 = tot_ge2 = tot_edits = tot_states = 0
1679+
all_turns: list[int] = [] # pooled across configs, for the total median
1680+
all_edits: list[int] = []
16471681

16481682
i = 0
16491683
while i < len(configs):
@@ -1657,33 +1691,45 @@ def _fmt_states(n: int) -> str:
16571691
mc = model_cell if first_in_group else ""
16581692
first_in_group = False
16591693
if cfg.get("placeholder"):
1660-
rows.append(rf"{mc} & {bm} & " + r"\multicolumn{5}{c}{---} \\")
1694+
rows.append(rf"{mc} & {bm} & " + r"\multicolumn{7}{c}{---} \\")
16611695
else:
16621696
stats = cfg["gen_stats"]
16631697
n_traj = len(stats)
16641698
gt50 = sum(1 for s in stats if s["turns"] >= 50)
1699+
turns = sorted(s["turns"] for s in stats)
1700+
med_steps = turns[len(turns) // 2] if turns else 0
16651701
es = cfg["edit_stats"]
1702+
med_edits = es.get("median", 0)
16661703
n_states = cfg["n_states"]
16671704

16681705
tot_traj += n_traj
16691706
tot_gt50 += gt50
16701707
tot_ge2 += es.get("ge2", 0)
16711708
tot_edits += es["total"]
16721709
tot_states += n_states
1710+
all_turns.extend(s["turns"] for s in stats)
1711+
all_edits.extend(es.get("counts", []))
16731712

16741713
rows.append(
16751714
rf"{mc} & {bm} & "
1676-
rf"{n_traj:,} & {gt50:,} & {es['total']:,} & {es.get('ge2', 0):,} & {_fmt_states(n_states)} \\"
1715+
rf"{n_traj:,} & {gt50:,} & {med_steps:,} & {es['total']:,} & {es.get('ge2', 0):,} & {med_edits:,} & {_fmt_states(n_states)} \\"
16771716
)
16781717
if i + 2 < len(configs):
16791718
rows.append(r"\addlinespace")
16801719
i += 2
16811720

1682-
# Total row
1721+
# Total row (medians pooled across all trajectories, not summed)
1722+
def _median(xs: list[int]) -> str:
1723+
if not xs:
1724+
return "---"
1725+
s = sorted(xs)
1726+
return f"{s[len(s) // 2]:,}"
1727+
16831728
rows.append(r"\midrule")
16841729
rows.append(
16851730
rf"\multicolumn{{2}}{{l}}{{Total}} & "
1686-
rf"{tot_traj:,} & {tot_gt50:,} & {tot_edits:,} & {tot_ge2:,} & {_fmt_states(tot_states)} \\"
1731+
rf"{tot_traj:,} & {tot_gt50:,} & {_median(all_turns)} & "
1732+
rf"{tot_edits:,} & {tot_ge2:,} & {_median(all_edits)} & {_fmt_states(tot_states)} \\"
16871733
)
16881734

16891735
body = "\n".join(rows)

0 commit comments

Comments
 (0)