"""Compare claimed container sides against stored bounds. Deterministic, no LLM. Metric per n: smaller container side s is better (see sources.md; relative score s/sqrt(n)-1 is monotone in s for fixed n).""" from __future__ import annotations from dataclasses import dataclass, asdict, field import json import math @dataclass class Bound: n: int s: float source: str date: str # ISO date the source was read verified: bool basis: str = "" # e.g. "listed", "trivial-grid rule", "proved" exact: str = "" # closed form if the source gives one def load_bounds(path): with open(path) as f: return {int(d["n"]): Bound(**d) for d in json.load(f)} def save_bounds(bounds, path): with open(path, "w") as f: json.dump([asdict(b) for _, b in sorted(bounds.items())], f, indent=2) def area_lower_bound(n): return math.sqrt(n) def trivial_upper_bound(n): return math.ceil(math.sqrt(n)) def rel_score(n, s): return s / math.sqrt(n) - 1.0 # Units: every side length here is the container side measured in unit-square edge lengths # (the squares have side 1). Thresholds are ABSOLUTE differences in that unit. VALIDATION_EPS = 1e-9 # geometry tolerance used by packing.validate (float mode) IMPROVEMENT_MATERIAL = 1e-8 # a claim must beat the bound by MORE than this; strictly > VALIDATION_EPS assert IMPROVEMENT_MATERIAL > VALIDATION_EPS def float_near_bound_margin(n): """Float validation allows each pair to overlap by up to VALIDATION_EPS. Along a row of ~sqrt(n)..n squares those slacks add up, so the true required side can be up to ~n*VALIDATION_EPS smaller than the float check suggests. A float-validated (non-proof) claim is promoted to an improvement only if it beats the bound by more than this; otherwise it stays a candidate until an exact/interval check.""" return IMPROVEMENT_MATERIAL + n * VALIDATION_EPS def classify(claim_s, bound_s, validation=None, material=IMPROVEMENT_MATERIAL): """Return (status, delta), delta = claim - bound (negative is better). partial: no side. impossible: s < sqrt(n) is ruled out by area (checked by caller). invalid: coordinates failed validation. improvement: validated and better. unverified: better than bound but no coordinates checked (a CANDIDATE, never an improvement). unchanged: within +-material. worse. no_baseline: bound unknown.""" if claim_s is None: return "partial", None if bound_s is None: if validation is not None and not validation["valid"]: return "invalid", None return "no_baseline", None delta = claim_s - bound_s if validation is not None and not validation["valid"]: return "invalid", delta if delta < -material: return ("improvement", delta) if validation is not None else ("unverified", delta) if delta > material: return "worse", delta return "unchanged", delta def find_conflicts(claims, tol=1e-6): """claims: dicts with n, s, source_url. One entry per n whose sides differ by > tol across distinct sources. s=None ignored.""" by_n = {} for c in claims: if c.get("s") is not None: by_n.setdefault(c["n"], []).append(c) out = [] for n, cs in sorted(by_n.items()): vals = [c["s"] for c in cs] if max(vals) - min(vals) > tol and len({c.get("source_url") for c in cs}) > 1: out.append({"n": n, "spread": max(vals) - min(vals), "claims": [{"s": c["s"], "source_url": c.get("source_url")} for c in cs]}) return out