#!/usr/bin/env python3
"""
E1: THE CHOICE-SPACE (ADDRESS-SPACE) DEFINITION for the DFD trials-factor theorem.
HONESTY-GUARD MAXIMAL: conservative = LARGER space. Every number below is computed, not asserted.

Corpus sources (READ-ONLY, verified 2026-07-02):
  F   = integrate_v40/v40/appendix_F.tex        (rem:q1-honest the derivation record; rem:independence the derivation record;
                                                 thm:flux-product the derivation record; rem:ngen-input the derivation record; app:spinz4 the derivation record)
  O   = integrate_v40/v40/appendix_O_alpha57.tex (the derivation record,148-153: k_max=60 input-chain, a-posteriori sub-ppm alpha match)
  AU  = integrate_v40/v40/appendix_AU_dark_energy.tex (the derivation record: look-elsewhere grammar 9 prefactors x 15 exponents = 135, 3 hits)
  AO  = integrate_v40/v40/appendix_AO_ckm_update.tex  (L96-125 anti-theorem apex {43/2,22}; the derivation record Postulate E.1 +
                                                 "4pi split g^2=alpha vs 4pi*alpha conventional" = unit binary)
  CE  = integrate_v40/v40/appendix_CE_combined_evidence.tex (L59-67: 4 cleanly-forced + 2 softer rows discipline -- REUSED)
  Z   = integrate_v40/v40/appendix_Z_complete_params.tex (the derivation record,340,396: 6 derived + 2 selected/input rows; N_gen=Input;
                                                 v prefactor asserted)
  Sources: the derivation record (private working notes) and the corpus appendices cited per entry.
                                                 the derivation record ten (a,n) bundles; the derivation record the 11 genuinely-free inputs;
                                                 the derivation record k_max = selection-plus-match, q1 menu, alt assemblies;
                                                 the derivation record chi-measure P1-P4, P4 operator-selected; the derivation record 5 gauge free choices)
"""
from math import comb, pi, prod
import json

out = {}

# ---------------------------------------------------------------- sanity arithmetic
assert comb(11, 2) + 5 == 60                      # chi(O(9)) + 5 = 55 + 5 = 60   [F rem:independence]
assert 60 - 3 == 57                                # nonzero-mode count            [O the derivation record]

# ten (a,n) bundles with C(a+2,2)+n = 60, n>=0    (derivation record)
bundles_60 = [(a, 60 - comb(a + 2, 2)) for a in range(0, 20) if 60 - comb(a + 2, 2) >= 0]
assert len(bundles_60) == 10 and (9, 5) in bundles_60
out["bundles_at_index_60"] = bundles_60

# k_max menu over the q1 menu (a = N_gen*q1, N_gen=3, n=5): F rem:q1-honest verbatim {q1=1->15, q1=3->60, q1=6->195}
kmax = lambda q1, ngen=3, n=5: comb(ngen * q1 + 2, 2) + n
assert kmax(1) == 15 and kmax(3) == 60 and kmax(6) == 195
out["kmax_menu_over_q1"] = {q: kmax(q) for q in (1, 3, 6)}

# alpha discreteness of the k-ladder: only ONE integer k can sit within sub-ppm of alpha^-1
# alpha^-1(k) = (pi^1.5/24) * Tr(Y^2)=10 * k(k+3)/(k+4) * [1 + 7/(80(d^2-1))], d=k+4   (derivation record)
alpha_inv = lambda k: (pi ** 1.5 / 24) * 10 * k * (k + 3) / (k + 4) * (1 + 7 / (80 * ((k + 4) ** 2 - 1)))
step = alpha_inv(61) - alpha_inv(60)
out["alpha_ladder"] = {"alpha_inv_60": alpha_inv(60), "step_per_unit_k": step,
                       "step_in_ppm_of_alpha": step / alpha_inv(60) * 1e6}   # ~17,000 ppm >> sub-ppm window

