mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
Core components: - ChentsovFinite.lean (883 lines, 0 sorry): Fisher metric uniqueness on 8-state simplex - HachimojiCodec.lean: Deterministic E=mc^2 -> Hachimoji state pipeline - PVGS_DQ_Bridge (8 sections, ~6,150 lines): Photon-Varied Gaussian to Dual Quaternion - UniversalMathEncoding.lean: 50-token math address space (~10^15 addresses) - ChiralitySpace.lean: 4D descriptor (phase x chirality x direction x regime) ~2x10^25 - BindingSite (3 files): Amino acid vocabulary, entropy-based bindability - Python: chaos game, Sidon addressing, Q16.16 canonical, Finsler metric, QUBO/QAOA - CI: Lean check, Python check, Q16 roundtrip workflows Papers: Giani-Win-Conti 2025, Chabaud-Mehraban 2022, Pizzimenti 2024, Wassner 2025
305 lines
9.7 KiB
Python
305 lines
9.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
chaos_game.py — Deterministic Chaos Game Engine
|
||
|
||
Deterministic chaos game using IFS contraction on 8×8 state matrix.
|
||
4 basins: q_void (rows 0-1), q_orbit (rows 2-3), q_braid (rows 4-5), q_observer (rows 6-7).
|
||
"""
|
||
|
||
import hashlib
|
||
import json
|
||
import math
|
||
from typing import Dict, List, Optional
|
||
|
||
from sidon_address import (
|
||
SIDON_ADDRESSES,
|
||
_ADDRESS_TO_STRAND,
|
||
address_to_strand,
|
||
compute_full_address,
|
||
structural_hash,
|
||
verify_sidon_property,
|
||
)
|
||
from spectral_profile import compute_spectral_profile
|
||
|
||
EPSILON = 1e-14
|
||
N = 8
|
||
IFS_ALPHA = 0.75 # Strong contraction for fast convergence
|
||
|
||
BASIN_ROWS = {
|
||
"q_void": (0, 1),
|
||
"q_orbit": (2, 3),
|
||
"q_braid": (4, 5),
|
||
"q_observer": (6, 7),
|
||
}
|
||
|
||
LCG_A = 1664525
|
||
LCG_C = 1013904223
|
||
LCG_M = 2**32
|
||
|
||
DEFAULT_CONVERGENCE_THRESHOLD = 0.95
|
||
DEFAULT_MAX_STEPS = 10000
|
||
DEFAULT_CONVERGENCE_WINDOW = 10
|
||
|
||
|
||
class LCG:
|
||
def __init__(self, seed: int):
|
||
self.state = seed & 0xFFFFFFFF
|
||
def next(self) -> int:
|
||
self.state = (LCG_A * self.state + LCG_C) % LCG_M
|
||
return self.state
|
||
def next_float(self) -> float:
|
||
return self.next() / LCG_M
|
||
|
||
|
||
def init_state_matrix(seed: int) -> List[List[float]]:
|
||
"""Initialize 8×8 state matrix deterministically from seed."""
|
||
lcg = LCG(seed)
|
||
A = [[0.0] * N for _ in range(N)]
|
||
for i in range(N):
|
||
for j in range(N):
|
||
if i == j:
|
||
A[i][j] = SIDON_ADDRESSES[i] / 128.0 + 0.5
|
||
elif abs(i - j) == 1:
|
||
A[i][j] = -0.1 + 0.04 * (lcg.next_float() - 0.5)
|
||
else:
|
||
A[i][j] = 0.05 * (lcg.next_float() - 0.5)
|
||
return A
|
||
|
||
|
||
def mat_copy(A): return [row[:] for row in A]
|
||
def mat_diff_norm(A, B):
|
||
return math.sqrt(sum((A[i][j] - B[i][j])**2 for i in range(N) for j in range(N)))
|
||
def mat_norm(A):
|
||
return math.sqrt(sum(A[i][j]**2 for i in range(N) for j in range(N)))
|
||
|
||
|
||
def strand_to_basin(strand: int) -> str:
|
||
if strand < 2: return "q_void"
|
||
elif strand < 4: return "q_orbit"
|
||
elif strand < 6: return "q_braid"
|
||
else: return "q_observer"
|
||
|
||
|
||
def get_basin_rows(strand: int):
|
||
return BASIN_ROWS[strand_to_basin(strand)]
|
||
|
||
|
||
def ifs_contract(A, strand, step, eq_hash):
|
||
"""Apply IFS contraction toward a strand's quadrant.
|
||
|
||
Pure IFS contraction: A <- (1-alpha)*A + alpha*T where T is the
|
||
target matrix with strong energy in the target strand's basin and
|
||
suppressed energy elsewhere. No post-step modifications.
|
||
"""
|
||
alpha = IFS_ALPHA
|
||
r0, r1 = get_basin_rows(strand)
|
||
lcg = LCG((eq_hash + step * 104729 + strand * 7919) & 0xFFFFFFFF)
|
||
|
||
for i in range(N):
|
||
for j in range(N):
|
||
in_basin = (r0 <= i <= r1)
|
||
on_diag = (i == j)
|
||
is_strand = (i == strand)
|
||
|
||
if is_strand and on_diag:
|
||
target = 10.0 # maximum energy at strand diagonal
|
||
elif is_strand:
|
||
target = 3.0 + 0.5 * lcg.next_float()
|
||
elif in_basin and on_diag:
|
||
target = 4.0 + 0.5 * lcg.next_float()
|
||
elif in_basin:
|
||
target = 1.5 + 0.3 * lcg.next_float()
|
||
elif on_diag:
|
||
target = 0.02 + 0.01 * lcg.next_float()
|
||
else:
|
||
target = 0.005 * lcg.next_float()
|
||
|
||
A[i][j] = (1 - alpha) * A[i][j] + alpha * target
|
||
|
||
|
||
def quadrant_energy(A):
|
||
"""Compute Frobenius energy in each basin (2-row block)."""
|
||
energy = {}
|
||
for basin, (r0, r1) in BASIN_ROWS.items():
|
||
e = sum(A[i][j]**2 for i in range(r0, r1 + 1) for j in range(N))
|
||
energy[basin] = math.sqrt(e)
|
||
energy["total"] = sum(v for k, v in energy.items())
|
||
return energy
|
||
|
||
|
||
def energy_ratio(A):
|
||
"""Ratio of dominant basin energy to total energy."""
|
||
qe = quadrant_energy(A)
|
||
total = qe["total"]
|
||
if total < EPSILON:
|
||
return 0.0
|
||
basin_energies = {k: v for k, v in qe.items() if k != "total"}
|
||
return max(basin_energies.values()) / total
|
||
|
||
|
||
def dominant_basin(A):
|
||
qe = quadrant_energy(A)
|
||
del qe["total"]
|
||
return max(qe, key=qe.get)
|
||
|
||
|
||
def detect_quarantine(equation):
|
||
if not equation or not equation.strip():
|
||
return "empty_equation"
|
||
eq = equation.strip()
|
||
normalized = eq.replace(" ", "").replace("\t", "")
|
||
contradictions = {"0=1", "1=0", "false=true", "true=false",
|
||
"False=True", "True=False", "⊥=⊤", "⊤=⊥"}
|
||
if normalized in contradictions:
|
||
return "explicit_contradiction"
|
||
if eq in {"0 = 1", "1 = 0", "False = True", "True = False", "⊥ = ⊤", "⊤ = ⊥"}:
|
||
return "explicit_contradiction"
|
||
return None
|
||
|
||
|
||
def sidon_guided_chaos_game(
|
||
target_address: list,
|
||
max_steps: int = DEFAULT_MAX_STEPS,
|
||
convergence_threshold: float = DEFAULT_CONVERGENCE_THRESHOLD,
|
||
convergence_window: int = DEFAULT_CONVERGENCE_WINDOW,
|
||
equation: str = "",
|
||
):
|
||
"""Deterministic chaos game guided by Sidon address."""
|
||
# Quarantine check
|
||
quarantine = detect_quarantine(equation) if equation else None
|
||
if quarantine:
|
||
return {
|
||
"converged": False,
|
||
"basin": "QUARANTINE",
|
||
"steps": -1,
|
||
"energy_ratio": 0.0,
|
||
"address": target_address,
|
||
"hash": hex(structural_hash(equation))[2:18] if equation else "",
|
||
"target_strand": -1,
|
||
"quarantine": quarantine,
|
||
}
|
||
|
||
primary = target_address[0] if target_address else SIDON_ADDRESSES[0]
|
||
primary_strand = address_to_strand(primary)
|
||
eq_hash = structural_hash(equation) if equation else 42
|
||
A = init_state_matrix(eq_hash & 0xFFFFFFFF)
|
||
|
||
converged = False
|
||
basin_history = []
|
||
trajectory = []
|
||
|
||
for step in range(max_steps):
|
||
# Adaptive: emphasize target strand more over time
|
||
progress = min(step / max(max_steps // 3, 1), 1.0)
|
||
target_prob = 0.5 + 0.45 * progress
|
||
|
||
lcg = LCG((eq_hash + step * 104729) & 0xFFFFFFFF)
|
||
if lcg.next_float() < target_prob:
|
||
chosen = primary_strand
|
||
else:
|
||
others = [s for s in range(N) if s != primary_strand]
|
||
chosen = others[step % len(others)]
|
||
|
||
ifs_contract(A, chosen, step, eq_hash)
|
||
trajectory.append(chosen)
|
||
|
||
# Check convergence every 4 steps
|
||
if step % 4 == 0 and step > 0:
|
||
ratio = energy_ratio(A)
|
||
current_basin = dominant_basin(A)
|
||
basin_history.append(current_basin)
|
||
|
||
if ratio >= convergence_threshold:
|
||
if len(basin_history) >= convergence_window:
|
||
recent = basin_history[-convergence_window:]
|
||
if len(set(recent)) == 1:
|
||
converged = True
|
||
break
|
||
|
||
steps = step + 1 if converged else max_steps
|
||
final_ratio = energy_ratio(A)
|
||
final_basin = dominant_basin(A)
|
||
|
||
if not converged and final_ratio >= convergence_threshold:
|
||
converged = True
|
||
|
||
qe = quadrant_energy(A)
|
||
profile = energy_to_profile(qe)
|
||
from sidon_address import spectral_to_sidon_address
|
||
achieved = spectral_to_sidon_address(profile, eq_hash)
|
||
|
||
return {
|
||
"converged": converged,
|
||
"basin": final_basin,
|
||
"steps": steps,
|
||
"energy_ratio": round(final_ratio, 6),
|
||
"address": achieved,
|
||
"hash": hex(eq_hash)[2:18],
|
||
"target_strand": primary_strand,
|
||
"quarantine": None,
|
||
"trajectory": trajectory[:100],
|
||
}
|
||
|
||
|
||
def energy_to_profile(energy):
|
||
"""Convert quadrant energies to 8D profile."""
|
||
total = energy.get("total", 1.0)
|
||
if total < EPSILON:
|
||
total = 1.0
|
||
v = energy.get("q_void", 0.0) / total
|
||
o = energy.get("q_orbit", 0.0) / total
|
||
b = energy.get("q_braid", 0.0) / total
|
||
ob = energy.get("q_observer", 0.0) / total
|
||
profile = [v, v*v, o, o*o, b, b*b, ob, ob*ob]
|
||
s = sum(profile)
|
||
if s > 0:
|
||
profile = [p / s for p in profile]
|
||
else:
|
||
profile = [0.125] * 8
|
||
return profile
|
||
|
||
|
||
def generate_receipt(results, schema_version="stage3_v1"):
|
||
import datetime
|
||
converged = sum(1 for r in results if r.get("converged"))
|
||
quarantined = sum(1 for r in results if r.get("quarantine"))
|
||
basin_counts = {"q_void": 0, "q_orbit": 0, "q_braid": 0, "q_observer": 0}
|
||
for r in results:
|
||
b = r.get("basin", "")
|
||
if b in basin_counts:
|
||
basin_counts[b] += 1
|
||
receipt = {
|
||
"schema": f"rrc_chaos_game_search_{schema_version}",
|
||
"sidon_property_verified": verify_sidon_property(),
|
||
"total_searches": len(results),
|
||
"converged": converged,
|
||
"quarantined": quarantined,
|
||
"failed": len(results) - converged - quarantined,
|
||
"basin_distribution": basin_counts,
|
||
"convergence_rate": round(converged / len(results), 4) if results else 0.0,
|
||
"parameters": {
|
||
"matrix_size": N,
|
||
"ifs_alpha": IFS_ALPHA,
|
||
"convergence_threshold": DEFAULT_CONVERGENCE_THRESHOLD,
|
||
"max_steps": DEFAULT_MAX_STEPS,
|
||
"convergence_window": DEFAULT_CONVERGENCE_WINDOW,
|
||
},
|
||
"results": results,
|
||
"computed_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
||
}
|
||
canonical = json.dumps(receipt, sort_keys=True, separators=(",", ":"))
|
||
receipt["receipt_sha256"] = hashlib.sha256(canonical.encode()).hexdigest()
|
||
return receipt
|
||
|
||
|
||
def search_equation(equation: str, **kwargs):
|
||
"""Full pipeline: equation → profile → address → chaos game → result."""
|
||
profile = compute_spectral_profile(equation)
|
||
address = compute_full_address(equation)
|
||
result = sidon_guided_chaos_game(
|
||
target_address=address,
|
||
equation=equation,
|
||
**kwargs,
|
||
)
|
||
result["spectral_profile"] = [round(x, 6) for x in profile]
|
||
return result
|