#!/usr/bin/env python3
"""
PST Computation 4 — Stage 3 of the 10-foundational programme
============================================================================
The spin-structure step: does the Mosco limit carry a spin structure and a
Dirac operator D_M, so that M x F is a bona fide spectral triple?

This is the load-bearing analytic item. It splits cleanly into a TOPOLOGICAL
part (which closes rigorously) and an ANALYTIC part (the convergence, which is
scoped here, not closed).

PST already establishes (paper §seeley-dewitt; Track I §B1, §B12) that the
substrate's Dirichlet-form Mosco limit gives the S^3 spatial geometry, and
the macroscopic spacetime is the globally hyperbolic M = R_time x S^3 with
Cauchy surface S^3.

TOPOLOGICAL part (closes):
  - Every orientable 3-manifold is parallelizable (Stiefel), hence spin.
    In particular S^3 = SU(2) is parallelizable.
  - w_2(S^3) lives in H^2(S^3; Z/2) = 0, so the spin obstruction vanishes.
  - Spin structures are a torsor over H^1(S^3; Z/2) = 0, so the spin
    structure is UNIQUE.
  - A globally hyperbolic M = R x Sigma is spin iff Sigma is spin; so
    M = R x S^3 is spin with a unique spin structure.
  => The spacetime carries a canonical Dirac operator determined by the
     metric and this unique spin structure. KO-dimension 4 (Lorentzian,
     Wick-rotated structure; Euclidean canonical triple of a 4-manifold).

ANALYTIC part (scoped, the residual):
  - Mosco / strong-resolvent convergence is naturally a statement about
    Dirichlet forms / Laplacians, giving Delta on the S^3 limit.
  - On a spin manifold the Dirac operator is the canonical first-order
    square root of (a curvature-shifted) Delta (Lichnerowicz:
    D^2 = Nabla*Nabla + R/4). With the spin structure now fixed and unique,
    D_M is DETERMINED; the residual is to show the substrate's own
    Clifford / CAR structure (the Boolean -> CAR isomorphism PST already
    has) converges to THIS canonical D_M, not merely that Delta converges.

What this script verifies numerically:
  L1  The canonical S^3 Dirac spectrum and its Weyl law: spectral dimension 3,
      confirming the TARGET geometry of the Mosco limit is 3-dimensional
      (a consistency anchor; contrast Track I §B1, where the BARE hypercube
      Dirac operator has no fixed continuum dimension).
  L2  Lichnerowicz consistency: D^2 eigenvalues vs the scalar-curvature shift
      on the round S^3 (R = 6 for unit radius), as an internal cross-check.
  L3  The topological facts assembled into the spin-structure conclusion.

Run:
    python3 computation_04.py
"""
import numpy as np

SEP = "=" * 78
def hdr(s): print(f"\n{SEP}\n  {s}\n{SEP}")

print(SEP)
print("  PST Computation 4 — spin structure on the Mosco limit (Stage 3)")
print(SEP)

# ─────────────────────────────────────────────────────────────────────
# §1. Canonical S^3 Dirac spectrum and its Weyl law (spectral dimension 3)
# ─────────────────────────────────────────────────────────────────────
hdr("§1 — S^3 Dirac spectrum: eigenvalues, multiplicities, Weyl law")
print("""
  Round unit S^3 = SU(2). The Dirac operator has eigenvalues
      lambda = +/- (3/2 + k),   k = 0, 1, 2, ...,
  each with multiplicity (k+1)(k+2)  (Bar, space-form Dirac spectrum;
  spinor bundle rank 2, the +/- giving the two chirality-paired towers).
  The Weyl counting function N(L) = #{|lambda| <= L} should grow as L^3,
  the spectral dimension of a 3-manifold.
""")

def s3_levels(kmax):
    levels = []                      # (|lambda|, multiplicity for that sign)
    for k in range(kmax + 1):
        lam = 1.5 + k
        mult = (k + 1) * (k + 2)
        levels.append((lam, mult))
    return levels

KMAX = 4000
levels = s3_levels(KMAX)

print(f"  {'k':<5}{'|lambda| = 3/2+k':<18}{'mult (k+1)(k+2)':<18}")
print(f"  {'-'*40}")
for k in range(6):
    lam, m = levels[k]
    print(f"  {k:<5}{lam:<18.1f}{m:<18}")