# AU look-elsewhere grammar: 9 prefactors x 15 exponents = 135, 3 hits   [AU the derivation record verbatim]
AU_prefactors = ["1", "3/8pi", "1/8pi", "3/4pi", "1/4pi", "1/2", "2", "pi", "1/pi"]
AU_exponents = list(range(50, 65))
assert len(AU_prefactors) * len(AU_exponents) == 135 and len(AU_exponents) == 15
out["AU_grammar"] = {"prefactors": 9, "exponents": 15, "total": 135, "hits_in_band": 3}

# ---------------------------------------------------------------- (A) FIXED BY THEOREM given the (B) coordinates
out["A_fixed"] = {
    "manifold_CP2xS3": "unique GIVEN axioms V1-V9; V6 = the gauge-partition input, plus observed N_gen "
                       "[appendix_AB thm:uniqueness + its own L29-30 independence remark] -> conditional theorem, "
                       "freedom lives in the (B) coordinates it cites, NOT here",
    "a_eq_Ngen_x_q1": "automatic-Lambda^3 lemma: det(C^3 x O(q1)) = O(3 q1); alpha-free arithmetic [F the derivation record,160]",
    "kmax_arithmetic": "k_max = chi(O(a)) + n = C(a+2,2) + n, exact HRR [F rem:independence]",
    "57_eq_kmax_minus_Ngen": "mode-count subtraction, exact [O the derivation record]",
    "flux_product_identity": "N_gen = |k3 k2 q1| is BOOKKEEPING within the construction, not an index theorem "
                             "[F thm:flux-product + rem:ngen-input] -> imposes NO independent constraint",
    "k2_k3_eq_1": "BPS minimality with kappa_r>0 POSITED [F thm:energy-min; ledger 'BPS selections'] -> folded into "
                  "the N_gen coordinate (counting both would double-count)",
    "AU_exponent_57": "forced = k_max - N_gen given the address; Friedmann prefactor 3/8pi forced by closure-density "
                      "definition [AU the derivation record] -> baseline grammar residual = 1",
    "minimal_padding_is_NOT_an_axiom": "corpus status: (9,5) needs an extra max-a/min-padding rule + the 'n=5 = SM "
                                        "5 species' reading -- 'Both SM-content choices, not index outputs' "
                                        "(derivation record) -> (a,n) belongs to (B), NOT (A)",
}

