#!/usr/bin/env python3
"""Torn-verify for 012 — One Letter Per Step. Pure Python."""

from decimal import Decimal, getcontext
from fractions import Fraction
from math import log, pi, sin

FAILS = []


def check(name, condition, detail=""):
    print(("PASS" if condition else "FAIL") + "  " + name +
          (("  [" + detail + "]") if detail else ""))
    if not condition:
        FAILS.append(name)


def logistic(x):
    return 4*x*(1-x)


residual = max(abs(logistic(sin(pi*k/4096)**2) - sin(2*pi*k/4096)**2)
               for k in range(4097))
check("x=sin²(pi theta) conjugates the r=4 logistic map to angle doubling",
      residual < 2e-15, f"max residual={residual:.3e}")

width = 200
mask = (1 << width) - 1
word = int("10110100101101110010"*10, 2)
shifted = word
for n in range(53):
    shifted = (shifted << 1) & mask
    expected = (word << (n+1)) & mask
    if shifted != expected:
        break
check("each iteration consumes exactly one binary digit",
      shifted == expected and n == 52, "53 exact left shifts")
check("the exact Lyapunov exponent is ln 2, or one bit per step",
      abs(log(2)/log(2) - 1) < 1e-15, f"lambda={log(2):.15f}, rate=1 bit/step")

getcontext().prec = 200
exact, machine = Decimal(1)/Decimal(5), 0.2
first_drift = first_separation = None
for n in range(71):
    delta = abs(float(exact) - machine)
    if first_drift is None and delta > 1e-3:
        first_drift = n
    if first_separation is None and delta > 0.1:
        first_separation = n
    exact = 4*exact*(1-exact)
    machine = logistic(machine)
check("the binary64 track first visibly drifts at the recorded step",
      first_drift == 45, f"step={first_drift}")
check("the two precision tracks fully separate at the recorded step",
      first_separation == 52, f"step={first_separation}")
check("the 53-bit wallet empties in the same window as the measured divergence",
      first_drift < 53 and first_separation <= 53,
      f"drift={first_drift}, separation={first_separation}, wallet=53")

x = Fraction(1, 5)
bits = []
for _ in range(8):
    bits.append(x.denominator.bit_length())
    x = logistic(x)
growth = [bits[i+1]/bits[i] for i in range(2, len(bits)-1)]
check("exact rational denominator size doubles asymptotically each step",
      all(1.85 < ratio < 2.05 for ratio in growth),
      "bit lengths=" + str(bits))

print()
if FAILS:
    print(f"TORN-VERIFY: {len(FAILS)} recorded claim(s) no longer hold: {FAILS}")
    raise SystemExit(1)
print("TORN-VERIFY: all recorded claims for 012 still hold.")
