#!/usr/bin/env python3 """ Deep Braid Exploration: YB modulo space, braid invariants, stabilization. """ import sys, math, itertools, random from typing import List, Tuple sys.path.insert(0, '/home/allaun/SilverSight/scripts') from multi_strand_braid import pairwise_coprime, moduli_from_pairs, F_multi, braid_word, cross from verify_wrapping import is_sidon # ============================================================ # 1. YB MODULO SPACE SEARCH # ============================================================ def search_yb_space(max_mod: int = 100) -> List[dict]: """Find ALL 4-tuples where the full YB relation holds with equal FA.""" results = [] # Precompute coprime pairs coprime_pairs_list = [] for a in range(2, max_mod+1): for b in range(a+1, max_mod+1): if math.gcd(a, b) == 1: coprime_pairs_list.append((a, b)) total = len(coprime_pairs_list) for idx1, (a, b) in enumerate(coprime_pairs_list): if idx1 % 100 == 0: sys.stdout.write(f"\r Searching YB space: {idx1}/{total} pairs...") sys.stdout.flush() for idx2 in range(idx1+1, total): c, d = coprime_pairs_list[idx2] if not pairwise_coprime([a, b, c, d]): continue # Path 1: σ₁⁺ → σ₂⁻ → σ₁⁺ s1 = cross([(a,b),(c,d)], 0, True) if not s1: continue s1s2 = cross(s1, 1, False) if not s1s2: continue s1s2s1 = cross(s1s2, 0, True) if not s1s2s1: continue # Path 2: σ₂⁻ → σ₁⁺ → σ₂⁻ s2 = cross([(a,b),(c,d)], 1, False) if not s2: continue s2s1 = cross(s2, 0, True) if not s2s1: continue s2s1s2 = cross(s2s1, 1, False) if not s2s1s2: continue # Check equal FA A0, S = [1, 2, 5, 6], 7 f1 = [F_multi(x, S, moduli_from_pairs(s1s2s1)) for x in A0] f2 = [F_multi(x, S, moduli_from_pairs(s2s1s2)) for x in A0] if f1 == f2: results.append({ 'init': [(a,b),(c,d)], 'final': s1s2s1, 'path1_word': 'σ₁⁺·σ₂⁻·σ₁⁺', 'path2_word': 'σ₂⁻·σ₁⁺·σ₂⁻', 'FA': f1, 'M': a*b*c*d }) print() return results def test_yb_search(): print("=" * 60) print("YB MODULO SPACE SEARCH") print("=" * 60) results = search_yb_space(max_mod=200) print(f"\nTotal YB-valid 4-tuples found: {len(results)}") if results: print(f"\nSmallest by M:") for r in sorted(results, key=lambda x: x['M'])[:5]: print(f" {r['init']} M={r['M']:6d} FA={r['FA']}") print(f"\nLargest by M:") for r in sorted(results, key=lambda x: -x['M'])[:3]: print(f" {r['init']} M={r['M']:8d} FA={r['FA']}") # ============================================================ # 2. BRAID INVARIANTS FROM M-DIFFERENCES # ============================================================ def m_difference_spectrum(A, moduli): """Compute the M-difference spectrum of a braid configuration.""" M = 1 for m in moduli: M *= m maxA = max(A) if M <= maxA: return {'regime': 'aliasing', 'M': M, 'sums': []} # Compute all pairwise sums sums = set() for i in range(len(A)): for j in range(i, len(A)): sums.add(A[i] + A[j]) sum_list = sorted(sums) # Find M-differences diffs = [] for i in range(len(sum_list)): for j in range(i+1, len(sum_list)): d = sum_list[j] - sum_list[i] if d > 0 and d % M == 0: diffs.append((sum_list[i], sum_list[j], d // M)) return {'regime': 'injective' if M > maxA else 'aliasing', 'M': M, 'sums': sum_list, 'diffs': diffs} def braid_invariant_from_mdiff(A, S, pairs_seq): """Compute braid invariant: the M-difference spectrum through a braid path.""" invariants = [] for pairs in pairs_seq: mods = moduli_from_pairs(pairs) spec = m_difference_spectrum(A, mods) invariants.append({ 'pairs': pairs, 'M': spec['M'], 'regime': spec['regime'], 'num_diffs': len(spec.get('diffs', [])), 'diffs': spec.get('diffs', []) }) return invariants def test_invariants(): print("\n" + "=" * 60) print("BRAID INVARIANTS FROM M-DIFFERENCES") print("=" * 60) A0, S = [1, 2, 5, 6], 7 # Trace a braid path and compute invariants configs = [[(3,4)], [(7,3)], [(11,2)]] for config in configs: mods = moduli_from_pairs(config) FA = [F_multi(a, S, mods) for a in A0] M = 1 for m in mods: M *= m spec = m_difference_spectrum(A0, mods) sidon = is_sidon(FA) pairs_str = str(config[0]) print(f" {pairs_str:12s} M={M:3d} Sidon={sidon} sums={len(spec.get('sums',[]))} diffs={len(spec.get('diffs',[]))}") # ============================================================ # 3. MODULUS REGENERATION AS BRAID STABILIZATION # ============================================================ def markov_stabilization(pairs, strand=0): """A Markov stabilization move: add a trivial crossing to extend word length. Stabilization: add (L_new_id, L_new_ref) as a new strand, with values coprime to all existing moduli. """ existing = moduli_from_pairs(pairs) existing_vals = set(existing) # Find a coprime pair not in existing values L_new_id = 2 while L_new_id in existing_vals: L_new_id += 1 L_new_ref = L_new_id + 1 while L_new_ref in existing_vals or math.gcd(L_new_id, L_new_ref) != 1: L_new_ref += 1 new_pair = (L_new_id, L_new_ref) all_mods = existing + [L_new_id, L_new_ref] if pairwise_coprime(all_mods): return pairs + [new_pair], f"stabilized with {new_pair}" return pairs, "stabilization failed" def test_stabilization(): print("\n" + "=" * 60) print("MODULUS REGENERATION AS BRAID STABILIZATION") print("=" * 60) # Start with a 1-strand system, cross until coprimality fails pairs = [(3, 4)] history = [pairs] for step in range(10): # Try over-crossing c = cross(pairs, 0, True) if c is None: # Stabilize: add a new strand with coprime moduli pairs, msg = markov_stabilization(pairs) print(f" Step {step}: coprimality failed → {msg}") if pairs == history[-1]: print(f" Cannot stabilize further. Stopping.") break else: pairs = c history.append(pairs) if len(history) <= 6: print(f" Step {step}: pairs={pairs}") print(f"\n Total steps before stabilization needed: {len(history)-1}") print(f" Final config: {pairs}") # ============================================================ # MAIN # ============================================================ if __name__ == "__main__": test_yb_search() test_invariants() test_stabilization()