#!/usr/bin/env python3
"""Reproducible checks for the Fibonacci-sum determinant research fixture.

The script uses exact integer arithmetic and has no third-party dependencies.
It verifies the determinant range, records the nonzero support, measures the
singleton-peeling residual core, and checks the growth-rate counterexample.
"""

from __future__ import annotations

import argparse
import json


def fibonacci_numbers(limit: int) -> set[int]:
    values = {1, 2}
    a, b = 1, 2
    while b <= limit:
        values.add(b)
        a, b = b, a + b
    return values


def sum_indicator_matrix(n: int, sequence: set[int] | None = None) -> list[list[int]]:
    allowed = sequence or fibonacci_numbers(2 * n)
    return [[int(i + j in allowed) for j in range(1, n + 1)] for i in range(1, n + 1)]


def bareiss_det(matrix: list[list[int]]) -> int:
    """Fraction-free Gaussian elimination with exact pivoting."""
    n = len(matrix)
    if n == 0:
        return 1
    a = [row[:] for row in matrix]
    sign = 1
    denominator = 1
    for k in range(n - 1):
        pivot = next((r for r in range(k, n) if a[r][k] != 0), None)
        if pivot is None:
            return 0
        if pivot != k:
            a[k], a[pivot] = a[pivot], a[k]
            sign *= -1
        pivot_value = a[k][k]
        for i in range(k + 1, n):
            for j in range(k + 1, n):
                a[i][j] = (a[i][j] * pivot_value - a[i][k] * a[k][j]) // denominator
        denominator = pivot_value
        for i in range(k + 1, n):
            a[i][k] = 0
    return sign * a[-1][-1]


def singleton_core(matrix: list[list[int]]) -> tuple[list[int], list[int]]:
    """Remove forced row/column matches until every remaining degree is 0 or >1."""
    rows = list(range(len(matrix)))
    cols = list(range(len(matrix)))
    while rows and cols:
        forced: tuple[int, int] | None = None
        for row in rows:
            neighbors = [col for col in cols if matrix[row][col]]
            if len(neighbors) == 1:
                forced = row, neighbors[0]
                break
        if forced is None:
            for col in cols:
                neighbors = [row for row in rows if matrix[row][col]]
                if len(neighbors) == 1:
                    forced = neighbors[0], col
                    break
        if forced is None:
            break
        row, col = forced
        rows.remove(row)
        cols.remove(col)
    return rows, cols


def run(max_n: int) -> dict:
    determinants: dict[str, int] = {}
    nonzero: list[int] = []
    nonempty_cores: list[int] = []
    core_sizes: dict[str, int] = {}
    for n in range(1, max_n + 1):
        matrix = sum_indicator_matrix(n)
        det = bareiss_det(matrix)
        determinants[str(n)] = det
        if det:
            nonzero.append(n)
        rows, _ = singleton_core(matrix)
        core_sizes[str(n)] = len(rows)
        if rows:
            nonempty_cores.append(n)

    counterexample = [2, 6, 8, 14, 22, 36, 58]
    counterexample_det = bareiss_det(sum_indicator_matrix(5, set(counterexample)))
    return {
        "max_n": max_n,
        "determinant_range_holds": all(abs(value) <= 1 for value in determinants.values()),
        "nonzero_indices": nonzero,
        "nonempty_singleton_cores": nonempty_cores,
        "nonempty_core_count": len(nonempty_cores),
        "core_sizes": core_sizes,
        "growth_counterexample_det_n5": counterexample_det,
    }


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--max-n", type=int, default=120)
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args()
    result = run(args.max_n)
    if args.json:
        print(json.dumps(result, indent=2))
        return
    print(f"determinants stay in {{-1,0,1}} through n={args.max_n}: "
          f"{result['determinant_range_holds']}")
    print("nonzero indices:", result["nonzero_indices"])
    print("nonempty singleton cores:", result["nonempty_core_count"], "/", args.max_n)
    print("growth-rate counterexample determinant at n=5:",
          result["growth_counterexample_det_n5"])


if __name__ == "__main__":
    main()
