#!/usr/bin/env python3
"""Independent checks for the pentagon compiler and support-tensor review.

The implementation is intentionally small and self-contained.  It does not
import the research code that produced the original records.
"""

from __future__ import annotations

import json
from itertools import combinations, product


def direct_pentagon_audit() -> dict[str, object]:
    alphabet = tuple(range(5))
    blocks = {(i, (2 * i) % 5) for i in alphabet}

    # Natural backward-prefix states: six accepting boundary states and five
    # nonaccepting halfway states.  Each boundary has five outgoing edges.
    boundaries = ("epsilon",) + tuple(f"complete-{i}" for i in alphabet)
    halfway = tuple(f"half-{i}" for i in alphabet)
    natural_edges = {
        (boundary, i, halfway[i]) for boundary in boundaries for i in alphabet
    } | {
        (halfway[i], (2 * i) % 5, f"complete-{i}") for i in alphabet
    }
    assert len(boundaries) + len(halfway) == 11
    assert len(natural_edges) == 35

    # Quotient all accepting block boundaries to q.
    quotient_edges = {("q", i, halfway[i]) for i in alphabet} | {
        (halfway[i], (2 * i) % 5, "q") for i in alphabet
    }
    assert len(quotient_edges) == 10
    for symbol in alphabet:
        destinations = [dst for _, label, dst in quotient_edges if label == symbol]
        assert len(destinations) == len(set(destinations))

    # Root is separated from halfway states by epsilon; half-i and half-j are
    # separated by the one-letter suffix 2i.  Hence the six states are minimal.
    distinguishers = {
        (halfway[i], halfway[j]): ((2 * i) % 5,)
        for i, j in combinations(alphabet, 2)
    }
    assert len(distinguishers) == 10

    tested = accepted = 0
    for length in range(9):
        for word in product(alphabet, repeat=length):
            oracle = length % 2 == 0 and all(
                tuple(word[offset : offset + 2]) in blocks
                for offset in range(0, length, 2)
            )
            state: str | None = "q"
            for symbol in word:
                options = [dst for src, label, dst in quotient_edges if src == state and label == symbol]
                state = options[0] if len(options) == 1 else None
                if state is None:
                    break
            machine = state == "q"
            assert machine == oracle
            tested += 1
            accepted += int(oracle)

    code = tuple(sorted(blocks))
    incompatible_pairs = 0
    for left, right in combinations(code, 2):
        # Distinct C5 vertices are strongly adjacent in the square precisely
        # when both coordinate differences are 0 or +/-1 modulo five.
        adjacent = all((a - b) % 5 in (0, 1, 4) for a, b in zip(left, right))
        assert not adjacent
        incompatible_pairs += 1

    return {
        "alphabet_words_tested_lengths_0_through_8": tested,
        "accepted_words_among_them": accepted,
        "natural_prefix_states": 11,
        "natural_prefix_transitions": len(natural_edges),
        "minimal_reversible_quotient_states": 6,
        "minimal_reversible_quotient_transitions": len(quotient_edges),
        "state_pair_distinguishers": 15,
        "pentagon_code_pairs_checked": incompatible_pairs,
    }


def overlap_graph(supports: list[frozenset[object]]) -> set[tuple[int, int]]:
    return {
        (i, j)
        for i, j in combinations(range(len(supports)), 2)
        if supports[i] & supports[j]
    }


def uniform_supports_for_graph(n: int, edges: set[tuple[int, int]]) -> list[frozenset[str]]:
    degrees = [sum(v in edge for edge in edges) for v in range(n)]
    width = max(1, max(degrees, default=0))
    supports = []
    for vertex in range(n):
        tokens = {
            f"edge-{min(vertex, other)}-{max(vertex, other)}"
            for other in range(n)
            if (min(vertex, other), max(vertex, other)) in edges
        }
        tokens |= {
            f"private-{vertex}-{index}" for index in range(width - len(tokens))
        }
        supports.append(frozenset(tokens))
    assert all(supports)
    assert len({len(support) for support in supports}) == 1
    return supports


def tensor_support(supports: list[frozenset[object]], word: tuple[int, ...]) -> frozenset[tuple[object, ...]]:
    return frozenset(product(*(supports[index] for index in word)))


def support_tensor_audit() -> dict[str, object]:
    represented = tensor_pairs = edge_slots_checked = 0
    hostile_edgeless_cases = 0
    for n in range(1, 6):
        slots = tuple(combinations(range(n), 2))
        for mask in range(1 << len(slots)):
            edges = {edge for index, edge in enumerate(slots) if mask & (1 << index)}
            supports = uniform_supports_for_graph(n, edges)
            assert overlap_graph(supports) == edges
            represented += 1
            edge_slots_checked += len(slots)
            if not edges:
                assert {len(support) for support in supports} == {1}
                hostile_edgeless_cases += 1

            if n <= 4:
                words = tuple(product(range(n), repeat=2))
                base = overlap_graph(supports)
                tensors = [tensor_support(supports, word) for word in words]
                for i, j in combinations(range(len(words)), 2):
                    actual = bool(tensors[i] & tensors[j])
                    expected = all(
                        a == b or (min(a, b), max(a, b)) in base
                        for a, b in zip(words[i], words[j])
                    )
                    assert actual == expected
                    tensor_pairs += 1

    # The complete two-support policy is the triangular graph T5.
    t5_supports = [frozenset(edge) for edge in combinations(range(5), 2)]
    t5_edges = overlap_graph(t5_supports)
    assert len(t5_supports) == 10 and len(t5_edges) == 30
    assert all(sum(vertex in edge for edge in t5_edges) == 6 for vertex in range(10))

    # The cyclic adjacent-pair policy has overlap graph C_n.  Its classical
    # pentagon code supplies the five-word lower certificate.
    cyclic_pairs = 0
    for n in (5, 7, 9):
        supports = [frozenset({i, (i + 1) % n}) for i in range(n)]
        edges = overlap_graph(supports)
        for i, j in combinations(range(n), 2):
            assert ((i, j) in edges) == ((i - j) % n in (1, n - 1))
            cyclic_pairs += 1

    return {
        "uniform_graph_representations": represented,
        "represented_graph_edge_slots_checked": edge_slots_checked,
        "tensor_vertex_pairs_checked": tensor_pairs,
        "hostile_edgeless_graphs_checked": hostile_edgeless_cases,
        "t5_vertices": len(t5_supports),
        "t5_edges": len(t5_edges),
        "cyclic_policy_pairs_checked": cyclic_pairs,
    }


def main() -> None:
    result = {
        "schema": "fprd.result-review.pentagon-shannon.v1",
        "date": "2026-09-01",
        "status": "pass",
        "pentagon_direct_block": direct_pentagon_audit(),
        "support_tensor": support_tensor_audit(),
        "scope_boundary": [
            "The imported T5 power values and graph-capacity theorems are checked against cited primary sources, not recomputed here.",
            "The earlier 66/81 carrier and 87/191 carrier-controller counts are excluded because their precise source model and verifier were not recovered.",
        ],
    }
    print(json.dumps(result, indent=2, sort_keys=True))


if __name__ == "__main__":
    main()
