Research-Stack/e2e/finsler_to_qubo.py
Allaun Silverfox 412c20df3f e2e: close E=mc2 trace — chaos game → Finsler → QUBO → QAOA
FinslerQUBO.lean: Fisher metric α + drift β → Randers → QUBO
finsler_to_qubo.py: eq_to_finsler_qubo('E = mc^2') → QUBO matrix
qaoa_circuit.py: 8-qubit p=2 circuit, depth 14, converges to state A
E2EMasterTrace.lean: 8-step master trace, 15 theorems (7 proven)
run_e2e_trace.py: python3 run_e2e_trace.py 'E = mc^2' → full pipeline

Result: HachimojiState.Φ (Phi) — trivial regime, above φ_GCP
Receipt: c8ad995a0fdd9bd0160ae5e20ca27b89a5ca759ef0465b7d0472d0901b3efcfa
2026-06-20 23:43:57 -05:00

587 lines
23 KiB
Python
Executable file
Raw 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
"""
finsler_to_qubo.py — Finsler Geometry → QUBO Bridge for E=mc²
Builds the mathematical bridge between Randers Finsler metrics and QUBO
formulations for the equation E = mc².
Mathematical construction:
1. Parse E=mc² → EquationShape (n_vars=3, n_ops=2, max_depth=1)
2. Fisher information metric g_ij on the constraint surface E=mc²
3. Drift 1-form β encoding the mass→energy conversion direction
4. Randers metric F = α + β = √(g_ij v^i v^j) + β_i v^i
5. QUBO discretization: Q_ij = F(state_i, state_j)² over Hachimoji states
Research-Stack integration:
- TransportTheory.lean: RandersMetric, AlphaComponent, BetaComponent
- EntropyMeasures.lean: QUBOFormulation
- HachimojiSubstitution.lean: 8-state Greek encoding
- qaoa_adapter.py: QUBO → Ising → Pauli → circuit
- BinnedFormalizations.lean: EquationShape indexing
"""
from __future__ import annotations
import math
import json
from dataclasses import dataclass, field
from typing import Optional, Callable
import numpy as np
# ═══════════════════════════════════════════════════════════════════════════
# I. Equation Shape (from BinnedFormalizations.lean)
# ═══════════════════════════════════════════════════════════════════════════
@dataclass
class EquationShape:
"""Structural descriptor for an equation fragment."""
n_vars: int
n_ops: int
max_depth: int
n_quantifiers: int
n_relations: int
def to_dict(self):
return {
"n_vars": self.n_vars,
"n_ops": self.n_ops,
"max_depth": self.max_depth,
"n_quantifiers": self.n_quantifiers,
"n_relations": self.n_relations,
}
def parse_equation_shape(eq_str: str) -> EquationShape:
"""Parse an equation string into its structural shape.
Matches Lean: EquationParser.parse / EquationParser.shapeOf
"""
# Count variables: alphabetic tokens excluding keywords
vars_found = set()
ops_found = set()
quantifiers = 0
relations = 0
max_depth = 0
curr_depth = 0
keywords = {"where", "and", "the", "for", "are", "with", "that", "then",
"from", "into", "set", "let", "be", "as", "is", "of", "to",
"in", "if", "so", "we", "have", "hence", "when", "can", "not",
"its", "by", "on", "at", "or", "an", "it", "all", "see",
"over", "via", "due", "this"}
# Tokenize
i = 0
chars = list(eq_str)
while i < len(chars):
c = chars[i]
# Track nesting depth
if c in "([{":
curr_depth += 1
max_depth = max(max_depth, curr_depth)
elif c in ")]}" :
curr_depth -= 1
# Count operators
if c in "+-*/^√∂∇∫∑∏⊗⊕∩∪×·⟨⟩∞":
ops_found.add(c)
# Count relations
if c in "=<>≠≤≥∈⊂⊆→↔⇒":
relations += 1
# Count quantifiers
if c in "∀∃":
quantifiers += 1
# Extract variable names (both upper and lower case)
# Single letters are variables; multi-letter sequences are only variables
# if they are known math symbols
if c.isalpha():
# In math notation like "mc²", each single letter is a variable
# Add the single character as a variable
vars_found.add(c)
# Also try to extract longer names (but stop at superscripts)
j = i + 1
while j < len(chars) and (chars[j].isalpha() or
(chars[j].isdigit() and chars[j] not in "²³⁴⁵⁶⁷⁸⁹⁰") or
chars[j] == "_"):
j += 1
if j > i + 1:
long_name = "".join(chars[i:j])
if long_name not in keywords:
# Add individual characters (mc² → m, c)
for ch in long_name:
if ch.isalpha() and len(ch) == 1:
vars_found.add(ch)
i = j - 1
# Detect superscript exponentiation (², ³, etc.)
if c in "²³⁴⁵⁶⁷⁸⁹⁰":
ops_found.add("^")
max_depth = max(max_depth, 1)
i += 1
return EquationShape(
n_vars=len(vars_found),
n_ops=len(ops_found),
max_depth=max_depth,
n_quantifiers=quantifiers,
n_relations=relations,
)
# ═══════════════════════════════════════════════════════════════════════════
# II. Fisher Information Metric (α component)
# ═══════════════════════════════════════════════════════════════════════════
@dataclass
class FisherMetric:
"""Fisher information metric g_ij on the constraint surface.
For E = mc², parameterize by (m, c) with E = mc².
The metric is induced from the ambient 3D space:
ds² = dE² + dm² + dc² = (c²dm + 2mc·dc)² + dm² + dc²
This gives:
g_mm = c⁴ + 1
g_mc = 2·m·c³
g_cc = 4·m²·c² + 1
"""
g_mm: float # ∂²/∂m² — mass-mass component
g_mc: float # ∂²/∂m∂c — mass-speed coupling
g_cc: float # ∂²/∂c² — speed-speed component
def as_matrix(self) -> np.ndarray:
return np.array([[self.g_mm, self.g_mc],
[self.g_mc, self.g_cc]])
def alpha_cost(self, vm: float, vc: float) -> float:
"""Compute α(p,v) = √(g_ij v^i v^j) — Riemannian base cost."""
quad_form = self.g_mm * vm**2 + 2 * self.g_mc * vm * vc + self.g_cc * vc**2
return math.sqrt(max(quad_form, 0.0))
def fisher_metric_for_emc2(m: float, c: float) -> FisherMetric:
"""Compute the Fisher information metric for E=mc² at point (m, c).
The constraint surface E = mc² is a 2D manifold in 3D (E,m,c) space.
Using (m, c) as local coordinates with E = mc²:
dE = c²·dm + 2mc·dc
ds² = dE² + dm² + dc²
= (c⁴+1)·dm² + 4mc³·dm·dc + (4m²c²+1)·dc²
Args:
m: mass value
c: speed of light value (or variable c in the equation)
Returns:
FisherMetric with components (g_mm, g_mc, g_cc)
"""
c2 = c * c
c4 = c2 * c2
m2 = m * m
g_mm = c4 + 1.0
g_mc = 2.0 * m * c * c2 # 2·m·c³
g_cc = 4.0 * m2 * c2 + 1.0
return FisherMetric(g_mm=g_mm, g_mc=g_mc, g_cc=g_cc)
# ═══════════════════════════════════════════════════════════════════════════
# III. Drift 1-Form (β component)
# ═══════════════════════════════════════════════════════════════════════════
@dataclass
class DriftOneForm:
"""Drift 1-form β_i encoding asymmetric transport cost.
For E = mc², the drift encodes the mass→energy conversion direction:
β = (β_m, β_c) = (c², 0)
This means moving in the +m direction (increasing mass) has a drift
cost proportional to c², reflecting that E = mc² converts mass to energy.
The β_c = 0 component reflects that c is a constant of nature in this
equation (not a direction of conversion).
"""
beta_m: float # Drift coefficient in the mass direction
beta_c: float # Drift coefficient in the speed direction
def beta_cost(self, vm: float, vc: float) -> float:
"""Compute β(v) = β_i v^i — signed drift cost."""
return self.beta_m * vm + self.beta_c * vc
def drift_one_form_for_emc2(c: float) -> DriftOneForm:
"""Compute the drift 1-form for E=mc².
The drift captures the "mass → energy" conversion asymmetry:
- β_m = c²: increasing mass increases energy (via E=mc²)
- β_c = 0: c is treated as a constant in this equation
Args:
c: speed of light value
Returns:
DriftOneForm with (β_m, β_c)
"""
return DriftOneForm(beta_m=c * c, beta_c=0.0)
# ═══════════════════════════════════════════════════════════════════════════
# IV. Randers Metric F = α + β
# ═══════════════════════════════════════════════════════════════════════════
@dataclass
class RandersMetric:
"""Randers metric F(p,v) = α(p,v) + β(p,v).
Combines the symmetric Fisher base cost α with the asymmetric
drift 1-form β. This is the core geometric structure from
TransportTheory.lean.
Strong convexity requires |β(v)| < α(v) for all v ≠ 0.
"""
fisher: FisherMetric
drift: DriftOneForm
def compute(self, vm: float, vc: float) -> float:
"""Compute F(v) = α(v) + β(v) — full Randers cost."""
alpha = self.fisher.alpha_cost(vm, vc)
beta = self.drift.beta_cost(vm, vc)
return alpha + beta
def check_strong_convexity(self, vm: float, vc: float) -> bool:
"""Check Randers strong convexity: |β(v)| < α(v)."""
alpha = self.fisher.alpha_cost(vm, vc)
beta = abs(self.drift.beta_cost(vm, vc))
return beta < alpha
def randers_metric_for_emc2(m: float, c: float) -> RandersMetric:
"""Construct the full Randers metric for E=mc² at (m, c)."""
return RandersMetric(
fisher=fisher_metric_for_emc2(m, c),
drift=drift_one_form_for_emc2(c),
)
# ═══════════════════════════════════════════════════════════════════════════
# V. Hachimoji 8-State Encoding
# ═══════════════════════════════════════════════════════════════════════════
# Greek Hachimoji states with their semantic meanings
# (from HachimojiSubstitution.lean §5)
HACHIMOJI_STATES = {
"Φ": {"phase": 0, "chirality": "ambidextrous", "direction": "forward", "regime": "beautifulTopologicalFolding"},
"Λ": {"phase": 45, "chirality": "left", "direction": "forward", "regime": "beautifulTopologicalFolding"},
"Ρ": {"phase": 90, "chirality": "ambidextrous", "direction": "forward", "regime": "uglyAsymmetricPruning"},
"Κ": {"phase": 135, "chirality": "left", "direction": "forward", "regime": "uglyAsymmetricPruning"},
"Ω": {"phase": 180, "chirality": "ambidextrous", "direction": "reverse", "regime": "horribleManifoldTearing"},
"Σ": {"phase": 225, "chirality": "right", "direction": "reverse", "regime": "horribleManifoldTearing"},
"Π": {"phase": 270, "chirality": "right", "direction": "reverse", "regime": "horribleManifoldTearing"},
"Ζ": {"phase": 315, "chirality": "right", "direction": "reverse", "regime": "horribleManifoldTearing"},
}
HACHIMOJI_SYMBOLS = ["Φ", "Λ", "Ρ", "Κ", "Ω", "Σ", "Π", "Ζ"]
# ═══════════════════════════════════════════════════════════════════════════
# VI. QUBO Discretization
# ═══════════════════════════════════════════════════════════════════════════
@dataclass
class QUBOMatrix:
"""QUBO problem: minimize x^T Q x where x_i ∈ {0, 1}."""
n: int
Q: dict[tuple[int, int], float] = field(default_factory=dict)
offset: float = 0.0
def to_numpy(self) -> np.ndarray:
"""Convert to dense numpy matrix."""
mat = np.zeros((self.n, self.n))
for (i, j), val in self.Q.items():
mat[i, j] = val
if i != j:
mat[j, i] = val
return mat
def energy(self, x: list[int]) -> float:
"""Compute QUBO energy for binary assignment x."""
e = self.offset
for (i, j), qij in self.Q.items():
e += qij * x[i] * x[j]
return e
def state_direction_vector(state_from: str, state_to: str) -> tuple[float, float]:
"""Compute a direction vector between two Hachimoji states.
The direction is encoded via phase difference:
- vm = cos(phase_to) - cos(phase_from) — mass-direction component
- vc = sin(phase_to) - sin(phase_from) — speed-direction component
The phases map to semantic positions on the equation manifold:
- Forward states (Φ, Λ, Ρ, Κ): normal regime, increasing energy
- Reverse states (Ω, Σ, Π, Ζ): quarantine regime, decreasing energy
"""
phase_from = HACHIMOJI_STATES[state_from]["phase"]
phase_to = HACHIMOJI_STATES[state_to]["phase"]
# Convert to radians
rad_from = math.radians(phase_from)
rad_to = math.radians(phase_to)
vm = math.cos(rad_to) - math.cos(rad_from)
vc = math.sin(rad_to) - math.sin(rad_from)
return vm, vc
def finsler_distance_squared(
state_i: str,
state_j: str,
randers: RandersMetric,
) -> float:
"""Compute Q_ij = F(state_i, state_j)² — squared Finsler distance.
This encodes the cost of transitioning between two Hachimoji states
on the equation manifold. The squared distance is used for the QUBO
quadratic form.
Args:
state_i: Source Hachimoji state symbol
state_j: Target Hachimoji state symbol
randers: Randers metric at the current point
Returns:
Squared Finsler distance F(v)²
"""
vm, vc = state_direction_vector(state_i, state_j)
finsler_cost = randers.compute(vm, vc)
return finsler_cost ** 2
def build_finsler_qubo(
m: float = 1.0,
c: float = 299792458.0, # Speed of light in m/s
use_reduced_encoding: bool = True,
penalty_weight: float = 1000.0,
) -> QUBOMatrix:
"""Build QUBO matrix encoding the Finsler distance between Hachimoji states.
For E=mc², the QUBO encodes the Randers metric discretized over the
8 Hachimoji states. Each binary variable x_i = 1 means the equation's
center-of-mass is in Hachimoji state i.
Args:
m: mass value (default 1 kg)
c: speed of light (default physical value)
use_reduced_encoding: If True, use 8 variables (one per state).
If False, use 24 variables (3 vars × 8 states).
penalty_weight: Weight for one-hot penalty (exactly one state active).
Returns:
QUBOMatrix with Finsler-squared distances
"""
randers = randers_metric_for_emc2(m, c)
if use_reduced_encoding:
n = 8 # One variable per Hachimoji state
Q = {}
for i in range(8):
state_i = HACHIMOJI_SYMBOLS[i]
for j in range(i, 8):
state_j = HACHIMOJI_SYMBOLS[j]
if i == j:
# Diagonal: self-cost = F(state, state)² = 0
# But we add a bias based on the state's semantic meaning
# Forward states (low phase) get negative bias (preferred)
phase = HACHIMOJI_STATES[state_i]["phase"]
# Lower phase = more stable = lower cost
Q[(i, i)] = -0.1 * (180.0 - phase) / 180.0
else:
# Off-diagonal: Finsler distance squared between states
dist_sq = finsler_distance_squared(state_i, state_j, randers)
# Normalize to avoid numerical issues with large c
Q[(i, j)] = dist_sq / (c**4)
# One-hot penalty: exactly one state should be active
for i in range(8):
Q[(i, i)] = Q.get((i, i), 0.0) + penalty_weight
for j in range(i + 1, 8):
Q[(i, j)] = Q.get((i, j), 0.0) - 2.0 * penalty_weight
return QUBOMatrix(n=n, Q=Q)
else:
# Full 24-variable encoding: 3 variables (E, m, c) × 8 states each
n = 24
Q = {}
# For each variable position (0=E, 1=m, 2=c)
for var_idx in range(3):
base = var_idx * 8
for i in range(8):
for j in range(i, 8):
state_i = HACHIMOJI_SYMBOLS[i]
state_j = HACHIMOJI_SYMBOLS[j]
if i == j:
phase = HACHIMOJI_STATES[state_i]["phase"]
Q[(base + i, base + i)] = -0.1 * (180.0 - phase) / 180.0
else:
dist_sq = finsler_distance_squared(state_i, state_j, randers)
Q[(base + i, base + j)] = dist_sq / (c**4)
# One-hot per variable position
for var_idx in range(3):
base = var_idx * 8
for i in range(8):
Q[(base + i, base + i)] = Q.get((base + i, base + i), 0.0) + penalty_weight
for j in range(i + 1, 8):
Q[(base + i, base + j)] = Q.get((base + i, base + j), 0.0) - 2.0 * penalty_weight
# Cross-variable coupling: states should be consistent
# (all three variables should tend toward similar states)
consistency_weight = 0.5
for i in range(8):
for var_a in range(3):
for var_b in range(var_a + 1, 3):
idx_a = var_a * 8 + i
idx_b = var_b * 8 + i
Q[(idx_a, idx_b)] = Q.get((idx_a, idx_b), 0.0) - consistency_weight
return QUBOMatrix(n=n, Q=Q)
# ═══════════════════════════════════════════════════════════════════════════
# VII. Main Entry Point: eq_to_finsler_qubo
# ═══════════════════════════════════════════════════════════════════════════
def eq_to_finsler_qubo(eq_str: str, **kwargs) -> dict:
"""Convert an equation string to a Finsler-QUBO formulation.
This is the main entry point matching the Research-Stack pipeline.
Args:
eq_str: Equation string (e.g., "E = mc²" or "E = mc^2")
**kwargs: Passed to build_finsler_qubo (m, c, etc.)
Returns:
Dictionary with:
- shape: EquationShape
- fisher_metric: Fisher metric components
- drift_one_form: Drift 1-form components
- randers_metric: Randers metric verification
- qubo: QUBO matrix as dense numpy array
- qubo_sparse: QUBO as sparse dict
- hachimoji_mapping: State-to-variable mapping
"""
# Step 1: Parse equation shape
shape = parse_equation_shape(eq_str)
# Step 2: Build Fisher metric (α component)
m = kwargs.get("m", 1.0)
c = kwargs.get("c", 299792458.0)
fisher = fisher_metric_for_emc2(m, c)
# Step 3: Build drift 1-form (β component)
drift = drift_one_form_for_emc2(c)
# Step 4: Form Randers metric
randers = RandersMetric(fisher=fisher, drift=drift)
# Step 5: Build QUBO
qubo = build_finsler_qubo(m=m, c=c, **{k: v for k, v in kwargs.items()
if k not in ("m", "c")})
# Build state mapping
hachimoji_mapping = {
i: {"symbol": sym, **HACHIMOJI_STATES[sym]}
for i, sym in enumerate(HACHIMOJI_SYMBOLS)
}
# Check strong convexity at sample direction
sample_convex = randers.check_strong_convexity(1.0, 0.0)
return {
"equation": eq_str,
"shape": shape.to_dict(),
"parameters": {"m": m, "c": c},
"fisher_metric": {
"g_mm": fisher.g_mm,
"g_mc": fisher.g_mc,
"g_cc": fisher.g_cc,
"determinant": fisher.g_mm * fisher.g_cc - fisher.g_mc ** 2,
},
"drift_one_form": {
"beta_m": drift.beta_m,
"beta_c": drift.beta_c,
},
"randers_metric": {
"strong_convexity_sample": sample_convex,
"sample_cost_vm_1_vc_0": randers.compute(1.0, 0.0),
},
"qubo_n": qubo.n,
"qubo_matrix": qubo.to_numpy().tolist(),
"qubo_sparse": {f"({i},{j})": v for (i, j), v in qubo.Q.items()},
"hachimoji_mapping": hachimoji_mapping,
}
# ═══════════════════════════════════════════════════════════════════════════
# VIII. Example / Self-Test
# ═══════════════════════════════════════════════════════════════════════════
if __name__ == "__main__":
print("=" * 70)
print("FINSLER → QUBO BRIDGE FOR E=mc²")
print("=" * 70)
# Run the full pipeline
result = eq_to_finsler_qubo("E = mc²", m=1.0, c=299792458.0)
print(f"\nEquation: {result['equation']}")
print(f"Shape: {result['shape']}")
print(f"\nFisher Metric (α component):")
print(f" g_mm = {result['fisher_metric']['g_mm']:.6e}")
print(f" g_mc = {result['fisher_metric']['g_mc']:.6e}")
print(f" g_cc = {result['fisher_metric']['g_cc']:.6e}")
print(f" det(g) = {result['fisher_metric']['determinant']:.6e}")
print(f"\nDrift 1-Form (β component):")
print(f" β_m = {result['drift_one_form']['beta_m']:.6e}")
print(f" β_c = {result['drift_one_form']['beta_c']:.6e}")
print(f"\nRanders Metric:")
print(f" F(1,0) = {result['randers_metric']['sample_cost_vm_1_vc_0']:.6e}")
print(f" Strong convexity (sample): {result['randers_metric']['strong_convexity_sample']}")
print(f"\nQUBO Matrix ({result['qubo_n']}×{result['qubo_n']}):")
qubo_mat = np.array(result['qubo_matrix'])
print(qubo_mat)
print(f"\nHachimoji Mapping:")
for i, mapping in result['hachimoji_mapping'].items():
print(f" x_{i}{mapping['symbol']} (phase={mapping['phase']}°, {mapping['regime']})")
# Test with normalized c (for numerical stability in QUBO)
print("\n" + "=" * 70)
print("NORMALIZED VERSION (c=1, m=1)")
print("=" * 70)
result_norm = eq_to_finsler_qubo("E = mc²", m=1.0, c=1.0)
print(f"\nFisher Metric:")
print(f" g_mm = {result_norm['fisher_metric']['g_mm']:.4f}")
print(f" g_mc = {result_norm['fisher_metric']['g_mc']:.4f}")
print(f" g_cc = {result_norm['fisher_metric']['g_cc']:.4f}")
print(f"\nQUBO Matrix:")
print(np.array(result_norm['qubo_matrix']))
print("\n✓ Finsler→QUBO bridge complete for E=mc²")