FSO-Genesis-Space / analysis.py
LOOFYYLO's picture
Upload folder using huggingface_hub
2c54126 verified
"""
analysis.py — Automated mathematical analysis of Claude's Cycles solutions.
Given a sigma function or SigmaTable, this module:
1. STRUCTURAL ANALYSIS
- Detects column-uniformity (does sigma depend only on s,j or all of i,j,k?)
- Computes the Q_c composed permutations
- Identifies the twisted translation form Q_c(i,j) = (i+b_c(j), j+r_c)
2. THEOREM VERIFICATION
- Theorem 1: Twisted Translation Structure (auto-detected)
- Theorem 2: Single-Cycle Conditions (gcd checks)
- Theorem 3: Existence for odd m (constructive verification)
- Theorem 4: Impossibility for even m (parity argument)
3. PATTERN REPORTING
- Full solution tables
- Arc sequences for each Hamiltonian cycle
- Comparison across m values
"""
from __future__ import annotations
from typing import Optional, List, Dict, Tuple
from math import gcd
from .core import (
Vertex, Perm, SigmaFn,
build_functional_graphs, verify_sigma, VerifyResult,
trace_cycle, arc_sequence, vertices
)
from .fiber import (
SigmaTable, compose_levels, analyze_Q_structure,
even_m_impossibility_check, verify_single_cycle_conditions,
table_to_sigma_fn, FIBER_SHIFTS
)
# =========================================================================== #
# Structural analysis of sigma
# =========================================================================== #
def detect_dependencies(sigma: SigmaFn, m: int) -> Dict[str, bool]:
"""
Determine which coordinates sigma actually depends on.
Returns {'i': bool, 'j': bool, 'k': bool, 's': bool}
where s = (i+j+k) mod m.
"""
depends_i = depends_j = depends_k = False
for i in range(m):
for j in range(m):
for k in range(m):
base = sigma(i, j, k)
if i > 0 and sigma(i, j, k) != sigma(0, j, k):
depends_i = True
if j > 0 and sigma(i, j, k) != sigma(i, 0, k):
depends_j = True
if k > 0 and sigma(i, j, k) != sigma(i, j, 0):
depends_k = True
# Check if sigma depends only on s=(i+j+k)%m and j
depends_s_only = True
for i in range(m):
for j in range(m):
for k in range(m):
s = (i + j + k) % m
# Find another vertex with same s and j but different i
other_i = (i + 1) % m
other_k = (s - other_i - j) % m
if sigma(i, j, k) != sigma(other_i, j, other_k):
depends_s_only = False
break
if not depends_s_only:
break
if not depends_s_only:
break
return {
"i": depends_i,
"j": depends_j,
"k": depends_k,
"column_uniform": depends_s_only, # sigma(i,j,k) = f(s,j)
}
def extract_sigma_table(sigma: SigmaFn, m: int) -> Optional[SigmaTable]:
"""
If sigma is column-uniform (depends only on s,j), extract SigmaTable.
Returns None if sigma is not column-uniform.
"""
deps = detect_dependencies(sigma, m)
if not deps["column_uniform"]:
return None
table = []
for s in range(m):
level = {}
for j in range(m):
# Find a representative vertex in fiber s with column j
i_rep = 0
k_rep = (s - i_rep - j) % m
level[j] = list(sigma(i_rep, j, k_rep))
table.append(level)
return table
# =========================================================================== #
# Full solution analysis
# =========================================================================== #
class SolutionAnalysis:
"""
Comprehensive analysis of a Claude's Cycles solution.
Usage:
analysis = SolutionAnalysis(sigma_fn, m=5)
analysis.run()
print(analysis.report())
"""
def __init__(self, sigma: SigmaFn, m: int):
self.sigma = sigma
self.m = m
self._run = False
def run(self) -> "SolutionAnalysis":
m = self.m
sigma = self.sigma
# 1. Core verification
self.verify_result: VerifyResult = verify_sigma(sigma, m)
# 2. Build functional graphs and traces
self.funcs = build_functional_graphs(sigma, m)
self.cycle_paths = [trace_cycle(fg, m) for fg in self.funcs]
self.arc_seqs = [arc_sequence(p, m) for p in self.cycle_paths]
# 3. Structural dependencies
self.deps = detect_dependencies(sigma, m)
# 4. If column-uniform, extract Q and analyze
self.sigma_table: Optional[SigmaTable] = extract_sigma_table(sigma, m)
if self.sigma_table is not None:
Qs = compose_levels(self.sigma_table, m)
self.Q_analysis: Optional[dict] = analyze_Q_structure(Qs, m)
else:
self.Q_analysis = None
# 5. Theoretical checks
self.impossibility = even_m_impossibility_check(m)
self._run = True
return self
def report(self, verbose: bool = True) -> str:
if not self._run:
self.run()
m = self.m
lines = [
"=" * 64,
f"CLAUDE'S CYCLES SOLUTION ANALYSIS — m={m}",
"=" * 64,
"",
f"Verification: {self.verify_result}",
"",
]
# Dependency structure
d = self.deps
dep_str = "sigma depends on: " + ", ".join(
x for x, v in [("i",d["i"]),("j",d["j"]),("k",d["k"])] if v
)
if d["column_uniform"]:
dep_str += " → COLUMN-UNIFORM (only s=(i+j+k)%m and j)"
lines.append(dep_str)
lines.append("")
# Sigma table
if self.sigma_table is not None and verbose:
lines.append("Sigma table [s][j] → [arc₀→cycle, arc₁→cycle, arc₂→cycle]:")
for s in range(m):
row = [self.sigma_table[s][j] for j in range(m)]
lines.append(f" s={s}: {row}")
lines.append("")
# Arc sequences
lines.append("Hamiltonian cycle arc sequences (I=incr_i, J=incr_j, K=incr_k):")
for c in range(3):
seq = self.arc_seqs[c]
counts = {x: seq.count(x) for x in "IJK"}
lines.append(f" Cycle {c}: {seq[:40]}{'...' if len(seq)>40 else ''}"
f" [I:{counts['I']} J:{counts['J']} K:{counts['K']}]")
lines.append("")
# Q structure
if self.Q_analysis is not None:
qa = self.Q_analysis
lines.append("Composed fiber permutation Q_c:")
twisted_str = "✅ YES" if qa["all_twisted"] else "❌ NO"
lines.append(f" Twisted translation form Q_c(i,j)=(i+b_c(j),j+r_c): {twisted_str}")
if qa["all_twisted"]:
lines.append(f" r-values: {qa['r_values']} sum={qa['sum_r']} (= m? {qa['sum_r']==m})")
for info in qa["cycles"]:
c = info["cycle"]
if info["is_twisted"]:
sc = verify_single_cycle_conditions(info["r_c"], info["b_c"], m)
lines.append(
f" Q_{c}: r={info['r_c']} b={info['b_c']}"
f" Σb={info['sum_b']}"
f" cond_a(gcd(r,m)=1)={'✅' if sc['condition_a'] else '❌'}"
f" cond_b(gcd(Σb,m)=1)={'✅' if sc['condition_b'] else '❌'}"
f" single_cycle={'✅' if info['is_single_cycle'] else '❌'}"
)
else:
lines.append(f" Q_{c}: NOT in twisted form")
lines.append("")
# Theoretical context
imp = self.impossibility
lines.append(f"Theoretical context (m={m}):")
if imp["m_is_even"]:
lines.append(f" m={m} is EVEN → column-uniform fiber construction IMPOSSIBLE")
lines.append(f" (Proof: {imp['proof']})")
else:
lines.append(f" m={m} is ODD → column-uniform fiber construction POSSIBLE")
ex = imp.get("example")
if ex:
lines.append(f" Example valid (r₀,r₁,r₂) = {ex}")
lines.append("=" * 64)
return "\n".join(lines)
def __repr__(self) -> str:
status = "✅" if (self._run and self.verify_result.is_valid) else "?"
return f"SolutionAnalysis(m={self.m}, valid={status})"
# =========================================================================== #
# Cross-m comparison
# =========================================================================== #
def compare_across_m(results: Dict[int, "SolutionAnalysis"]) -> str:
"""
Generate a comparison table across multiple m values.
results: {m: SolutionAnalysis}
"""
lines = [
"=" * 72,
"COMPARISON ACROSS m VALUES",
"=" * 72,
f"{'m':>4} {'parity':>6} {'valid':>7} {'col_unif':>9} "
f"{'twisted':>8} {'r_vals':>20}",
"-" * 72,
]
for m in sorted(results):
a = results[m]
if not a._run:
a.run()
parity = "ODD" if m % 2 == 1 else "EVEN"
valid = "✅" if a.verify_result.is_valid else "❌"
col = "✅" if a.deps["column_uniform"] else "❌"
if a.Q_analysis:
twisted = "✅" if a.Q_analysis["all_twisted"] else "❌"
r = str(a.Q_analysis.get("r_values", "—"))
else:
twisted = "—"
r = "—"
lines.append(f"{m:>4} {parity:>6} {valid:>7} {col:>9} {twisted:>8} {r:>20}")
lines.append("=" * 72)
return "\n".join(lines)