# ---------------------------------------------------------------- (B) RESIDUAL CHOICE COORDINATES
# Each factor: (baseline = corpus-honest menu, conservative = honesty-guard enlarged menu, citation)
B = {
 "q1": dict(base=2, cons=3,
    cite="F rem:q1-honest the derivation record verbatim: 'selected from the discrete menu {1,3,6,...}'; strict uniform-spin^c min "
         "q1=6; q1=1 (Z6 center flux) 'provably fail[s]' (every SM multiplet Z6-neutral) -> baseline {3,6}; "
         "conservative keeps 1 anyway: {1,3,6}. Tail q1>=9 gives k_max>=440, outside every evaluated menu."),
 "gauge_partition": dict(base=2, cons=5,
    cite="recorded anomaly audit (derivation record): (3,2,1) SELECTED-IRREDUCIBLE; anomaly "
         "constraints leave SM + Pati-Salam (baseline 2). Route C the derivation record: SU(5), SO(10), trinification ALSO "
         "anomaly-free and admit a chi=60 bundle; their exclusion via dim X=7 is CIRCULAR -> conservative 5. "
         "(The 2026-06-28 isometry kill of PS conditions on K=CP2xS3, whose uniqueness axiom V6 presupposes the "
         "partition -> honesty-guard refuses that reduction.)"),
 "N_gen": dict(base=6, cons=9,
    cite="F rem:ngen-input: DISCRETE INPUT, same epistemic class as SM rep content; flux-product rule is bookkeeping "
         "so it does NOT bound N_gen. Honest bound = construction viability: a=N_gen*q1 must land k_max inside the "
         "corpus's own evaluated ladder [15,195] -> N_gen*q1<=18 -> N_gen in {1..6} at q1=3 (baseline 6). "
         "Conservative box {1..9} (a<=27, k_max<=440, the last value the corpus ever printed)."),
 "padding_n": dict(base=2, cons=10,
    cite="n=5 = SM hypercharged-type count, an INPUT [F rem:independence]; given the SM partition the count is "
         "nearly forced, but nu_R (Y=0) creates a genuine 5-vs-6 reading -> baseline 2. Conservative: the full "
         "10-bundle menu {(a,n): C(a+2,2)+n=60} (derivation record: the derivation record, computed above) = 10."),
 "assembly_rule": dict(base=1, cons=7,
    cite="baseline: post-2026-07-02 corpus has ONE assembly (det-line chain; automatic-Lambda^3 + Bismut-Quillen "
         "shared-provenance removed rivals). Conservative: the audit's alternate assemblies gave "
         "{6,8,10,24,78,96,195} (derivation record) = 7 extra readings."),
 "CKM_E1": dict(base=2, cons=8,
    cite="AO anti-theorem L96-125: apex branch {43/2, 22} genuinely 2-way (Postulate E.1 selects) = baseline 2. "
         "Conservative x2 unit identification (g^2=alpha vs 4pi*alpha 'being conventional', AO the derivation record) "
         "x2 eta-bar=49=D^2 SELECTED [normalization thm knob 5, derivation record] = 8."),
 "closure_grammar": dict(base=1, cons=135,
    cite="AU the derivation record: grammar = 9 prefactors x 15 exponents (n in [50,64]) = 135 candidates, 3 hits. Baseline 1: "
         "exponent 57 is derived from the address (k_max - N_gen) and prefactor 3/8pi is forced by the Friedmann "
         "closure-density definition [AU the derivation record]. Conservative: full 135 (treat both as free, worst case)."),
 "sign_bits": dict(base=4, cons=16,
    cite="recorded 2-bit result (derivation record): Bit A = sign(J) (arrow/quantum-i/eta_B), Bit B = s_FS "
         "(delta_CP/handedness) -> baseline 2^2=4. Conservative adds ledger-the derivation record items [3] which-SU(2)-gauged and "
         "[4] L-vs-R label (+2 bits; item [5] breaking channel not instantiated in the canonical build) = 2^4=16."),
 "axiom_adoption_bits": dict(base=1, cons=8,
    cite="three adopt/not axioms with no numeric menu: clock-dictionary (H0 tP)^2=alpha^57 [knob 4]; chi-measure P4 "
         "identification (operator-selected/asserted, derivation record); Q_chi=1 rest-mass channel (+1 grav "
         "axiom, derivation record). Baseline: axioms, not address coordinates (they pick no value from a menu of "
         "could-have-hit alternatives) -> factor 1, listed. Conservative: 2^3=8."),
}
out["B_residual"] = {k: v["cite"] for k, v in B.items()}

# lambda_H and sqrt(2pi)/pi decision (HONEST, stated): the normalization theorem (derivation record) books
# lambda_H=1/8 (knob 8) and the v/m3 normalizations {sqrt(2pi), pi} (knob 9) as GENUINELY-FREE INPUTS, and
# appendix_Z the derivation record/the derivation record says 'prefactor is fitted / asserted'. So they are FREE PARAMETERS (class C-adjacent),
# NOT discrete trials coordinates: counting them as 9-way grammar draws AND as free knobs would double-count.
out["decision_lambdaH_sqrt2pi"] = ("FREE PARAMETERS (normalization-theorem knobs 8,9; appendix_Z 'fitted/asserted') "
                                   "-> excluded from |A|; their look-elsewhere burden is carried per-closure by the "
                                   "AU-style 135-grammar when any of them is claimed as a HIT (none currently is).")

# ---------------------------------------------------------------- (C) CONTINUOUS / EMPIRICAL imports (outside the discrete theorem)
out["C_continuous"] = [
    "alpha = 1/137.036 (the single coupling; it is the SELECTOR datum, so it must NOT also be a coordinate)",
    "hbar value (one dimensionful unit; Buckingham-Pi pins G*hbar only -- routeC no-go)",
    "one scale (H0 via the clock dictionary; equivalently Omega_Lambda fit)",
    "theta* screen-gate amplitude (~0.39; data-fitted 1 dof) [knob 2]",
    "light-fermion fit cluster: ~5-6 of 9 Yukawa prefactors + assignment dictionary [knob 10] (continuous fits)",
    "SM hypercharge VALUE SET / rep content (empirical input class, per rem:ngen-input; not a small enumerable menu)",
]

