Files
troupe-standup/wizard-work/cassian/q84_mutants.py
T
cassian 9e5cf400e3 queue: three cassian addenda (no closure, no state change): Q84 re-measured at 000580a — 5/5 mutants killed, 9,724-case oracle 0 mismatches, closure never appended after reply 121's acceptance; Q75 first increment (instrument red: FIELDS 14, TOTAL 2, ABSENT 519/TSV); Q69 instance turning beam CHECK red off-host (test_sha256_manifest.py:3)
Adds wizard-work/cassian/q84_mutants.py (harness, rc 0). Written as
'**Q<n> addendum' lines (the Q129/Q156 addendum form), so open_set.py's pin
does not move: --check -> counts match the pin. docs/queue-index.md
re-rendered with tools/queue_index.py --write in this commit.
2026-11-02 15:57:50 -05:00

47 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""q84_mutants.py -- re-grade Q84's cells (wizard-work/beam/test_interval_overlap.py) against
five named mutants of interval_overlap.py, plus an independent oracle (integer-set
intersection, not the module's own brute_force_pairs). Read-only: each mutant runs in a
fresh temp dir; nothing in the tree is edited. Default subject is the beam lane beside
this file (Path(__file__)-relative); pass another beam dir as argv[1].
python3 wizard-work/cassian/q84_mutants.py
"""
import itertools, os, shutil, subprocess, sys, tempfile
SRC = sys.argv[1] if len(sys.argv) > 1 else os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "beam")
orig = open(os.path.join(SRC, "interval_overlap.py")).read()
MUT = {
"M1 kind ordering flipped": ("events.sort(key=lambda x: (x[0], x[1]))", "events.sort(key=lambda x: (x[0], -x[1]))"),
"M2 s>=e skip removed (pairs)": (" if s >= e: # zero-length interval: empty set, never overlaps\n continue\n for other", " for other"),
"M3 start-pair loop removed": (" for other in active:\n a, b = (idx, other) if idx < other else (other, idx)\n pairs.add((a, b))\n", ""),
"M4 has_any_overlap -> pair-list body": (" iv = list(intervals)\n for s, e in iv:\n if e < s:\n raise ValueError(f\"end < start: {(s, e)}\")\n # Sorted", " return bool(find_overlapping_pairs(intervals))\n iv = []\n # Sorted"),
"M5 boundary s<max_end -> s<=max_end": ("s < max_end:", "s <= max_end:"),
}
survivors = []
for name, (a, b) in MUT.items():
assert orig.count(a) == 1, (name, orig.count(a))
d = tempfile.mkdtemp()
shutil.copy(os.path.join(SRC, "test_interval_overlap.py"), d)
open(os.path.join(d, "interval_overlap.py"), "w").write(orig.replace(a, b))
r = subprocess.run([sys.executable, "-m", "unittest", "test_interval_overlap"], cwd=d, capture_output=True, text=True, timeout=600)
dead = sorted({l.split()[1] for l in r.stderr.splitlines() if l.startswith(("FAIL:", "ERROR:"))})
print(f"{name}: rc {r.returncode}, dead {len(dead)}: {', '.join(dead)}")
if r.returncode == 0:
survivors.append(name)
# independent oracle, not the module's brute_force_pairs
sys.path.insert(0, SRC)
import interval_overlap as m
pts = range(-2, 4); ivs = [(s, e) for s in pts for e in pts if e >= s]
n = mism = 0
for k in range(0, 4):
for combo in itertools.product(ivs, repeat=k):
truth = sorted((i, j) for i in range(k) for j in range(i+1, k)
if set(range(combo[i][0], combo[i][1])) & set(range(combo[j][0], combo[j][1])))
n += 1
if m.find_overlapping_pairs(combo) != truth or m.has_any_overlap(combo) != bool(truth):
mism += 1
print(f"oracle (integer-set intersection, ordered tuples over [-2,3], size 0-3): {n} cases, {mism} mismatches")
print(f"mutants: {len(MUT)}, survived {len(survivors)}: {survivors}")
sys.exit(0 if mism == 0 and not survivors else 1)