print("  ...")

# Weyl law: N(L) = sum over both signs of multiplicities with |lambda| <= L
Ls, Ns = [], []
cum = 0
for (lam, mult) in levels:
    cum += 2 * mult                  # factor 2 for +/- towers
    Ls.append(lam); Ns.append(cum)
Ls = np.array(Ls); Ns = np.array(Ns)
mask = (Ls > 5) & (Ls < Ls.max() * 0.8)    # fit the bulk
slope, intercept = np.polyfit(np.log(Ls[mask]), np.log(Ns[mask]), 1)
print(f"\n  Weyl-law fit  log N(L) = d_s log L + c  over the bulk:")
print(f"    spectral dimension d_s = {slope:.4f}   (target 3)")
print(f"    => the S^3 Dirac operator has spectral dimension 3, the correct")
print(f"       spatial dimension of the Mosco-limit target geometry.")

# ─────────────────────────────────────────────────────────────────────
# §2. Lichnerowicz consistency on the round S^3
# ─────────────────────────────────────────────────────────────────────
hdr("§2 — Lichnerowicz cross-check: D^2 = Nabla*Nabla + R/4 on S^3")
print("""
  Lichnerowicz: D^2 = Nabla* Nabla + R/4, with R the scalar curvature.
  For the round unit S^3, R = n(n-1) = 6, so R/4 = 3/2. The lowest Dirac
  eigenvalue is |lambda_0| = 3/2, so the lowest D^2 eigenvalue is (3/2)^2
  = 9/4. The connection-Laplacian part Nabla*Nabla is then >= 0:
      Nabla*Nabla_min = D^2_min - R/4 = 9/4 - 3/2 = 3/4 >= 0,
  consistent with a non-negative Laplacian. We tabulate D^2 - R/4 across
  the tower and confirm it stays non-negative (a curvature/sign sanity
  check on the canonical Dirac operator).
""")
R_over_4 = 1.5
print(f"  {'k':<5}{'lambda^2':<14}{'lambda^2 - R/4':<18}{'>= 0 ?'}")
print(f"  {'-'*45}")
all_nonneg = True
for k in range(6):
    lam = 1.5 + k
    val = lam * lam - R_over_4
    nn = val >= -1e-12
    all_nonneg = all_nonneg and nn
    print(f"  {k:<5}{lam*lam:<14.3f}{val:<18.3f}{nn}")
print(f"\n  Nabla*Nabla = D^2 - R/4 non-negative across the tower: {all_nonneg}")

# ─────────────────────────────────────────────────────────────────────
# §3. Topological spin-structure facts assembled
# ─────────────────────────────────────────────────────────────────────
hdr("§3 — Spin structure on M = R x S^3 (topological part: closes)")
facts = [
    ("S^3 is parallelizable (= SU(2)), hence orientable and spin", True),
    ("w_2(S^3) in H^2(S^3;Z/2) = 0  -> spin obstruction vanishes", True),
    ("H^1(S^3;Z/2) = 0  -> spin structure is UNIQUE", True),
    ("M = R x S^3 globally hyperbolic, spin iff S^3 spin -> M spin, unique", True),
]
for txt, ok in facts:
    print(f"    [{'OK' if ok else '  '}] {txt}")
print("""
  Conclusion (topological): the Mosco-limit spacetime M = R x S^3 carries a
  unique spin structure, hence a canonical Dirac operator D_M determined by
  the metric. KO-dimension 4. This closes the topological half of the
  spin-structure step.

  Residual (analytic), stated precisely:
    Show the substrate's rescaled Boolean Dirac-type operator (built from the
    Boolean -> CAR Clifford structure PST already has) converges, in strong
    resolvent sense, to this canonical D_M -- not merely that the Dirichlet
    form / Laplacian converges (which PST already argues to the S^3 metric).
    Because the spin structure is now fixed and unique, the target D_M is
    UNIQUELY determined; the residual is a convergence statement to a known
    limit, not a search among inequivalent spin structures.

  Stage 3 outcome: PARTIALLY CLOSED. Topology done (unique spin structure,
  canonical D_M, KO-4). The analytic convergence to D_M is the remaining
  piece, now reduced to convergence-to-a-unique-target rather than an
  open-ended existence question. This is the honest state of the deepest
  item, and it is sharper than before: the obstruction is one named
  convergence theorem.
""")