# ---------------------------------------------------------------- totals
# TWO DE-DOUBLE-COUNTING RULES (honesty-guard: a double-counted dimension is as fatal as an undercounted one):
# (R1) (q1, N_gen, n, assembly) act on every numeric prediction ONLY through the observable pair (k_max, N_gen).
#      Distinct raw addresses mapping to the same pair are ONE effective trial -> count distinct pairs.
# (R2) The AU 15-exponent window n in [50,64] is the look-elsewhere of 57 = k_max - N_gen, which the pair
#      (k_max, N_gen) ALREADY varies. Multiplying by 15 again would double-count -> the address-level grammar
#      residual is the 9 prefactors only. (AU's standalone 135 is recovered when the microsector is frozen,
#      which is exactly how appendix_AU books its own 3/135 CC hit.)
# VIABILITY CAP (conservative but finite): k_max <= 195 = the largest candidate the corpus ever evaluated
#      (q1=6 chain, F rem:q1-honest); beyond it no address was ever a live rival.
CAP = 195

def micro_pairs(q1s, ngens, ns, extra_kmax):
    pairs = {(comb(q1 * ng + 2, 2) + n, ng) for q1 in q1s for ng in ngens for n in ns
             if comb(q1 * ng + 2, 2) + n <= CAP}
    pairs |= {(k, ng) for k in extra_kmax for ng in ngens if k <= CAP}
    return pairs

pairs_base = micro_pairs((3, 6), range(1, 7), (5, 6), [])
pairs_cons = micro_pairs((1, 3, 6), range(1, 10), (5, 6), [6, 8, 10, 24, 78, 96, 195])
# the 10-bundle menu at index 60 collapses under R1 (all have k_max=60) -> multiplicity, not new pairs (computed):
assert all(comb(a + 2, 2) + n == 60 for a, n in bundles_60)

core_base = len(pairs_base) * B["gauge_partition"]["base"] * B["CKM_E1"]["base"] * B["closure_grammar"]["base"]
core_cons = len(pairs_cons) * B["gauge_partition"]["cons"] * B["CKM_E1"]["cons"] * 9   # 9 = prefactors only (R2)
full_base = core_base * B["sign_bits"]["base"] * B["axiom_adoption_bits"]["base"]
full_cons = core_cons * B["sign_bits"]["cons"] * B["axiom_adoption_bits"]["cons"]
raw_box   = prod(v["cons"] for v in B.values())   # flagged ceiling only (violates R1+R2 by construction)

out["totals"] = {
    "micro_pairs_baseline": len(pairs_base), "micro_pairs_conservative": len(pairs_cons),
    "kmax_values_baseline": sorted({k for k, _ in pairs_base}),
    "kmax_values_conservative": sorted({k for k, _ in pairs_cons}),
    "core_baseline": core_base,
    "core_conservative": core_cons,
    "full_baseline_with_bits": full_base,
    "full_conservative_with_bits": full_cons,
    "raw_box_ceiling_flagged": raw_box,
    "note_bits": "sign/axiom-adoption bits pick no value from a numeric menu, so they generate NO rival numeric "
                 "hits; per-hit trials (CE discipline) use the CORE factors. They are kept in the full count for "
                 "worst-case honesty.",
    "HEADLINE": f"|A|_core (numeric address space) = {core_base} (baseline) .. {core_cons} (conservative); "
                f"with convention/axiom bits {full_base} .. {full_cons}; naive box ceiling {raw_box} (flagged "
                f"double-count, ruled out by R1+R2).",
}
print(json.dumps(out, indent=1, default=str))
with open("E1_address_space.json", "w") as f:
    json.dump(out, f, indent=1, default=str)
