"""F4-conf-02: verdicts on six assertions vs. cited extracts. Reads data/ only; deterministic (no randomness).""" import json, math, os, re, hashlib ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) D = os.path.join(ROOT, "data") DCR, RES = "arxiv-2609.27732v1", "arxiv-2606.14621v1" def read(p): with open(os.path.join(D, p), encoding="utf-8") as f: return f.read() assertions = json.loads(read("assertions.json")) src = {DCR: read(f"sources/{DCR}.txt"), RES: read(f"sources/{RES}.txt")} lines = {k: v.splitlines() for k, v in src.items()} def line(sid, prefix): """Return (lineno, text) of first line starting with prefix; print it; also return following line.""" for i, l in enumerate(lines[sid]): if l.startswith(prefix): print(f" [{sid} L{i+1}] {l}") nxt = lines[sid][i + 2] if i + 2 < len(lines[sid]) else "" # SE line (blank line between) if nxt.startswith("|"): print(f" [{sid} L{i+3}] {nxt}") return i, l, nxt raise RuntimeError(f"line not found: {prefix}") def cells(l): return [c.strip() for c in l.split("|")] def num(c): return float(re.sub(r"[^\d.\-]", "", c.replace("−", "-"))) def pct(b): return 100 * (math.exp(b) - 1) # ---- baseline: naive verbatim number match (all numbers in assertion occur in cited source) ---- baseline = {} for a in assertions: nums = re.findall(r"\d+\.\d+", a["text"]) found = [n for n in nums if n in src[a["cites"]]] baseline[a["id"]] = "supported" if len(found) == len(nums) else "not_supported" V, L, R = {}, {}, {} COLS = {"1 km": 1, "3 km": 2, "5 km": 3} # ---- A1: Table 6, 5 km ---- print("A1 evidence:") idx6 = next(i for i, l in enumerate(lines[DCR]) if l.startswith("Table 6:")) sub = lines[DCR][idx6:] i_att = next(i for i, l in enumerate(sub) if l.startswith("ATT |")) att, se_l, pct_l = sub[i_att], sub[i_att + 2], sub[i_att + 4] for l in (att, se_l, pct_l): print(" [Table 6]", l) b5 = num(cells(att)[3]); se5 = num(cells(se_l)[3]); stars5 = cells(att)[3].count("*"); p5 = cells(pct_l)[3] ok = (b5 == -0.431 and se5 == 0.210 and stars5 >= 2 and p5 == "-35.0%" and abs(pct(b5) - (-35.0)) < 0.05) V["A1"] = "supported" if ok else "not_supported" L["A1"] = f'{DCR} | Table 6 | row "ATT" | column "5 km"' R["A1"] = (f"Table 6 prints ATT {cells(att)[3]} with SE {cells(se_l)[3].strip("()")} (** = p<0.05) and % change {p5}, " f"and 100(exp({b5})-1) = {pct(b5):.2f}%, so every element matches.") # ---- A2: Table 7 HIV, 1 km ---- print("A2 evidence:") _, hiv, hiv_se = line(DCR, "HIV |") b_hiv1 = num(cells(hiv)[1]) V["A2"] = "supported" if b_hiv1 < 0 else "not_supported" L["A2"] = f'{DCR} | Table 7 | row "HIV" | column "1 km"' R["A2"] = (f"Table 7 prints the 1 km HIV ATT as +{cells(hiv)[1]} (SE {cells(hiv_se)[1].strip("()")}), positive and insignificant, " "so the claimed negative sign and implied fall are contradicted.") # ---- A3: Table 6, 3 km ---- print("A3 evidence:") b3 = num(cells(att)[2]); p3 = cells(pct_l)[2] V["A3"] = "supported" if abs(pct(b3) - (-28.3)) < 0.05 else "not_supported" L["A3"] = f'{DCR} | Table 6 | row "% change" | column "3 km"' R["A3"] = (f"Table 6 converts the 3 km ATT {cells(att)[2]} to {p3} (100(exp({b3})-1) = {pct(b3):.2f}%), " "not 28.3%; the assertion reads log points as percent (and the estimate is insignificant, SE " f"{cells(se_l)[2].strip("()")}).") # ---- A4: Table 7 Hepatitis, 5 km ---- print("A4 evidence:") _, hep, hep_se = line(DCR, "Hepatitis |") bh = num(cells(hep)[3]); sh = num(cells(hep_se)[3]) ci196 = (bh - 1.96 * sh, bh + 1.96 * sh); ci2 = (bh - 2 * sh, bh + 2 * sh); ci1 = (bh - sh, bh + sh) excl = ci196[1] < 0 or ci196[0] > 0 V["A4"] = "supported" if (excl and abs(ci196[0] + 0.66) < 0.02 and abs(ci196[1] + 0.16) < 0.02) else "not_supported" L["A4"] = f'{DCR} | Table 7 | row "Hepatitis" | column "5 km"' R["A4"] = (f"With ATT {bh} and SE ({sh:.3f}) the 95% CI is [{ci196[0]:.3f}, {ci196[1]:.3f}] (±2SE: " f"[{ci2[0]:.3f}, {ci2[1]:.3f}]), which includes zero; the asserted [-0.66, -0.16] is only ±1 SE " f"([{ci1[0]:.3f}, {ci1[1]:.3f}]) and the cell carries no significance star.") # ---- A5: sex heterogeneity ---- print("A5 evidence: search for sex/gender terms in DCR extract") hits = [i + 1 for i, l in enumerate(lines[DCR]) if re.search(r"\b(men|women|male|female|sex|gender)\b", l, re.I)] print(f" lines mentioning men/women/male/female/sex/gender: {hits}") V["A5"] = "not_assessable" if not hits else "REVIEW" L["A5"] = f"not reported in {DCR}" R["A5"] = ("The extract reports ATTs only by buffer (Table 6), outcome category (Table 7) and estimator (Table A19), " "never by sex, so the men-vs-women comparison can be neither confirmed nor refuted.") # ---- A6: RESEA Table 2, Weeks on UI ---- print("A6 evidence:") _, ui, _ = line(RES, "Weeks on UI |") c = cells(ui) ate = c[4]; ctrl = c[2] m = re.match(r"(-?[\d.]+) weeks; p<0.001; 95% CI: \[(-?[\d.]+), (-?[\d.]+)\]", ate) b6, lo6, hi6 = map(float, m.groups()); cm = float(re.match(r"([\d.]+)", ctrl).group(1)) rel = 100 * abs(b6) / cm V["A6"] = "supported" if (b6 == -1.99 and lo6 == -2.24 and hi6 == -1.75 and cm == 17.3 and round(rel, 1) == 11.5) else "not_supported" L["A6"] = f'{RES} | Table 2 | row "Weeks on UI" | column "Average treatment effect estimate"' R["A6"] = (f"Table 2 prints the ATE as {b6} weeks (95% CI [{lo6}, {hi6}]) against a control mean of {cm} weeks, " f"and 1.99/17.3 = {rel:.1f}%, matching every element.") counts = {k: sum(v == k for v in V.values()) for k in ("supported", "not_supported", "not_assessable")} def wcl(p): with open(os.path.join(D, p), "rb") as f: return f.read().count(b"\n") results = { "task_id": "F4-conf-02", "verdicts": V, "locators": L, "reasons": R, "n_supported": counts["supported"], "n_not_supported": counts["not_supported"], "n_not_assessable": counts["not_assessable"], "feasibility": "complete", "feasibility_reason": None, "data_issues": [ {"issue": f"{DCR}: Table A19 CS-DR column prints SE (0.218) for the ATT -0.431 that Table 6 prints with SE (0.210) (same estimator, buffer and sample).", "handling": f"A1 decided on Table 6, which the assertion quotes; under SE 0.218 the estimate remains significant at 5% (|t|={0.431/0.218:.2f} > 1.96) and carries ** in both tables, so the verdict is unaffected."}, {"issue": f"{DCR}: Table A19 note states 640 never-treated comparison regions whereas Tables 6, 7 and A19 body state 608.", "handling": "Recorded only; no assertion depends on the control-region count."}, {"issue": f"{DCR}: abstract says fatal hospitalisations fall by 35%, but Table 7 5 km fatal ATT -0.354 converts to {pct(-0.354):.1f}% (Section 6.1 says ~30%); abstract appears to read log points as percent.", "handling": "Recorded only; verdicts rely on table cells, not the abstract; no assertion concerns fatal outcomes."}, {"issue": f"{DCR}: results text calls HIV estimates 'close to zero' although the 5 km HIV ATT is -0.340 (SE 0.294).", "handling": "Recorded only; A2 decided on the printed 1 km cell (0.063)."}, {"issue": f"{RES}: text reports CIs for reductions as positive magnitudes ([1.75 weeks, 2.24 weeks]) while Table 2 prints [-2.24, -1.75]; also a rendering defect 'p ¡ 0.001'.", "handling": "Treated as sign convention of the prose; A6 decided on Table 2, whose signed interval matches the assertion."}, ], "n_input_rows": { "assertions.json": len(assertions), "README.md": wcl("README.md"), f"{DCR}.txt": wcl(f"sources/{DCR}.txt"), f"{RES}.txt": wcl(f"sources/{RES}.txt"), }, "n_analysed": len(V), "random_seed": None, "baseline_naive_number_match_verdicts": baseline, "baseline_agreement_with_final": sum(baseline[k] == V[k] for k in V), "derived": { "A1_pct_from_logpoints": round(pct(b5), 2), "A1_t_stat_table6": round(b5 / se5, 3), "A3_pct_from_logpoints": round(pct(b3), 2), "A4_ci95_1.96": [round(x, 3) for x in ci196], "A4_ci95_2.0": [round(x, 3) for x in ci2], "A4_ci_1se": [round(x, 3) for x in ci1], "A6_relative_reduction_pct": round(rel, 2), }, } assert "REVIEW" not in V.values() os.makedirs(os.path.join(ROOT, "out"), exist_ok=True) with open(os.path.join(ROOT, "out", "results.json"), "w") as f: json.dump(results, f, indent=2, ensure_ascii=False) print("Verdicts:", V) print("Counts:", counts)