The number-theory arc established two facts that look contradictory:
This example resolves the apparent contradiction and unifies the arc. The same canonical operator on the same residue digraph exhibits a clean double dissociation — its spectrum sees the arithmetic, its per-node substrate does not — and there is ONE structural reason: vertex-transitivity.
The residue digraph is a Cayley digraph of ℤ_n with connection set = the quadratic residues. The translation σ: i → i+1 (mod n) is ALWAYS a graph automorphism (an edge (i,j) exists iff (j−i) mod n is a QR, and σ preserves the difference j−i). So the automorphism group acts on nodes — every node is structurally equivalent to every other.
Consequence: the graph's arithmetic (which differences are QRs) is a property of the EDGE structure that is INVARIANT under the node automorphism. It cannot imprint a per-node distinction, because all nodes are equivalent. Therefore:
Everything uses the canonical emergent substrate: the per-node fields come
from extract_phase_space_point (the symplectic substrate Φ_s, K_φ, J_φ,
J_ΔNFR), the spectrum from structural_diffusion_operator (the literal ΔNFR
EPI channel), and the dynamics is the canonical nodal equation
∂EPI/∂t = νf·ΔNFR. The ONLY arithmetic input is x² mod n.
R1 VERTEX-TRANSITIVITY. The translation i → i+1 (mod n) is an automorphism of the residue digraph for every n (edge set invariant). The structural fact.
R2 DOUBLE DISSOCIATION. Compare the Paley residue digraph (QR structure) against a random regular tournament of the SAME out-degree, both seeded with the SAME random field and evolved by the canonical nodal equation: - SPECTRUM: Paley has exactly 3 distinct eigenvalues (the prime signature of 119); the random tournament has ~n distinct eigenvalues. The spectrum SEES the QR arithmetic. - SUBSTRATE: the per-node Φ_s dispersion is statistically IDENTICAL for Paley and the random tournament. The substrate is BLIND to the QR arithmetic — swapping the arithmetic for a random tournament of the same degree leaves the substrate distribution unchanged.
R3 SUBSTRATE TRACKS SIZE, NOT PRIMALITY. Across odd n, the global spectrum detects primality exactly (3 distinct ⟺ prime), while the per-node substrate dispersion grows monotonically with n (graph size) and never separates primes from composites.
Vertex-transitivity (the residue graph's translation symmetry) confines the arithmetic to the spectral / group-representation sector Fix(G_aut)^⊥, and leaves the per-node substrate in the symmetric sector Fix(G_aut), which is blind. This is the SAME structure as the paused TNFR-Riemann program: the oscillatory residue S(T) = (1/π)arg ζ(½+iT) lives in ker(R∞) ∩ Fix(S_n)^⊥, unreachable by Fix(S_n)-trapped (symmetric) constructions (AGENTS.md "REMESH-∞ Closure", "B0★ closures"). So physics (the symplectic substrate), number theory (Gauss sums, primality), emergent geometry (the canonical operator), and the Riemann residual hit ONE wall — a SYMMETRY wall — located precisely: arithmetic is in the spectrum, the per-node substrate is in the fixed sector.
This EXPLAINS the e–π / Fix(G)^⊥ wall structurally (via vertex-transitivity / representation theory); it does NOT cross it and closes no open problem. It confirms, with a measured double dissociation and an arithmetic-neutral control, that running the directed dynamics does NOT let the per-node substrate see arithmetic — the blindness is a symmetry constraint, not a dynamics artefact. The arithmetic remains spectral, bounded by the same wall as the paused Riemann program.
#!/usr/bin/env python3
"""
Example 120 — The Symmetry Wall: Vertex-Transitivity Confines Arithmetic to
the Spectrum (the Per-Node Substrate Stays Blind)
===========================================================================
The number-theory arc established two facts that look contradictory:
* examples 103/116 — the per-node symplectic substrate (Φ_s, K_φ, J_ΔNFR)
is BLIND to arithmetic: it re-expresses whatever you inject through νf,
it does not discover primes.
* example 119 — the GLOBAL spectrum of the SAME canonical emergent operator
on the directed residue graph DETECTS all odd primes (58/58) and even the
Gauss-sum √n, in its complex phase.
This example resolves the apparent contradiction and unifies the arc. The
**same** canonical operator on the **same** residue digraph exhibits a clean
**double dissociation** — its spectrum sees the arithmetic, its per-node
substrate does not — and there is ONE structural reason: **vertex-transitivity**.
The structural mechanism (vertex-transitivity)
----------------------------------------------
The residue digraph is a Cayley digraph of ℤ_n with connection set = the
quadratic residues. The translation σ: i → i+1 (mod n) is ALWAYS a graph
automorphism (an edge (i,j) exists iff (j−i) mod n is a QR, and σ preserves
the difference j−i). So the automorphism group acts **transitively** on
nodes — every node is structurally equivalent to every other.
Consequence: the graph's arithmetic (which differences are QRs) is a property
of the EDGE structure that is INVARIANT under the node automorphism. It cannot
imprint a per-node distinction, because all nodes are equivalent. Therefore:
* Any per-node substrate variation must come from the (arithmetic-neutral)
SEED, never from the arithmetic — the substrate lives in the symmetric /
fixed sector Fix(G_aut), which is BLIND to the connection set.
* The arithmetic shows up only in a GLOBAL invariant sensitive to the
connection set — the SPECTRUM (eigenvalues = group-character / Gauss
sums) = the complement sector Fix(G_aut)^⊥.
Doctrine compliance
-------------------
Everything uses the canonical emergent substrate: the per-node fields come
from `extract_phase_space_point` (the symplectic substrate Φ_s, K_φ, J_φ,
J_ΔNFR), the spectrum from `structural_diffusion_operator` (the literal ΔNFR
EPI channel), and the dynamics is the canonical nodal equation
∂EPI/∂t = νf·ΔNFR. The ONLY arithmetic input is x² mod n.
Three measured results
----------------------
R1 VERTEX-TRANSITIVITY. The translation i → i+1 (mod n) is an automorphism of
the residue digraph for every n (edge set invariant). The structural fact.
R2 DOUBLE DISSOCIATION. Compare the Paley residue digraph (QR structure)
against a random regular tournament of the SAME out-degree, both seeded
with the SAME random field and evolved by the canonical nodal equation:
- SPECTRUM: Paley has exactly 3 distinct eigenvalues (the prime
signature of 119); the random tournament has ~n distinct eigenvalues.
The spectrum SEES the QR arithmetic.
- SUBSTRATE: the per-node Φ_s dispersion is statistically IDENTICAL for
Paley and the random tournament. The substrate is BLIND to the QR
arithmetic — swapping the arithmetic for a random tournament of the
same degree leaves the substrate distribution unchanged.
R3 SUBSTRATE TRACKS SIZE, NOT PRIMALITY. Across odd n, the global spectrum
detects primality exactly (3 distinct ⟺ prime), while the per-node
substrate dispersion grows monotonically with n (graph size) and never
separates primes from composites.
The unification (one wall, four domains)
----------------------------------------
Vertex-transitivity (the residue graph's translation symmetry) confines the
arithmetic to the spectral / group-representation sector Fix(G_aut)^⊥, and
leaves the per-node substrate in the symmetric sector Fix(G_aut), which is
blind. This is the SAME structure as the paused TNFR-Riemann program: the
oscillatory residue S(T) = (1/π)arg ζ(½+iT) lives in ker(R∞) ∩ Fix(S_n)^⊥,
unreachable by Fix(S_n)-trapped (symmetric) constructions (AGENTS.md
"REMESH-∞ Closure", "B0★ closures"). So physics (the symplectic substrate),
number theory (Gauss sums, primality), emergent geometry (the canonical
operator), and the Riemann residual hit ONE wall — a SYMMETRY wall — located
precisely: arithmetic is in the spectrum, the per-node substrate is in the
fixed sector.
Honest scope
------------
This EXPLAINS the e–π / Fix(G)^⊥ wall structurally (via vertex-transitivity /
representation theory); it does NOT cross it and closes no open problem. It
confirms, with a measured double dissociation and an arithmetic-neutral
control, that running the directed dynamics does NOT let the per-node
substrate see arithmetic — the blindness is a symmetry constraint, not a
dynamics artefact. The arithmetic remains spectral, bounded by the same wall
as the paused Riemann program.
References
----------
- src/tnfr/physics/symplectic_substrate.py (extract_phase_space_point)
- src/tnfr/physics/structural_diffusion.py (structural_diffusion_operator)
- examples/08_emergent_geometry/119_phase_sector_directed_residue.py (spectrum)
- examples/07_number_theory/116_nuf_emergent_prime_visibility.py (substrate blind)
- examples/08_emergent_geometry/118_emergent_vs_classical_operator.py (Cayley/regular)
- theory/TNFR_NUMBER_THEORY.md §9.7 (this example; the symmetry wall)
- AGENTS.md "REMESH-∞ Closure" (S(T) in ker(R∞) ∩ Fix(S_n)^⊥)
"""
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "src"))
import networkx as nx
import numpy as np
from sympy import isprime
from tnfr.alias import get_attr, set_attr
from tnfr.constants.aliases import ALIAS_DNFR, ALIAS_EPI, ALIAS_VF
from tnfr.dynamics import default_compute_delta_nfr
from tnfr.physics.structural_diffusion import structural_diffusion_operator
from tnfr.physics.symplectic_substrate import extract_phase_space_point
def _qr(n):
return {(x * x) % n for x in range(1, n)} - {0}
def residue_digraph(n):
"""Directed residue Cayley graph: edge i->j iff (j-i) mod n is a QR."""
R = _qr(n)
G = nx.DiGraph()
G.add_nodes_from(range(n))
for i in range(n):
for j in range(n):
if i != j and ((j - i) % n) in R:
G.add_edge(i, j)
return G
def random_regular_tournament(n, outdeg, seed):
"""Arithmetic-neutral control: each node picks outdeg random successors."""
rng = np.random.default_rng(seed)
G = nx.DiGraph()
G.add_nodes_from(range(n))
for i in range(n):
choices = [j for j in range(n) if j != i]
succ = rng.choice(choices, size=outdeg, replace=False)
for j in succ:
G.add_edge(i, int(j))
return G
def _seed_random(G, seed):
"""Arithmetic-neutral random initial TNFR state (the symmetry breaker)."""
rng = np.random.default_rng(seed)
for nd in G.nodes():
G.nodes[nd]["theta"] = float(rng.uniform(0, 2 * np.pi))
set_attr(G.nodes[nd], ALIAS_EPI, float(rng.uniform(-0.35, 0.35)))
set_attr(G.nodes[nd], ALIAS_VF, 1.0)
default_compute_delta_nfr(G)
def _evolve(G, steps=16, dt=0.05):
"""Canonical nodal equation EPI <- EPI + dt * nu_f * dNFR (mid-transient)."""
for _ in range(steps):
default_compute_delta_nfr(G)
for nd in G.nodes():
epi = float(get_attr(G.nodes[nd], ALIAS_EPI, 0.0))
vf = float(get_attr(G.nodes[nd], ALIAS_VF, 0.0))
dnfr = float(get_attr(G.nodes[nd], ALIAS_DNFR, 0.0))
set_attr(G.nodes[nd], ALIAS_EPI, epi + dt * vf * dnfr)
def _n_distinct(G, decimals=4):
"""Distinct eigenvalues of the CANONICAL emergent operator (global)."""
_, L = structural_diffusion_operator(G)
ev = np.linalg.eigvals(L)
return len(np.unique(np.round(ev, decimals)))
def _substrate_phi_std(G):
"""Per-node symplectic-substrate Phi_s dispersion (the local channel)."""
p = extract_phase_space_point(G)
return float(np.std(p.phi_s))
def experiment_1_vertex_transitivity():
"""R1: i -> i+1 mod n is an automorphism of the residue digraph."""
print("=" * 74)
print("EXPERIMENT 1: Vertex-Transitivity (the translation automorphism)")
print("=" * 74)
print("The residue digraph is a Cayley digraph of Z_n. The translation")
print("i -> i+1 (mod n) preserves the difference j-i, hence the QR edge")
print("set: it is ALWAYS an automorphism. All nodes are equivalent.")
print()
print(f" {'n':>4} {'mod4':>5} {'prime':>6} translation is automorphism?")
all_ok = True
for n in [7, 11, 13, 17, 19, 23, 25, 29]:
G = residue_digraph(n)
E = set(G.edges())
E_shift = {((i + 1) % n, (j + 1) % n) for (i, j) in E}
ok = E == E_shift
all_ok = all_ok and ok
print(f" {n:>4} {n % 4:>5} {str(isprime(n)):>6} {ok}")
print()
print(f" -> automorphism for every tested n: {all_ok}")
print(" The arithmetic (which differences are QRs) is invariant under")
print(" this node symmetry: it cannot label any individual node.")
def experiment_2_double_dissociation():
"""R2: spectrum sees the QR arithmetic, the per-node substrate does not."""
print()
print("=" * 74)
print("EXPERIMENT 2: Double Dissociation (spectrum vs per-node substrate)")
print("=" * 74)
print("Paley residue digraph (QR structure) vs a random regular tournament")
print("of the SAME out-degree. Both get the SAME random seed + canonical")
print("nodal evolution. Spectrum = global; Phi_s std = per-node substrate.")
print()
print(
f" {'n':>4} | {'Paley_dist':>10} {'rand_dist':>10} | "
f"{'Paley_phiStd':>12} {'rand_phiStd':>12}"
)
for n in [11, 19, 23, 31, 43, 47]:
Gp = residue_digraph(n)
outdeg = Gp.out_degree(0)
p_dist = _n_distinct(Gp)
_seed_random(Gp, 0)
_evolve(Gp)
p_phi = _substrate_phi_std(Gp)
r_dists, r_phis = [], []
for s in range(5):
Gr = random_regular_tournament(n, outdeg, seed=200 + s)
r_dists.append(_n_distinct(Gr))
_seed_random(Gr, 0)
_evolve(Gr)
r_phis.append(_substrate_phi_std(Gr))
print(
f" {n:>4} | {p_dist:>10} {np.mean(r_dists):>10.1f} | "
f"{p_phi:>12.4f} {np.mean(r_phis):>12.4f}"
)
print()
print(" -> SPECTRUM: Paley = 3 distinct (prime signature) vs random ~n")
print(" distinct. The spectrum SEES the QR arithmetic.")
print(" -> SUBSTRATE: Paley Phi_s std ~ random Phi_s std. The per-node")
print(" substrate is BLIND to the QR arithmetic (tracks the seed).")
def experiment_3_substrate_tracks_size():
"""R3: spectrum detects primality; substrate tracks size, not primality."""
print()
print("=" * 74)
print("EXPERIMENT 3: Substrate Tracks Size, Spectrum Tracks Primality")
print("=" * 74)
print("Across odd n: '3 distinct eigenvalues <=> prime' (global spectrum)")
print("vs per-node Phi_s std (local substrate). The substrate grows with n")
print("(graph size), never separating primes from composites.")
print()
print(
f" {'n':>4} {'prime':>6} {'spec_dist':>10} {'spec_prime?':>12} "
f"{'phiStd':>8}"
)
n_correct = 0
n_total = 0
for n in range(7, 42):
if n % 2 == 0:
continue
G = residue_digraph(n)
dist = _n_distinct(G)
spec_prime = dist == 3
_seed_random(G, 0)
_evolve(G)
phi = _substrate_phi_std(G)
ok = spec_prime == isprime(n)
n_correct += int(ok)
n_total += 1
flag = "OK" if ok else "XX"
print(
f" {n:>4} {str(isprime(n)):>6} {dist:>10} "
f"{str(spec_prime):>12} {phi:>8.4f} {flag}"
)
print()
print(f" -> spectral primality: {n_correct}/{n_total} correct.")
print(" The per-node Phi_s std is a smooth function of n (size), not")
print(" of primality: composites can exceed primes (e.g. 25 vs 29).")
def main():
print()
print(" TNFR Example 120: The Symmetry Wall - Vertex-Transitivity")
print(" Confines Arithmetic to the Spectrum; the Substrate Stays Blind")
print(" =============================================================")
print()
experiment_1_vertex_transitivity()
experiment_2_double_dissociation()
experiment_3_substrate_tracks_size()
print()
print("=" * 74)
print("WHAT THIS ESTABLISHES")
print("=" * 74)
print("The SAME canonical emergent operator on the SAME residue digraph")
print("shows a clean DOUBLE DISSOCIATION: its global spectrum sees the QR")
print("arithmetic (3 distinct eigenvalues = prime, vs ~n for a random")
print("tournament), its per-node symplectic substrate does not (identical")
print("dispersion for Paley vs random). The single structural reason is")
print("VERTEX-TRANSITIVITY: the residue graph's translation automorphism")
print("makes all nodes equivalent, confining the arithmetic to the")
print("spectral / group-representation sector Fix(G_aut)^perp and leaving")
print("the per-node substrate in the symmetric sector Fix(G_aut), blind.")
print("This is the SAME wall as the paused TNFR-Riemann program, where")
print("S(T)=(1/pi)arg zeta(1/2+iT) lives in ker(R_inf) ^ Fix(S_n)^perp,")
print("unreachable by symmetric (Fix-trapped) constructions. Physics, number")
print("theory, emergent geometry and the Riemann residual hit ONE symmetry")
print("wall, located precisely. It EXPLAINS the wall; it closes no problem.")
if __name__ == "__main__":
main()