#!/usr/bin/env python3
"""Independent finite checks for FPRD-D30/T68/T69 and FPRD-T70/T71."""

from fractions import Fraction
from itertools import combinations, product
import json


def even_palindrome(word: str) -> bool:
    return len(word) % 2 == 0 and word == word[::-1]


def direct_survivors(word: str) -> set[int]:
    t = len(word)
    return {r for r in range(t + 1) if (r - t) % 2 == 0 and even_palindrome(word[r:t])}


def update_survivors(word: str, survivors: set[int], bit: str) -> set[int]:
    t = len(word)
    return {t + 1} | {
        r - 1 for r in survivors if r >= 1 and word[r - 1] == bit
    }


def precedes(left: tuple[int, int], right: tuple[int, int]) -> bool:
    t, p = left
    tt, pp = right
    return p >= pp and p - pp <= tt - t


def width(events: tuple[tuple[int, int], ...]) -> int:
    best = 0
    for mask in range(1 << len(events)):
        chosen = [events[i] for i in range(len(events)) if mask >> i & 1]
        if all(not precedes(a, b) and not precedes(b, a)
               for a, b in combinations(chosen, 2)):
            best = max(best, len(chosen))
    return best


def min_chain_cover(events: tuple[tuple[int, int], ...]) -> int:
    chains: list[list[tuple[int, int]]] = []
    best = len(events)

    def rec(i: int) -> None:
        nonlocal best
        if len(chains) >= best:
            return
        if i == len(events):
            best = len(chains)
            return
        e = events[i]
        for chain in chains:
            if precedes(chain[-1], e):
                chain.append(e)
                rec(i + 1)
                chain.pop()
        chains.append([e])
        rec(i + 1)
        chains.pop()

    rec(0)
    return best


def max_mean_cycle_triangle(weights: tuple[int, int, int]) -> Fraction:
    # Boundary-augmented triangle with the displayed orientations 0->1->2->0.
    return Fraction(abs(sum(weights)), 3)


def integer_gauge_opt_triangle(weights: tuple[int, int, int]) -> int:
    best = 99
    # Fix potential 0 at vertex 0. The bound 8 covers every tested weight.
    for z1 in range(-8, 9):
        for z2 in range(-8, 9):
            gauged = (
                weights[0] + z1,
                weights[1] + z2 - z1,
                weights[2] - z2,
            )
            best = min(best, max(abs(x) for x in gauged))
    return best


def run() -> dict:
    counts: dict[str, int] = {}

    recurrence_cases = 0
    stationary_cases = 0
    for n in range(15):
        for bits in product("01", repeat=n):
            word = "".join(bits)
            survivors = direct_survivors(word)
            for bit in "01":
                updated = update_survivors(word, survivors, bit)
                assert updated == direct_survivors(word + bit)
                recurrence_cases += 1
                for r in survivors:
                    if r >= 1 and word[r - 1] == bit:
                        assert Fraction(n + r - 1, 2) == Fraction((n + 1) + (r - 1) - 1, 2)
                        stationary_cases += 1
    counts["palindrome_recurrence_extensions"] = recurrence_cases
    counts["stationary_lineage_steps"] = stationary_cases

    grid = tuple((t, p) for t in range(3) for p in range(3))
    poset_subsets = 0
    for mask in range(1 << len(grid)):
        events = tuple(grid[i] for i in range(len(grid)) if mask >> i & 1)
        if len(events) <= 7:
            ordered = tuple(sorted(events))
            assert width(ordered) == min_chain_cover(ordered)
            poset_subsets += 1
    counts["causal_poset_subsets"] = poset_subsets

    a, b, c = (28, 8), (28, 12), (36, 6)
    d, dd = (38, 0), (38, 10)
    assert width(tuple(sorted((a, b, c, d)))) == 2
    assert width(tuple(sorted((a, b, c, dd)))) == 2
    assert precedes(a, c) and precedes(b, c)
    assert not precedes(c, d) and not precedes(b, d) and precedes(a, d)
    assert not precedes(c, dd) and not precedes(a, dd) and precedes(b, dd)
    counts["online_adversary_completions"] = 2

    selector_capacity_cases = 0
    for r in range(1, 11):
        targets = [(r + 1) * z for z in range(1 << r)]
        for position in range(targets[-1] + r + 2):
            seen = [q for q in targets if position - r <= q <= position]
            assert len(seen) <= 1
            selector_capacity_cases += 1
    counts["spaced_selector_positions"] = selector_capacity_cases

    # The r+1 spacing is sharp for the one-bit-per-track frontier.
    hostile_r = 2
    hostile_targets = [0, 2, 4, 6]
    visible = [q for q in hostile_targets if 2 - hostile_r <= q <= 2]
    assert visible == [0, 2]
    assert 2 ** (len(hostile_targets) - len(visible)) == 4
    counts["hostile_spacing_examples"] = 1

    # Exact late-INDEX frontier: a k-track cell fixes at most k independent bits.
    frontier_cases = 0
    for r in range(1, 5):
        d_bits = 1 << r
        for k in range(d_bits + 2):
            predicted = 1 << max(d_bits - k, 0)
            tracked = min(k, d_bits)
            cells = 1 << (d_bits - tracked)
            assert cells == predicted
            frontier_cases += 1
    counts["late_index_frontier_cases"] = frontier_cases

    # T70 sharp unary family and the pointwise h<=H hostile boundary.
    sharp_height_cases = 0
    for n in range(1, 31):
        raw = 1
        canonical = n + 1
        assert canonical == (n + 1) * raw
        sharp_height_cases += 1
    assert max(abs(5), 0, abs(-5)) == 5
    assert 5 + (-5) == 0
    counts["sharp_height_families"] = sharp_height_cases
    counts["pointwise_height_counterexamples"] = 1

    cycle_cases = 0
    for weights in product(range(-3, 4), repeat=3):
        rho = max_mean_cycle_triangle(weights)
        optimum = integer_gauge_opt_triangle(weights)
        ceiling = (rho.numerator + rho.denominator - 1) // rho.denominator
        assert optimum == ceiling
        cycle_cases += 1
    counts["integer_cycle_duality_triangles"] = cycle_cases

    # Boundary edges are essential: a one-state machine with initial 2 and final -2
    # has a nonzero augmented graph even though its transition graph has no edge.
    assert max(abs(2), abs(-2)) == 2
    counts["boundary_vertex_hostile_examples"] = 1

    return {
        "status": "passed",
        "claims": ["FPRD-D30", "FPRD-T68", "FPRD-T69", "FPRD-T70", "FPRD-T71"],
        "counts": counts,
    }


if __name__ == "__main__":
    print(json.dumps(run(), indent=2, sort_keys=True))
