#!/usr/bin/env python3 """ PROVENANCE: PROOF Computation 175 -- colour and generation cannot be independent labels on tau-perp, and the Dixon ambient does not change that ======================================================================== WHAT THIS SETTLES. history/research/open_research.md item 3.6 was closed at v25.8 and REOPENED at v32.64 when comp 106's block-diagonality claim was withdrawn. The closure said, and sec:gauge still said until this computation landed, that "PST resolves this on the Dixon side by moving to the ambient C (x) H (x) O, where the three generation sectors are orthogonal (comp 48)". That inference is invalid, and this file shows it in three steps, each measured rather than asserted. (1) ORTHOGONALITY IS NOT INVARIANCE. The three Fano lines through tau-hat ARE mutually orthogonal, exactly: Tr(P_i P_j) = 0 to machine zero, each P is a genuine projector, and the ranks sum to dim(tau-perp) = 6. comp 48's decomposition is real. And colour still leaks out of them at O(1). Both statements are true at once, because orthogonality of subspaces says nothing about whether a group preserves them. The v25.8 closure used the first to claim the second. (2) THE OBSTRUCTION IS A THEOREM, NOT A DIMENSION COUNT. The register states it as "3 (x) 3 needs real dimension >= 18 against tau-perp's 6". True, but weaker than what actually holds. The commutant of Stab_{G_2}(tau-hat) on tau-perp is computed here and is exactly 2-dimensional over R, i.e. C. By Schur that makes tau-perp an IRREDUCIBLE complex 3-dimensional representation: the fundamental 3. An irreducible representation has NO proper invariant subspace at all. So there is no colour-invariant way to split tau-perp into generation sectors -- not merely none that anyone has found. The dimension count rules out a tensor factorisation; irreducibility additionally rules out a direct-sum one, which is the case the Fano lines actually realise. (3) THE DIXON AMBIENT CHANGES NOTHING. Colour acts on C (x) H (x) O only through the O factor, as I (x) g. The sectors are G_k = (C (x) H) (x) L_k. Then ||(1 - I(x)P_k)(I(x)g)(I(x)P_k)|| = ||I (x) (1-P_k) g P_k|| = ||(1-P_k) g P_k|| in operator norm, so the leakage on the 64-real-dimensional ambient is IDENTICAL to the leakage on O alone. Measured here to 0.00e+00 difference across trials. The ambient supplies room (64 real dimensions against 8) and no invariance whatever. Tensoring a slot with factors that colour does not act on cannot change how colour moves that slot. WHAT SURVIVES, AND IT IS NOT NOTHING. The COUNT three is untouched: tau-perp is 3-dimensional over C, robustly, and that is where N_gen = 3 and N_c = 3 both come from. What fails is reading the same three directions as two INDEPENDENT labels. PST therefore derives one three, not two, and inherits the octonionic programme's colour-versus-generation question rather than closing it. That is what sec:ngen-mechanism and the Summary now say, and what sec:gauge said the opposite of until this file. SCOPE. This is a statement about tau-perp and about the Dixon ambient built over it. It does not say no resolution exists anywhere; it says the two specific moves the book made -- orthogonal sectors, and the enlargement to C (x) H (x) O -- do not provide one, and that within tau-perp none can. """ import numpy as np from scipy.linalg import expm TAU = 7 TRIPLES = [(1, 2, 3), (1, 4, 5), (1, 7, 6), (2, 4, 6), (2, 5, 7), (3, 4, 7), (3, 6, 5)] def rule(): print("=" * 100) def octonions(): C = np.zeros((8, 8, 8)) for i in range(8): C[0, i, i] = 1.0 C[i, 0, i] = 1.0 for i in range(1, 8): C[i, i, 0] = -1.0 for (a, b, c) in TRIPLES: for (x, y, z) in [(a, b, c), (b, c, a), (c, a, b)]: C[x, y, z] += 1.0 C[y, x, z] -= 1.0 return C C = octonions() E = np.eye(8) def mul(u, v): return np.einsum('i,j,ijk->k', u, v, C) def stabiliser(): """Der(O) = g_2, then the subalgebra annihilating tau-hat = su(3).""" rows = [] for i in range(8): for j in range(8): blk = np.zeros((8, 64)) eij = mul(E[i], E[j]) for a in range(8): for b in range(8): v = np.zeros(8) v[a] = eij[b] w = mul(E[a], E[j]) if b == i else np.zeros(8) u = mul(E[i], E[a]) if b == j else np.zeros(8) blk[:, a * 8 + b] = v - w - u rows.append(blk) _, s, Vt = np.linalg.svd(np.vstack(rows)) der = [Vt[k].reshape(8, 8) for k in range(64) if k >= len(s) or s[k] < 1e-9] M = np.array([(d @ E[TAU]) for d in der]).T _, s2, Vt2 = np.linalg.svd(M) coef = [Vt2[k] for k in range(len(der)) if k >= len(s2) or s2[k] < 1e-9] return der, [sum(c[i] * der[i] for i in range(len(der))) for c in coef] def fano_lines(): return [tuple(sorted(set(t) - {TAU})) for t in TRIPLES if TAU in t] # --------------------------------------------------------------------------- def part1(der, stab): rule() print(" 1. THE ALGEBRA") rule() ok = len(der) == 14 and len(stab) == 8 print(f" dim Der(O) = {len(der):2d} (g_2 = 14)") print(f" dim Stab_{{g_2}}(tau-hat) = {len(stab):2d} (su(3) = 8)") print(f" -> the colour algebra is where the book says it is : {ok}") print() return ok def part2(stab, lines): rule() print(" 2. ORTHOGONALITY IS NOT INVARIANCE") rule() P = [sum(np.outer(E[k], E[k]) for k in L) for L in lines] off = max(abs(np.trace(P[i] @ P[j])) for i in range(3) for j in range(3) if i != j) idem = max(np.linalg.norm(p @ p - p) for p in P) ranks = sum(int(round(np.trace(p))) for p in P) print(f" the three Fano lines through tau-hat : {lines}") print(f" max |Tr(P_i P_j)|, i != j : {off:.2e}") print(f" max ||P^2 - P|| : {idem:.2e}") print(f" ranks sum to : {ranks} (= dim tau-perp)") orth = off < 1e-12 and idem < 1e-12 and ranks == 6 print(f" -> the sectors ARE exactly orthogonal, comp 48 stands : {orth}") print() rng = np.random.default_rng(20260929) worst = 0.0 for _ in range(8): g = expm(sum(rng.normal() * S for S in stab)) for p in P: worst = max(worst, float(np.linalg.norm((np.eye(8) - p) @ g @ p, 2))) print(f" max leakage ||(1 - P) g P|| over random colour g : {worst:.3f}") leaks = worst > 0.1 print(f" -> and colour does NOT preserve them : {leaks}") print() print(" Both hold at once. Orthogonality of subspaces is not invariance") print(" under a group. The v25.8 closure inferred the second from the") print(" first, and that step is what reopened item 3.6.") print() return orth and leaks, P def part3(stab): rule() print(" 3. SCHUR: tau-perp IS IRREDUCIBLE, SO NO GENERATION SPLITTING EXISTS") rule() idx = [1, 2, 3, 4, 5, 6] n = len(idx) R = [S[np.ix_(idx, idx)] for S in stab] blocks = [] for A in R: B = np.zeros((n * n, n * n)) for r in range(n): for c in range(n): Ers = np.zeros((n, n)) Ers[r, c] = 1.0 B[:, r * n + c] = (Ers @ A - A @ Ers).flatten() blocks.append(B) sv = np.linalg.svd(np.vstack(blocks), compute_uv=False) dim_comm = n * n - int((sv > 1e-9).sum()) print(f" dim of the real commutant of su(3) on tau-perp : {dim_comm}") print( " 1 -> real irreducible 2 -> COMPLEX irreducible (= C) >2 -> reducible") ok = dim_comm == 2 print(f" -> tau-perp is the irreducible fundamental 3 : {ok}") print() print(" An irreducible representation has NO proper invariant subspace.") print(" So there is no colour-invariant way to split tau-perp into") print(" generation sectors at all: the Fano-line splitting exists as a") print(" decomposition of the vector space and is not preserved, which is") print(" exactly what part 2 measured.") print() print(" The dimension count in the register rules out a TENSOR") print(" factorisation: 3_colour (x) 3_gen would need 9 complex = 18 real") print(" dimensions against tau-perp's 3 complex = 6. Irreducibility") print(" additionally rules out a DIRECT-SUM one, which is the case the") print(" Fano lines actually realise. The obstruction is therefore a") print(" theorem, not a counting remark.") print() return ok def part4(stab, P): rule() print(" 4. THE DIXON AMBIENT C (x) H (x) O CHANGES NOTHING") rule() CH = np.eye(8) # C (x) H: real dim 8, colour acts trivially on it rng = np.random.default_rng(4242) print(" sectors G_k = (C (x) H) (x) L_k ; colour acts as I (x) g") print() print(f" {'trial':>6}{'leak on O':>14}{'leak on the ambient':>22}{'difference':>14}") worst_diff = 0.0 for t in range(5): g = expm(sum(rng.normal() * S for S in stab)) G = np.kron(CH, g) a = float(np.linalg.norm((np.eye(8) - P[0]) @ g @ P[0], 2)) Pk = np.kron(CH, P[0]) b = float(np.linalg.norm((np.eye(64) - Pk) @ G @ Pk, 2)) worst_diff = max(worst_diff, abs(a - b)) print(f" {t:>6}{a:>14.4f}{b:>22.4f}{abs(a-b):>14.1e}") print() print(f" max difference across trials : {worst_diff:.2e}") ok = worst_diff < 1e-9 print(f" -> identical, so the ambient supplies no invariance : {ok}") print() print(" And necessarily so:") print(" ||(1 - I(x)P)(I(x)g)(I(x)P)|| = ||I (x) (1-P)gP|| = ||(1-P)gP||.") print(" Tensoring a slot with factors colour does not act on cannot change") print(" how colour moves that slot. The ambient gives ROOM, 64 real") print(" dimensions against 8, and no invariance whatever.") print() return ok def part5(): rule() print(" 5. WHAT SURVIVES") rule() print(" The COUNT three is untouched. tau-perp is 3-dimensional over C,") print(" and that single fact is where BOTH N_c = 3 and N_gen = 3 come from.") print(" What fails is reading those same three directions as two") print(" INDEPENDENT labels. PST derives one three, not two.") print() print(" So the honest status is: PST INHERITS the octonionic programme's") print(" colour-versus-generation question rather than closing it, and") print(" tree-level FCNC absence is not a structural theorem of PST.") print() return True def part6(stab, P): rule() print(" 6. TAMPER TEST") rule() # The Cartan torus DOES preserve the lines. If the leakage test could not # tell the two cases apart it would be measuring nothing. idx = [1, 2, 3, 4, 5, 6] blocks = [] for Ln in [tuple(sorted(set(t) - {TAU})) for t in TRIPLES if TAU in t]: Pp = sum(np.outer(E[k], E[k]) for k in Ln) Q = np.eye(8) - Pp blocks.append(np.array([(Q @ S @ Pp).flatten() for S in stab]).T) sv = np.linalg.svd(np.vstack(blocks), compute_uv=False) dim_pres = len(stab) - int((sv > 1e-9).sum()) rng = np.random.default_rng(99) # build a generic element of the preserving subalgebra and show it does NOT leak _, s, Vt = np.linalg.svd(np.vstack(blocks)) null = [Vt[k] for k in range(len(stab)) if k >= len(s) or s[k] < 1e-9] X = sum(rng.normal() * sum(c[i] * stab[i] for i in range(len(stab))) for c in null) gC = expm(X) leak_cartan = max(float(np.linalg.norm((np.eye(8) - p) @ gC @ p, 2)) for p in P) print(f" dim of the subalgebra preserving all three lines : {dim_pres} (maximal torus)") print(f" leakage for a generic element of THAT subalgebra : {leak_cartan:.2e}") print(f" leakage for a generic element of all of su(3) : O(1), part 2") ok = dim_pres == 2 and leak_cartan < 1e-9 print(f" -> the test separates the two cases, so it measures something : {ok}") print() return ok def main(): print() rule() print(" COMPUTATION 175. Colour and generation cannot be independent labels") rule() print(""" Item 3.6 was closed at v25.8 on the ground that the Dixon ambient makes the three generation sectors orthogonal. That is true and it does not resolve anything, for reasons measured below rather than asserted. """) der, stab = stabiliser() r1 = part1(der, stab) r2, P = part2(stab, fano_lines()) r3 = part3(stab) r4 = part4(stab, P) r5 = part5() r6 = part6(stab, P) rule() print(" ASSESSMENT") rule() print(f" 1. Der(O) = 14 and Stab(tau-hat) = 8 : {r1}") print(f" 2. sectors orthogonal AND colour leaks out of them : {r2}") print(f" 3. tau-perp irreducible, so no invariant splitting exists : {r3}") print(f" 4. the Dixon ambient leaves the leakage identical : {r4}") print(f" 5. the count three survives; two independent labels do not: {r5}") print(f" 6. tamper test: the Cartan case is distinguished : {r6}") print() print(""" RESULT. Item 3.6 stays OPEN, and is now sharper than "unproven". Within tau-perp a colour-invariant generation splitting is IMPOSSIBLE, by Schur: the representation is irreducible and has no proper invariant subspace. The move to C (x) H (x) O, which the book offered as the resolution, changes the leakage by exactly zero, because colour acts only on the O factor. What survives is the count. tau-perp is 3-dimensional over C, and that one fact is the source of both N_c = 3 and N_gen = 3. PST derives ONE three. Reading it as two independent labels is what the octonionic programme leaves open, and PST inherits that rather than closing it.""") print() return all([r1, r2, r3, r4, r5, r6]) if __name__ == "__main__": import sys # Exit only on FAILURE. The website runs these in the browser under Pyodide, # where SystemExit is fatal even at status 0: it tears the runtime down, and the # page prints ERROR after output that was in fact correct. Falling off the end # hands the build gates the same status 0, and a failure still exits 1. if not main(): sys.exit(1)