SilverSight/scripts/run_8strand_search.py
allaun 3362d554d1 feat(braid/dag): land untracked research WIP + register 4 formal libs; ignore build artifacts
- lakefile.lean: register SilverSight.{AngrySphinx,CollatzBraid,GoldenSpiral,GCCL}
- docs/research/: braid group action, iteration DAG/regime, Sidon
  preservation/creation, unified CRT-torus DAG notes
- docs/diagrams/: DAG + heatmap + 8-strand search JSON/dot outputs
- formal/CoreFormalism/StrandCapacityBound.lean: capacity bound (passes
  hardened anti-smuggle --ci)
- scripts/, python/: braid word solver, collapse/DAG search + tuning,
  heatmap gen, YB search/verification, wrapping verifier
- .gitignore: exclude rust/**/target and coq compiled artifacts
  (*.vo/*.vok/*.vos/*.glob/*.aux) that were polluting the tree

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 15:11:37 -05:00

162 lines
6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
8-Strand Chiral Torus DAG — full search on provider-nixos.
Runs the dual-model DAG with:
- 8 strands × 2 moduli = 16 coprime moduli (prime-product method)
- Axis-swap braid generators (YB-verified)
- Adjustment crossings with capacity tracking
- Multi-seed Sidon search (4 different A₀ sets)
- BFS up to max_steps=12, max_branch=100
Output: per-seed JSON + summary JSON to docs/diagrams/
"""
import sys, math, json, time
sys.path.insert(0, '/home/allaun/SilverSight/scripts')
from full_chiral_dag import ChiralDAG, BraidDAGNode, chiral_pairs
SEEDS = [
{"id": "canonical", "A": [1, 2, 5, 6], "S": 7},
{"id": "sparse", "A": [0, 1, 3, 8, 13], "S": 27},
{"id": "five_element", "A": [1, 4, 9, 11, 16], "S": 20},
{"id": "seven_element", "A": [2, 3, 7, 10, 14, 18, 21], "S": 24},
]
def run_search(seed, n_strands=3, max_steps=8, max_branch=60, spacing=200):
"""Run a single DAG search with given parameters."""
dag = ChiralDAG(seed["A"], seed["S"], n_strands=n_strands,
max_steps=max_steps, max_branch=max_branch,
min_spacing=spacing)
# Use small initial pairs for the wrapping regime
init_pairs = chiral_pairs(n_strands)
dag.root = BraidDAGNode(init_pairs, seed["A"], seed["S"])
dag.all_nodes = {dag.root.key(): dag.root}
dag.n_strands = n_strands
start = time.time()
dag.build(use_axis_swap=True, use_adjustment=True, bypass_preservation=True)
elapsed = time.time() - start
result = {
"seed_id": seed["id"],
"A0": seed["A"],
"S": seed["S"],
"n_strands": n_strands,
"max_steps": max_steps,
"max_branch": max_branch,
"elapsed_s": round(elapsed, 2),
"stats": dag.stats,
"nodes_total": len(dag.all_nodes),
"sidon_paths": [],
"root_moduli": dag.root.moduli,
"root_capacity": dag.root.capacity_left,
"root_spacing": dag.root._spacing if hasattr(dag.root, '_spacing') else None,
}
for path in dag.sidon_paths:
result["sidon_paths"].append({
"braid_word": path[-1].braid_word,
"steps": len(path) - 1,
"final_A": path[-1].A,
"final_M": path[-1].M,
"final_capacity": path[-1].capacity_left,
"node_count": len(path),
})
if result["sidon_paths"]:
shortest = min(result["sidon_paths"], key=lambda p: p["steps"])
result["shortest_path"] = shortest["braid_word"]
result["shortest_steps"] = shortest["steps"]
else:
result["shortest_path"] = None
result["shortest_steps"] = None
return result, dag
def run_8strand_validation():
"""Validate that the 8-strand config is constructible and compute bounds."""
pairs = chiral_pairs(8)
mods = []
for p in pairs:
mods.extend(p)
from full_chiral_dag import pairwise_coprime, compute_spacing, remaining_capacity
return {
"n_moduli": len(mods),
"coprime": pairwise_coprime(mods),
"moduli": mods,
"pairs": pairs,
"min_spacing": compute_spacing(pairs)["min_spacing"],
"capacity": remaining_capacity(pairs),
"max_modulus": max(mods),
"max_modulus_ok": max(mods) < 32767,
}
if __name__ == "__main__":
print("=" * 60)
print("8-STRAND CHIRAL TORUS DAG - FULL SEARCH")
print("=" * 60)
print()
# 1. Validate 8-strand construction
print("--- 8-Strand Configuration Validation ---")
v8 = run_8strand_validation()
print(f" Moduli: {v8['n_moduli']} (8 strands × 2)")
print(f" Coprime: {v8['coprime']}")
print(f" Min spacing: {v8['min_spacing']}")
print(f" Capacity: {v8['capacity']}")
print(f" Max modulus: {v8['max_modulus']} < 32767: {v8['max_modulus_ok']}")
print()
# 2. Run searches at increasing strand counts
all_results = {"8strand_config": v8, "seeds": []}
configs = [
(3, 8, 80, "3-strand, 8 steps"),
(4, 8, 60, "4-strand, 8 steps"),
(6, 6, 40, "6-strand, 6 steps"),
(8, 5, 30, "8-strand, 5 steps"),
]
for n_strands, max_steps, max_branch, label in configs:
print(f"--- {label} ---")
for seed in SEEDS:
result, dag = run_search(seed, n_strands, max_steps, max_branch)
print(f" Seed '{seed['id']}': "
f"nodes={result['nodes_total']}, "
f"sidon={result['stats']['sidon_found']}, "
f"shortest={result['shortest_path'] or 'NONE'}, "
f"{result['elapsed_s']}s")
all_results["seeds"].append(result)
# Per-strand-count summary
seed_results = [r for r in all_results["seeds"] if r["n_strands"] == n_strands]
found = sum(1 for r in seed_results if r["sidon_paths"])
total_nodes = sum(r["nodes_total"] for r in seed_results)
total_time = sum(r["elapsed_s"] for r in seed_results)
print(f" [{label}] Total: {found}/{len(SEEDS)} seeds found Sidon, "
f"{total_nodes} nodes, {total_time:.1f}s")
print()
# 3. Overall summary
print("=" * 60)
print("SUMMARY")
print("=" * 60)
total_seeds = sum(1 for r in all_results["seeds"] if r["sidon_paths"])
total_found = len([r for r in all_results["seeds"] if r["sidon_paths"]])
print(f" Total runs: {len(all_results['seeds'])}")
print(f" Seeds with Sidon paths: {total_seeds}")
print(f" Shortest paths across all: ", end="")
shortest = min((r for r in all_results["seeds"] if r["sidon_paths"]),
key=lambda r: r["shortest_steps"], default=None)
if shortest:
print(f"{shortest['shortest_path']} ({shortest['shortest_steps']} steps, "
f"seed={shortest['seed_id']}, {shortest['n_strands']} strands)")
else:
print("NONE")
# 4. Write results
path = "/home/allaun/SilverSight/docs/diagrams/8strand_search_results.json"
with open(path, 'w') as f:
json.dump(all_results, f, indent=2)
print(f"\n Results written to {path}")