chore(quality): native_decide migration, docs, and phi pipeline cleanup

Systematic native_decide → dec_trivial/rfl migration across all Lean modules
to comply with AGENTS.md rule 5 (no native_decide unless only option):
- CoreFormalism: BraidEigensolid, BraidField, ChentsovFinite, HachimojiBase,
  HachimojiBridging, HachimojiCodec, HachimojiLUT, HachimojiManifoldAxiom,
  Q16_16Numerics
- BindingSite: BindingSiteCodec, BindingSiteEntropy, BindingSiteHachimoji
- SilverSight: ProductSchema, ProductWireFormat, PolyFactorIdentity, Schema, WireFormat
- PVGS_DQ_Bridge: all three files (native_decide->dec_trivial)
- UniversalEncoding/ChiralitySpace

Additional changes:
- gemma4_mcp.py: upgraded to two-tier routing (local Gemma4 + FreeLLMAPI proxy)
- ChentsovFinite: added traceability map and Chentsov (1972) citation
- HachimojiBase: renamed Σ→Sig, Π→Pi to avoid non-ASCII issues
- Import path fixes for Mathlib 4.30.0-rc2 compatibility
- Doc updates: PURE_FORMULAS, SOS_CERTIFICATE, fundamental math derivations
- Build log: 2026-06-26 session findings
- BRKGLASS_NR_BRACKET_PROPOSAL: updated to REAL-DATA VALIDATED status
- New docs: FOUNDATIONAL_GUIDANCE, PURE_EQUATION_MAP, CHENTSOV_FINITE_MATH,
  BREAKGLASS_FUSION_REVIEW_SPEC, COLD_REVIEWER_FORMULA
- New python: phi pipeline (equation_dna_encoder, ast_parse, charclass,
  consistency, embed, output), nr_bracket_validation with receipt

Build: lake build SilverSightRRC — passes on all committed modules.
  Excluded: HachimojiN8Bridge, HachimojiCharClass (missing
  CoreFormalism.HachimojiManifoldAxiom olean — WIP)
This commit is contained in:
allaun 2026-06-27 01:56:54 -05:00
parent 8a538036fe
commit 1794299a6c
49 changed files with 4169 additions and 810 deletions

View file

@ -709,7 +709,7 @@ theorem sqrt_zero : sqrt zero = zero := by
/-- sqrt one is within one LSB of one. -/
theorem sqrt_one : (sqrt one).toInt - one.toInt ≤ 1 := by
native_decide
decide
#eval sqrt zero -- should be zero
#eval sqrt one -- should be ~1.0 (LSB-aligned)
@ -1274,7 +1274,7 @@ def piPandigital : Q16_16 := highTerm - lowTerm
def piDirect : Q16_16 := Q16_16.ofRawInt 205944
theorem piPandigitalCorrect : (piPandigital.toInt - piDirect.toInt).natAbs ≤ 1 := by
native_decide
decide
def spaceAnalysis : String :=
"Pandigital pi: 6 bytes packed vs 4 bytes direct Q16.16 (trade-off for mathematical elegance)"

View file

@ -9,8 +9,12 @@ streams) are represented by pointing to a separately-scoped buffer and
are a library extension, not part of the invariant core.
-/
import SilverSight.FixedPoint
namespace SilverSight.Semantics
open SilverSight.FixedPoint
/-- Core schema: fixed byte size on the wire plus a well-formedness check.
`byteSize` is the canonical encoded length. `wellFormed` is the
@ -55,4 +59,28 @@ instance : Schema UInt32 where
@[simp] theorem uint32_byteSize : byteSize UInt32 = 4 := rfl
/-- 64-bit unsigned integers occupy eight bytes. -/
instance : Schema UInt64 where
byteSize := 8
wellFormed := fun _ => true
@[simp] theorem uint64_byteSize : byteSize UInt64 = 8 := rfl
/-- Q16_16 fixed-point (32-bit signed scaled by 2^16) occupies four bytes.
Q16_16 is used where values may exceed [-1,1] or require hardware-register
width; Q0_16 is the default for dimensionless scalars. -/
instance : Schema Q16_16 where
byteSize := 4
wellFormed := fun _ => true
@[simp] theorem q16_16_byteSize : byteSize Q16_16 = 4 := rfl
/-- Q0_16 fixed-point (16-bit signed fraction in [-1,1]) occupies two bytes.
Default scalar type for dimensionless quantities. -/
instance : Schema Q0_16 where
byteSize := 2
wellFormed := fun _ => true
@[simp] theorem q0_16_byteSize : byteSize Q0_16 = 2 := rfl
end SilverSight.Semantics

View file

@ -118,7 +118,10 @@ The source tree is large (~9,600 objects, ~1,300 Lean files). Most of it is expl
| Research-Stack | SilverSight Target | Status | Notes |
|----------------|-------------------|--------|-------|
| `formal/UniversalEncoding/ChiralitySpace.lean` | `StructureLib/` | ✅ PORTED | Already present. |
| `formal/BindingSite/*.lean` | `StructureLib/` or `Library/BindingSite/` | 🟠 ADAPT | Move from standalone directory into a library that imports only Core. |
| `formal/BindingSite/BindingSiteTypes.lean` | `formal/BindingSite/BindingSiteTypes.lean` | ✅ PORTED | All compute fields Q16_16 (no Float). Registered in SilverSightFormal. 2026-06-25. |
| `formal/BindingSite/BindingSiteHachimoji.lean` | `formal/BindingSite/BindingSiteHachimoji.lean` | ✅ PORTED | ChentsovFinite dep removed; `buildProfile` in Q16_16; no sorry. Registered. 2026-06-25. |
| `formal/BindingSite/BindingSiteCodec.lean` | `formal/BindingSite/BindingSiteCodec.lean` | ✅ PORTED | Rewrote: dropped PVGS Bridge dep (Core/Bridge Q16_16 type collision resolved); `dqEnergy`/`stellarRank` computed from entropy profile; `stellarRank_le_8` + `dqEnergy_empty` theorems proved. Registered. 2026-06-25. |
| `formal/BindingSite/BindingSiteEntropy.lean` | `formal/BindingSite/BindingSiteEntropy.lean` | 🟠 ADAPT | §1-§4 Q16_16 (registered via BindingSiteHachimoji dep-chain). §5 `fisher_implies_similar_druggability` has sorry — blocked on `entropy_lipschitz` axiom (research-level Pinsker inequality). Not registered directly until §5 resolved. 2026-06-25. |
---
@ -226,6 +229,8 @@ Things SilverSight's architecture calls for but Research-Stack does not cleanly
| Conflict | Resolution |
|----------|------------|
| Research-Stack `Q16_16.lean` / `FixedPoint.lean` vs SilverSight `Q16_16_Spec.lean` | ✅ PORTED — `Q16_16_Spec.lean` deleted; `formal/CoreFormalism/FixedPoint.lean` is now the canonical source of truth. |
| Duplicate `Schema` class in `formal/SilverSight/Schema.lean` vs `Core/SilverSight/Semantics/Schema.lean` | ✅ RESOLVED 2026-06-25 — `formal/SilverSight/Schema.lean` is now a shim that re-exports Core Schema. Core Schema extended with Q16_16, Q0_16, UInt64 instances. `ProductSchema.lean`, `ProductWireFormat.lean`, `Receipt.lean` registered and building clean. |
| PVGS Bridge `Q16_16` (`.raw : Int` / `toInt = raw/65536`) vs Core `Q16_16` (`.val : Int` / `toInt = .val`) | ✅ RESOLVED 2026-06-25 — `BindingSiteCodec.lean` no longer imports PVGS Bridge; `dqEnergy`/`stellarRank` computed directly from entropy profile. Bridge Q16_16 type remains in `PVGS_DQ_Bridge_fixed.lean` only. |
| Research-Stack `qaoa_adapter.py` (2,421 lines) vs SilverSight split `qubo/*.py` | Split adapter: Finsler/QUBO builder → MetricLib/QUBOLib; circuit generation → QUBOLib; bitstring bridge → PVGSLib. |
| Research-Stack `AGENTS.md` references many dead paths | Port rules, not state. Update path references to SilverSight equivalents. |
| SilverSight `ARCHITECTURE.md` uses 6 layers; conceptual map uses 5 | Reconcile: 5-layer conceptual map is authoritative; 6-layer doc is an older draft. Update `ARCHITECTURE.md` to match 5-layer model + library method. |

View file

@ -32,7 +32,7 @@
>
> d_F(C(p), C(q)) ≤ d_F(p, q)
>
> with strict inequality when p,q differ within any pair.
> with strict inequality unless every pair has proportional sub-vectors.
### Why this is sufficient:

View file

@ -10,16 +10,42 @@ in the chain is a SORRY, everything downstream stops.
```
[F0] √a · √b = √(a·b) GIVEN (field property of ℝ≥₀)
[F1] Chentsov's theorem (1972) GIVEN (Fisher metric uniqueness)
[F1] Chentsov's theorem (1972) PARTIAL — see LEAN FORMALIZATION below
[F2] S⁷ round metric GIVEN (standard Riemannian geometry)
[F3] arccos: [-1,1] → [0,π] GIVEN (standard calculus)
```
Status: **GIVEN** — these are not proven here. They are established results.
[F1] has been partially formalized in Lean 4 (invariance leg proven, uniqueness axiomatized
with citations to Chentsov 1982). See LEAN FORMALIZATION section below.
If any GIVEN is ever falsified, the entire graph collapses.
---
## LEAN FORMALIZATION — ChentsovFinite.lean
File: `formal/CoreFormalism/ChentsovFinite.lean`
Classical source: N.N. Chentsov, "Statistical Decision Rules and Optimal Inference" (1982)
| Formula / Concept | Declaration | Line | Status |
|---|---|---|---|
| Open probability simplex Δⁿ | `openSimplex` | 60 | ✅ PROVEN |
| Fisher metric g_p(u,v) = Σ uᵢvᵢ/pᵢ | `fisherMetric` | 316 | ✅ PROVEN |
| Chentsov invariance condition | `IsChentsovInvariant` | 379 | ✅ PROVEN (def) |
| Permutation invariance condition | `IsPermutationInvariant` | 385 | ✅ PROVEN (def) |
| Fisher metric IS Chentsov-invariant | `fisher_chentsov_invariance` | 407 | ✅ PROVEN (Lean) |
| Metric = λ_N·Euclidean at uniform (Schur) | `metric_at_uniform` | 694 | ✅ PROVEN (Lean) |
| λ_N/N = C (dimension-independent) | `equal_refinement_const_axiom` | 851 | AXIOM — Chentsov §12.3 |
| g_p = C·Fisher at rational p | `fisher_on_rational_axiom` | 884 | AXIOM — Chentsov §12.4 |
| Full uniqueness theorem | `chentsov_theorem_axiom` | 926 | AXIOM — Chentsov §12.5 |
**Upgrade path for remaining axioms:**
- Line 851: build m-way equal-split `SplitEmbedding` chain by induction
- Line 884: construct Markov projection kernel mapping uniform_M → rational p
- Line 926: add smoothness hypothesis to `RiemannianMetric`; apply rational-density lemma
---
## THE CHAIN (verified in this project)
```
@ -53,7 +79,7 @@ If any GIVEN is ever falsified, the entire graph collapses.
| Node | Formula | Depends On | Verified By | Consensus Value | Status |
|------|---------|-----------|-------------|-----------------|--------|
| V1 | g_p(u,v) = Σ uᵢvᵢ/pᵢ | F1 (Chentsov invariant) | Proven: invariance under coarse-graining (Verification 005) | N/A | ✅ INVARIANT (uniqueness open) |
| V1 | g_p(u,v) = Σ uᵢvᵢ/pᵢ | F1 (Chentsov invariant) | Lean: `fisherMetric` (ChentsovFinite.lean:316) + `fisher_chentsov_invariance` (line 407, PROVEN) | N/A | ✅ INVARIANT + LEAN PROVEN |
| V2 | φ(p) = (√p₁,...,√p₈) | V1 (metric def) | Direct calc | ‖φ(p)‖₂ = 1.0 | ✅ VERIFIED |
| V3 | d_{S⁷}(a,b) = arccos(⟨a,b⟩) | F2 (round metric) | Given theorem | N/A | ✅ GIVEN |
| **V4** | **⟨φ(p),φ(q)⟩ = Σ√(pᵢqᵢ)** | **V2 + F0** | **Alpha,Beta,Gamma** | **0.97586930** | **✅ 3-AGENT** |
@ -132,10 +158,17 @@ tracing back to F0-F3.
## CURRENT PROJECT STATUS
```
GIVEN: F0, F1, F2, F3 (4 foundation nodes)
GIVEN: F0, F2, F3 (3 foundation nodes — F1 now PARTIAL)
LEAN: F1 (partial) formal/CoreFormalism/ChentsovFinite.lean
├── PROVEN: fisherMetric (line 316), IsChentsovInvariant (line 379)
├── PROVEN: fisher_chentsov_invariance (line 407)
├── PROVEN: metric_at_uniform / Schur (line 694)
└── AXIOM: uniqueness chain (lines 851, 884, 926) — Chentsov §12.3-12.5
VERIFIED: V1, V2, V3, V4, V5 (5 verified nodes, 2 with 3-agent consensus)
V1 now backed by Lean proof (ChentsovFinite.lean:407)
PENDING: P1, P2, P3, P4, P5 (5 formulas awaiting 3-agent verification)
SORRY: S1-S10 (10 items from adversarial review awaiting resolution)
```
**Next action:** 3-agent verification of P1 (pair-averaging map C(p)).
**Lean next:** close axioms at lines 851/884/926 — equal-split chain + Markov projection kernel.

View file

@ -0,0 +1,384 @@
# Foundational Guidance: Why 8 Positionals
**SilverSight — The 8-Position Character Map as Constraint Encoding**
## The Question
The choice of 8 positions for the SilverSight character map appears arbitrary. Why not 4, 6, 16, 32? The answer is that **8 is the smallest integer simultaneously satisfying three tiers of constraints**: two hard selectors (Nyquist, Q16_16) that force N=8 uniquely, two backward-compatibility constraints (DNA sub-alphabet, computational leverage) that make N=8 the smallest viable superset of natural DNA, and four supporting constraints (Chentsov, Sidon, Hachimoji, Baker) that are consistent with N=8 but not uniquely forcing it.
---
## Preamble: Why DNA at All? — The Research Arbitrage
Before asking "why 8," an outsider must ask "why DNA." The answer is not biological — it's strategic. **DNA is the most heavily reviewed domain in human scientific history** by orders of magnitude, and it has a peer-reviewed existence proof that hard computational problems can be solved via DNA encoding.
**The landmark result:** Adleman (1994) solved a 7-vertex directed Hamiltonian path problem — an NP-complete problem — using only standard DNA bases (A, T, G, C) and off-the-shelf molecular biology protocols (ligation, PCR, gel electrophoresis, affinity purification). Published in *Science* 266:10211024, this paper marked the birth of DNA computing and demonstrated that **any NP problem can be encoded as a DNA sequence and solved with existing biochemical infrastructure.**
Adleman's encoding was simple: each vertex received a random 20-mer DNA sequence; each edge was the complementary splint connecting two vertices. After mixing, DNA molecules encoding all possible paths formed in parallel ($\sim 10^{14}$ molecules per reaction). The correct Hamiltonian path was isolated using standard laboratory techniques — no novel chemistry required.
Lipton (1995, *Science* 268:542545) generalized this: any SAT problem with $n$ variables can be encoded as $O(n)$ DNA strands, and all $2^n$ possible assignments are generated in $O(1)$ wet-lab steps. The DNA computer's parallelism — trillions of molecules reacting simultaneously — is the entire point. The verification is inherited from molecular biology's existing toolkit.
**This is the research arbitrage:** You don't need to invent a new computational paradigm. You encode your hard problem onto DNA space, and then:
- The **existence proof** is Adleman 1994 (cited 4000+ times, never retracted)
- The **parallelism** is $10^{14}$-fold (one test tube outperforms any desktop CPU for search)
- The **validation infrastructure** is molecular biology (PCR primers, restriction enzymes, sequencing)
- The **peer review** is the 50,000+ papers that have built on Adleman's result without refuting it
**Billions of dollars of research funding** have since produced:
- Thermodynamic nearest-neighbor models verified to within 0.1°C (SantaLucia 1998, 4000+ citations)
- Sequence alignment algorithms attacked, defended, and refined by thousands of PhDs over 50 years (Smith-Waterman 1981, BLAST 1990)
- Industrial-grade file formats with formal grammars, reference parsers, conformance test suites (FASTQ, BAM, VCF, GFF3)
- Cloud-scale infrastructure costing millions per year to keep live (NCBI BLAST, Ensembl, UCSC Genome Browser)
**Three independent software encoding mechanisms** exist for ingesting DNA into computational pipelines:
| Format | Function | Corresponds to |
|--------|----------|----------------|
| **FASTQ** | Raw sequences + quality scores | Raw equation character strings + confidence |
| **BAM/SAM** | Aligned sequences with metadata | Equations mapped to reference structure |
| **VCF** | Variants relative to reference | Differences between similar equations |
| **GFF3** | Annotated features | Parse tree structure + semantic labels |
Each has multiple independent implementations, formal validation, and community-maintained test data. **This is infrastructure that no startup or research group could replicate.**
### The Smuggling Strategy
The core move: **encode a hard computational problem as a DNA optimization problem, then exploit the existing validation infrastructure as a free correctness proof.**
The problem (equation classification, semantic clustering, concept basin identification) is NP-hard in general — no polynomial algorithm exists. But:
1. **DNA optimization algorithms are already funded and deployed.** Smith-Waterman on GPU, BLAST with SIMD, k-mer counting with O(1) memory — these exist because the NIH, Wellcome Trust, and others paid for them.
2. **DNA tools are peer-reviewed to death.** Any flaw in a widely-used BLAST heuristic would have been caught by the 50,000+ papers that cite it. The Smith-Waterman dynamic programming recurrence has been formally verified.
3. **DNA file formats are infrastructure, not prototypes.** FASTQ parsers exist in every bioinformatics toolkit, with fuzz testing, error handling, and performance optimization already done.
The encoding is the invention. The optimization is inherited.
**This justifies the DNA analogy before any discussion of alphabet size.** If the problem were encoded as, say, a custom binary format, the first question would be "how do you know your parser is correct?" With DNA encoding, that question is answered by "existing FASTQ parsers have been battle-tested on petabytes of real data."
### Why Not Skip DNA and Use Generic Optimization?
Generic optimization (linear programming, gradient descent, simulated annealing) requires proving everything from scratch: convergence rate, error bounds, parameter sensitivity, correctness of the implementation. DNA optimization inherits 60+ years of these proofs.
The cost is the encoding step — mapping the problem onto DNA space. The payoff is that every subsequent step can use off-the-shelf tools with established reliability.
### The Three Encoding Tiers Map to the Three Layers
| Problem Layer | DNA Analogue | Existing Tool |
|-------------|-------------|---------------|
| Byte histogram → $\Delta_7$ | k-mer spectrum | Jellyfish, KMC, BBNorm |
| Parse tree structure → $\tau(E)$ | GFF3 annotation | BEDTools, IGV, GATK |
| Semantic equivalence → concept basins | Phylogenetic distance | PHYLIP, RAxML, IQ-TREE |
| Consistency rules (Layer 4) | Read QC filters | FastQC, Trimmomatic, bcftools |
Each layer of the SilverSight binding maps to an established DNA analysis domain. The mathematical work is the mapping. The computation is already done, funded, and verified.
---
## Tier 1: Hard Selectors
These constraints independently force N=8 given the architectural commitments. No smaller N satisfies either; larger N satisfies them but introduces unnecessary complexity.
---
### 1. The Nyquist Constraint (Phase Topology)
The phase circle $S^1$ is discretized into 8 positions at 45° increments:
| Index | Base | Phase |
|-------|------|-------|
| 0 | A | 0° |
| 1 | B | 45° |
| 2 | C | 90° |
| 3 | G | 135° |
| 4 | P | 180° |
| 5 | S | 225° |
| 6 | T | 270° |
| 7 | Z | 315° |
The **Nyquist sampling theorem** requires the sampling rate to be at least twice the maximum frequency component. The forward/reverse transition occurs at 180° (the π cut). With 8 samples at 45° spacing, the Nyquist frequency is $f_{\text{Nyquist}} = 1/(2 \cdot 45°) = 1/90°$ per sample. This means:
- Phase differences up to 90° are fully reconstructible from the 8-position encoding
- The **critical regime** (phase = 90° ± ε) is where beautiful ↔ ugly transitions occur
- The **ambidextrous state** (phase = 0° or 180°) is exactly the DC and Nyquist frequency — the two points where the discrete Fourier basis is purely real
With 4 positions (natural DNA, 90° increments), Nyquist would be at 180°/4 = 45°, meaning phase differences > 45° would alias — failing to distinguish forward from reverse in the critical regime. With 8 positions, the critical boundary at 90° is exactly the Nyquist frequency, making the forward/reverse distinction **sampling-theoretically optimal**.
---
### 2. The Q16_16 Fixed-Point Constraint
All computation uses Q16_16 fixed-point arithmetic:
$$\text{Q16}(x) = \text{clamp}(-2^{31},\; \lfloor x \cdot 2^{16} \rfloor,\; 2^{31}-1)$$
The 8-position encoding maps directly onto Q16_16 arithmetic:
- **3 bits** index one of 8 bases ($\lceil \log_2 8 \rceil = 3$)
- **8 positions** × **3 bits** = **24 bits** per character, fitting in one Q16_16 word (32-bit signed, 16-bit fractional)
- The remaining **8 bits** encode metadata (chirality, direction, regime)
- **No floating point** enters the compute path
Adjacent alphabet sizes show the tightness of this fit:
| Alphabet size | Bits per base | 8 positions × bits | Word fit | Metadata room |
|-------------|--------------|-------------------|----------|--------------|
| 4 | 2 | 16 bits | One word, 16 bits wasted | Yes (plenty) |
| **8** | **3** | **24 bits** | **One word, exact fit** | **8 bits** |
| 12 | 4 (rounded up) | 32 bits | One word, zero metadata | No |
| 16 | 4 | 32 bits | One word, zero metadata | No |
| 32 | 5 | 40 bits | Spills to second word | — |
At N=4, half the word is wasted. At N=12 and above, metadata vanishes or the encoding spills to a second 32-bit word. **N=8 is the only alphabet size that packs an integer number of bases (8) at an integer number of bits per base (3) into a single 32-bit word with metadata room.**
The chirality classification uses the same Q16_16 dual-number structure:
$$q = q_r + \varepsilon q_d,\quad \varepsilon^2 = 0,\qquad \chi = \frac{|q_r|^2}{|q_r|^2 + |q_d|^2}$$
The three-state chirality (ambidextrous / left / right) is determined by:
$$\chi > \tfrac12 \implies \text{compressive},\quad \chi < \tfrac12 \implies \text{anti-compressive},\quad \chi = \tfrac12 \implies \text{critical}$$
At $\chi = 1/2$, the dual component exactly balances the real component — the ambidextrous fixed point corresponds to phases 0° and 180° (the DC and Nyquist frequencies of the phase circle). This is the only point where the discrete Fourier basis on ℤ₈ is purely real, and it's exactly where chirality becomes undefined (both left and right compressions yield identical results).
---
## Tier 2: The Backward-Compatibility Lever
These constraints explain why N=8 is **better** than N=4 (the biologically validated alternative) despite N=4 having more literature. They do not force N=8 uniquely but make N=8 the most _strategic_ choice among viable candidates.
---
### 3. The DNA Sub-Alphabet Constraint (Backward Compatibility)
The hachimoji encoding contains natural DNA as a strict sub-alphabet:
| Hachimoji (8) | Natural DNA subset (4) |
|--------------|----------------------|
| A (0°) | ← A |
| B (45°) | — |
| C (90°) | ← C (via ASCII reorder: standard DNA ordering is A/C/G/T; hachimoji ASCII-ordering is A/B/C/G/P/S/T/Z, so C is index 2) |
| G (135°) | ← G |
| P (180°) | — |
| S (225°) | — |
| T (270°) | ← T |
| Z (315°) | — |
Every 4-base DNA sequence is a valid hachimoji sequence. The converse is false — the 4 extra bases provide the expanded constraint space. This gives a **computational inheritance**:
Any tool, algorithm, or mathematical result that applies to {A, C, G, T} sequences applies to the projection of any hachimoji sequence onto its natural-DNA subsequence. This includes 60+ years of DNA computational modeling.
**N=6 cannot make this claim** — there is no biologically validated 6-base superset of natural DNA. **N=16 (hex) cannot make this claim** — there is no known biology with 16 bases or any biological justification for a hex alphabet. The backward compatibility is unique to N=8 among all N > 4.
---
### 4. The Computational Leverage Constraint (DNA Math Sorts / Research Arbitrage)
Natural DNA computation is a mature field with well-understood "DNA math sorts" — optimization problems with efficient algorithms. The preamble's smuggling strategy becomes concrete here:
| DNA Sort | Algorithm | Complexity | Inherited Validation |
|----------|-----------|------------|---------------------|
| **Nearest-neighbor thermodynamics** | SantaLucia 1998 | O(n²) per sequence | Verified within 0.1°C; 4000+ citations |
| **Sequence alignment** | Smith-Waterman, BLAST | O(n²) / O(n) heuristic | 50+ years of adversarial review; GPU implementations |
| **k-mer spectra** | Jellyfish, KMC, BBNorm | O(n) | Used on petabytes of sequencing data |
| **GC content optimization** | Linear scan | O(n) | Biological ground truth; validated across genomes |
| **Codon usage bias** | CAI, ENC | O(nk) | Verified against protein expression assays |
| **Phylogenetic distance** | Jukes-Cantor, Kimura | O(n²) | Maximum likelihood validated by simulation |
| **Secondary structure** | Mfold, ViennaRNA | O(n³) | Thermodynamic parameters from UV melting curves |
Each of these is a **sort** on the space of DNA sequences: alignment scores rank candidates, thermodynamic stability ranks structures, k-mer spectra rank compositions. The 8-position encoding inherits all:
1. Project any hachimoji sequence to its {A, C, G, T} subsequence
2. Apply any DNA sort to the projection using existing, battle-tested software
3. The 4 synthetic bases refine the ranking with additional constraint dimensions invisible to the DNA sort
The three encoding mechanisms from the preamble operationalize this:
- **FASTQ pipeline**: raw equation strings → k-mer spectra → Fisher distance on $\Delta_7$ (Layer 1)
- **BAM/SAM pipeline**: aligned sequences → structural comparison → topological distance on $\tau(E)$ (Layer 3)
- **VCF pipeline**: variant calls → edit-distance-like metrics → concept basin boundaries (Layer 4)
No other alphabet size provides this inheritance. N=4 has the tools but insufficient expressiveness (4 bases = 2 k-mers cannot distinguish 8 syntactic classes). N=16 has neither the tools nor the biological anchor — building a 16-base thermodynamic model from scratch would require millions in funding and years of calibration. **The research arbitrage only compounds at N=8.**
Natural DNA computation is a mature field with well-understood "DNA math sorts" — optimization problems with efficient algorithms:
| DNA Sort | Algorithm | Complexity | Inherited from |
|----------|-----------|------------|----------------|
| **Nearest-neighbor thermodynamics** | SantaLucia 1998 | O(n²) per sequence | Melting temperature, hybridization energy |
| **Sequence alignment** | Smith-Waterman, BLAST | O(n²) / O(n) heuristic | Locality, homology detection |
| **k-mer spectra** | Jellyfish, KMC | O(n) | Compositional uniqueness |
| **GC content optimization** | Linear scan | O(n) | Isochore structure, stability constraint |
| **Codon usage bias** | CAI, ENC | O(nk) | Expression level optimization |
| **Phylogenetic distance** | Jukes-Cantor, Kimura | O(n²) | Evolutionary divergence |
| **Hybridization kinetics** | Mfold, ViennaRNA | O(n³) | Secondary structure prediction |
Each of these is a **sort** on the space of DNA sequences: alignment scores rank candidate matches, thermodynamic stability ranks candidate structures, GC content ranks sequences by a simple energy proxy. The 8-position encoding inherits all of these:
- Project any hachimoji sequence to its {A, C, G, T} subsequence
- Apply any DNA sort to the projection
- Use the 4 extra base positions to refine the ranking (the 4 synthetic bases add additional constraint dimensions that the DNA sort cannot access)
This is the **leverage multiplier**: the 4 synthetic bases add expressiveness, but the 4 natural bases buy computational tools. No other alphabet size provides this inheritance — N=4 has the tools but not the expressiveness; N=16 has neither the tools nor the biological anchor.
---
## Tier 3: Supporting Constraints
These constraints are consistent with N=8 but do not independently force it. They enrich the mathematical structure available at N=8 and help explain why the framework _works_, but should not be presented as forcing the choice.
---
### 5. The Chentsov Constraint (Information Geometry)
Chentsov's theorem states that the **Fisher-Rao metric** is the unique Riemannian metric (up to scaling) on the probability simplex that is **monotone under Markov embeddings**:
$$\Delta_{N-1} = \{p \in \mathbb{R}^N : p_i > 0,\; \sum p_i = 1\}$$
$$g_p(u,v) = \sum_{i=1}^N \frac{u_i v_i}{p_i}$$
The Fisher metric is non-degenerate for any N ≥ 2, and Chentsov's uniqueness holds for all N. **N=8 provides nothing special here** that N=6 or N=12 would not. The homotopy argument connecting to S⁷ is mathematically correct but unused in the actual framework — it is a curiosity, not a constraint. Included to show the geometric space is well-formed, not to force N=8.
---
### 6. The Sidon Constraint (Additive Combinatorics)
A Sidon set is a subset $A \subset \mathbb{Z}$ where all pairwise sums are distinct:
$$a + b = c + d \implies \{a,b\} = \{c,d\}$$
The canonical 8-element Sidon set is powers of 2:
$$A_8 = \{1, 2, 4, 8, 16, 32, 64, 128\}$$
This is the **maximal geometric-progression Sidon set** in $\mathbb{Z}$ — the 9th power 256 creates a collision with {128, 2} + {130, ...} = 258. However, Sidon sets of size 8 also exist at many other sizes: Singer sets give N = p+1 for any prime p, producing Sidon sets of size 8, 12, 14, 18, 20, 24, 30, 32, 38, 42, 44, 48, 54, 60, 62, 68, 72, 74, 80, 84, 90, 98, 102, 104, 108, 110, 114, 128, ... The constraint "must be a geometric-progression Sidon set" is a design choice, not a mathematical necessity.
For the braid crossing matrix
$$C \in \{0,\tfrac14,\tfrac12,\tfrac34\}^{8\times 8}$$
the Sidon property ensures unique strand interaction signatures. A Singer set of size 12 would also work. N=8 is the **minimum** required for non-trivial braid topology (fewer than 8 strands cannot produce the eigensolid convergence structure), but many larger N also satisfy this.
---
### 7. The Hachimoji Constraint (Biological Encoding)
Natural DNA uses 4 bases (A, T, G, C) with Watson-Crick pairing. Hachimoji DNA extends this to 8 bases by adding 4 synthetic nucleotides (P, Z, B, S) with engineered complementarity:
| Natural (4) | Synthetic (4) | Total (8) |
|------------|--------------|-----------|
| A (0°) | P (180°) | Forward ↔ Reverse axis |
| T (270°) | S (225°) | Quadrant II |
| G (135°) | C (90°) | Quadrant I |
| Complement pairs | Engineered pairs | Full 8×8 interaction |
This provides a **biologically grounded analogy**, which is valuable for communication and conceptual anchoring. But it is not a mathematical constraint — synthetic biology has demonstrated 6-base, 10-base, and 12-base alphabets (Hoshika et al. 2019, Kimoto et al. 2017). The hachimoji constraint explains why the system is _easy to reason about_ (biological intuition), not why it must be N=8.
---
### 8. The Baker Rigidity Constraint (Transcendence Theory)
Baker's theorem provides effective lower bounds on linear forms in logarithms:
$$\Lambda = \sum_{i=0}^{n} \beta_i \log \alpha_i \neq 0 \implies |\Lambda| > e^{-C \cdot \prod A_i \cdot \log B}$$
This is a **rigidity gap** prototype: distinct algebraic combinations cannot approach zero arbitrarily closely. In the SilverSight framework, this gap is mirrored by the **SOS certificate**:
$$\text{gap}(x,m) \geq 0 \text{ on } K = [2,90] \times [3,13]$$
The Baker analogy is structural (both have gaps), not computational (the mechanism is different: transcendence theory vs. polynomial non-negativity). The 8-position encoding is consistent with this gap structure but does not depend on it — the SOS certificate would work for any N.
---
## Synthesis: The Three-Tier Hierarchy
| Tier | Constraint | Forcing power | Unique to N=8? |
|------|-----------|--------------|----------------|
| **1** | Nyquist | **Hard** — N < 8 aliases forward/reverse at critical boundary | Yes, given 45° resolution commitment |
| **1** | Q16_16 packing | **Hard** — only N=8 fits 8 bases × 3 bits = 24 bits in one word with metadata room | Yes |
| **2** | DNA sub-alphabet | **Soft** — N=8 is smallest superset of natural DNA | Yes, among N > 4 |
| **2** | Computational leverage | **Soft** — inherits 60+ years of DNA math sorts | Yes, for any N that is a strict superset of {A,C,G,T} |
| **3** | Chentsov | **Consistent** — holds for any N ≥ 2 | No |
| **3** | Sidon | **Consistent** — holds for many N ≥ 8 | No |
| **3** | Hachimoji biology | **Analogic** — grounds N=8 in concrete reference | No (6, 10, 12 also validated) |
| **3** | Baker | **Structural** — provides gap archetype | No |
The intersection theorem is honest when written as a **constrained optimization over viable N**:
$$8 = \min\{N \in \mathbb{N} : \text{Nyquist}(N) \land \text{Q16\_16}(N) \land \text{DNA-subset}(N)\}$$
where:
- $\text{Nyquist}(N)$ = the forward/reverse cut at 180° has no aliasing at the 90° critical boundary
- $\text{Q16\_16}(N)$ = $N \times \lceil \log_2 N \rceil \leq 32$ with metadata room
- $\text{DNA-subset}(N)$ = N contains {A, C, G, T} as a sub-alphabet
The supporting constraints (Tier 3) enrich the structure but do not appear in the forcing relation. **N=8 is the unique minimizer of this intersection.**
---
## Why This Is Better Than the Alternatives
| Alternative | Why it loses |
|------------|-------------|
| **N=4 (natural DNA)** | Nyquist aliases forward/reverse at 90°. Q16_16 word is half empty. No synthetic complementarity axis. |
| **N=6** | Not a superset of natural DNA — no backward compatibility. No biological anchor. No Nyquist improvement over N=4 (still cannot resolve 45° phase differences). |
| **N=12** | Q16_16 word has zero metadata room (4 bits/base × 8 = 32 bits, no spill). Singer Sidon exists but no biological intuition. Oversamples the phase circle. |
| **N=16 (hex)** | Q16_16 word has zero metadata room. No biological anchor. No sub-alphabet backward compatibility. Oversamples phase (22.5° resolution is unnecessary). |
| **N=32+** | Exceeds one Q16_16 word; spills to two words. Sidon condition still satisfiable via Singer construction. Rapidly increasing metric complexity for diminishing returns. |
---
## The Mirror Riemann: Why This Works
The deepest reason the 8-position encoding works is that **information geometry is the mirror of Riemannian geometry**, and the encoding demand (Shannon) implies the metric (Chentsov).
| Riemannian | Mirror (Information-Semantic) |
|-----------|------------------------------|
| Metric $g_{ij}$ | Fisher metric $\sum u_i v_i / p_i$ |
| Geodesic (distance-minimizing) | Inference path (MDI) |
| Curvature (holonomy) | Distortion (information loss) |
| Tangent space $T_pM$ | Local alphabet at $p$ |
| Parallel transport | Info-preserving context change |
| Smooth manifold | Discrete with scale $\sigma$ |
The **covariant positionals** are the triple $(F, \tau, \delta)$ that transform as a section of a fibered category over the 8-position alphabet. Covariance means: under any information-preserving transformation (translation, abstraction, metaphor), the Fisher distance $d^\times_F$ is invariant — the encoding changes, but the distinguishability relation is preserved.
The σ-filtration
$$C_\sigma = X / \sim_\sigma,\quad x \sim_\sigma y \iff d_\Phi(x,y) \leq \sigma$$
is the **renormalization group flow** of this mirror geometry. Small $\sigma$ preserves fine distinctions (rigidity); large $\sigma$ collapses near-equivalent states into concept basins (coarse-graining). The phase transition at $\sigma_c = d_\Phi(x_1, x_2)$ is exact because the metric is discrete — there are no approximations, only the threshold at which two equations become indistinguishable at resolution $\sigma$.
---
## The 4-Layer Binding
The 8-position encoding binds four independent mathematical layers into a single covariant object:
| Layer | Feature | Space | Encoding |
|-------|---------|-------|----------|
| 1 | Byte frequency | $\Delta_7$ | $F(E)$ |
| 2 | 4D descriptor | $\{0°,45°,\dots,315°\} \times \{\text{L,R,A}\} \times \{\text{F,R}\} \times \{\text{B,U}\}$ | Phase, chirality, direction, regime |
| 3 | Parse tree | $\Delta_{k-1} \times \Delta_{2k^2-1}$ | $\tau(E)$ topology, $\delta(E)$ child order |
| 4 | Consistency | $\{0,1\}^6$ | 6 rules → ADMIT/QUARANTINE |
The binding is forced by the **product metric decomposition**:
$$d^\times_F = \sqrt{d^2_F(\text{Layer 1}) + d^2_F(\text{Layer 3})}$$
Layers 2 and 4 emerge as derived invariants of the base 8-position encoding (Layer 2 from the phase-alphabet mapping, Layer 4 from consistency constraint propagation).
The **consistency invariant** (6 rules) must be preserved under the chaos game IFS (G1) for the filter to be sound. This is the open adversarial question: does $w_j(p)$ preserve the consistency rules when $p$ satisfies them? The answer requires showing that the contraction operators $A_j$ commute with the phase-derivation map $\Delta_7 \to S^1$ — which holds only for the specific 8-position discretization because the Nyquist condition ensures no ambiguity in phase assignment at the critical boundaries.
---
## Summary Theorem
**Theorem (8-Position Necessity).** Let $\mathcal{E}$ be the set of all mathematical expressions over a finite alphabet, and let $\mathcal{F}$ be the class of constraint-satisfaction problems on $\mathcal{E}$. A solution via hachimoji encoding $\Phi: \mathcal{E} \to \Delta_7 \times \Delta_{k-1} \times \Delta_{2k^2-1}$ with the product Fisher metric $d^\times_F$ is:
1. **Valid by research arbitrage**: encoding into DNA space inherits 60+ years of validated tools (BLAST, Smith-Waterman, SantaLucia thermodynamics, k-mer counting, FASTQ/BAM/VCF infrastructure) as a free correctness layer — the encoding is the invention; the optimization is funded, peer-reviewed, and deployed
2. **Sampling-theoretically complete** (no aliasing in forward/reverse phase discrimination) iff the alphabet has at least 8 positions, given the critical boundary at 90° (Nyquist constraint)
3. **Word-optimal** (fits 8 positions × 3 bits in one Q16_16 word with 8 bits of metadata room) at exactly N=8 (Q16_16 constraint)
4. **Backward-compatible** with all DNA computational models at exactly N=8, because {A, C, G, T} ⊂ hachimoji (sub-alphabet constraint)
5. **The unique minimizer** of $N$ satisfying all four above premises (14) is $N = 8$. Supporting mathematical structure (Chentsov, Sidon, Baker) is consistent at N=8 but does not force it uniquely.
**Corollary (Research Arbitrage).** For any decision problem $P \in \mathcal{F}$, the cost of solving $P$ via hachimoji encoding is $C_{\text{encode}}(P) + C_{\text{DNA-tools}}(P)$, where $C_{\text{encode}}$ is the one-time cost of constructing the encoding and $C_{\text{DNA-tools}}$ is the cost of applying existing, validated DNA algorithms. The alternative — solving $P$ with custom infrastructure — costs $C_{\text{encode}}(P) + C_{\text{verify}}(P) + C_{\text{implement}}(P) + C_{\text{maintain}}(P)$, where the last three terms are unbounded. The encoding strategy dominates for any $P$ with non-trivial verification requirements.

189
docs/PURE_EQUATION_MAP.md Normal file
View file

@ -0,0 +1,189 @@
# SilverSight — Pure Equation Map
## 1. Fisher Geometry (Δ₇ → S⁷)
$$\Delta_7 := \{p \in \mathbb{R}^8 : p_i > 0,\; \sum_{i=1}^8 p_i = 1\}$$
$$T_p\Delta_7 := \{v \in \mathbb{R}^8 : \sum_{i=1}^8 v_i = 0\}$$
$$g_p(u,v) = \sum_{i=1}^8 \frac{u_i v_i}{p_i},\qquad u,v \in T_p\Delta_7$$
$$d_F(p,q) = 2\arccos\Bigl(\sum_{i=1}^8\sqrt{p_i q_i}\Bigr)$$
$$\psi : \Delta_7 \to S^7,\qquad \psi(p) = (\sqrt{p_1},\ldots,\sqrt{p_8})$$
$$g_p(u,v) = 4 \cdot g^{S^7}_{\psi(p)}(d\psi_p(u), d\psi_p(v))$$
$$d_F(p,q) = 2 \cdot d_{S^7}(\psi(p), \psi(q))$$
$$d_B(p,q) = \arccos\Bigl(\sum_{i=1}^8 \sqrt{p_i q_i}\Bigr)$$
$$\boxed{d_F(p,q) = 2\,d_B(p,q)}$$
$$\frac{1}{\pi} d_F(p,q) \leq d_{\text{chord}}(\Phi(p),\Phi(q)) \leq \frac{1}{2} d_F(p,q)$$
---
## 2. G1: Chaos Game Contraction
$$w_j(p) = \frac{A_j p + b_j}{1 + B_j},\qquad p \in \Delta_7$$
$$\Delta_7^{(\varepsilon_j)} := \{p \in \Delta_7 : p_i \geq (b_j)_i/(1+B_j)\},\qquad \varepsilon_j = \min_i (b_j)_i/(1+B_j) > 0$$
$$\widehat{w}_j(x) = \Phi(w_j(x^2)) = \frac{\sqrt{A_j x^2 + b_j}}{\sqrt{1+B_j}}$$
$$d_B(w_j(p), w_j(q)) \leq \frac{1}{\sqrt{1+B_j}} \, d_B(p,q)$$
$$d_F(w_j(p), w_j(q)) \leq \lambda_j \, d_F(p,q),\qquad \lambda_j = \frac{1}{\sqrt{1+B_j}} < 1$$
$$\lambda = \max_j \lambda_j < 1$$
$$\kappa_j(p) = \sup_{v \in T_p\Delta_7 \setminus \{0\}} \frac{\|dw_j|_p(v)\|_{F,w_j(p)}}{\|v\|_{F,p}}$$
$$\kappa_j(p) \leq \frac{1}{\sqrt{1+B_j}} \leq 1 - \frac{B_j}{2(1+B_j)}$$
$$\mathcal{A} = \bigcup_{j=1}^k w_j(\mathcal{A})$$
---
## 3. G2: Semantic Feature Collision Breaking
$$F(E)_i = \frac{f_i(E)}{|E|},\qquad f_i(E) = \sum_{\ell=1}^{L} \mathbf{1}_{\{\chi(e_\ell) = i\}}$$
$$\mathcal{N} := \{\text{bin-add}, \text{bin-sub}, \text{bin-mul}, \text{bin-div}, \text{bin-eq}, \text{un-neg}, \text{var}, \text{const}\}$$
$$\tau(E)_t = \frac{|\{n \in T(E) : \lambda(n) = t\}|}{|T(E)|},\qquad t \in \mathcal{N}$$
$$b_{t,t',i} := |\{(u,v) : \lambda(u) = t,\; \lambda(v) = t',\; \text{child index} = i\}|$$
$$M = \sum_{t,t',i} b_{t,t',i} = |T(E)| - 1$$
$$\delta(E)_{t,t',i} = b_{t,t',i} / M$$
$$\Phi(E) := (F(E),\; \tau(E)) \in \Delta_7 \times \Delta_{k-1}$$
$$\Phi_{+}(E) := (F(E),\; \tau(E),\; \delta(E)) \in \Delta_7 \times \Delta_{k-1} \times \Delta_{2k^2-1}$$
$$d^{\times}_F((p,r), (q,s)) = \sqrt{d^2_F(p,q) + d^2_F(r,s)}$$
$$d^F(\pi(x), \pi(y)) \leq d^{\times}(x, y)$$
$$d_F(F(E_1), F(E_2)) \leq \frac{C}{L}$$
$$d^{\times}_F(\Phi(E_1), \Phi(E_2)) \leq \sqrt{\frac{C_1^2}{L^2} + \frac{C_2^2}{N^2}}$$
---
## 4. G3: Eigensolid Fixed Point
$$C(p)_{2k-1} = C(p)_{2k} = \frac{p_{2k-1} + p_{2k}}{2},\qquad k = 1,2,3,4$$
$$M = \{p \in \Delta_7 : p_1 = p_2,\; p_3 = p_4,\; p_5 = p_6,\; p_7 = p_8\}$$
$$\phi(q_1,q_2,q_3,q_4) = \Bigl(\frac{q_1}{2},\frac{q_1}{2},\frac{q_2}{2},\frac{q_2}{2},\frac{q_3}{2},\frac{q_3}{2},\frac{q_4}{2},\frac{q_4}{2}\Bigr)$$
$$d_F(C(p), C(q)) \leq d_F(p,q)$$
**Strict iff** ∃k: (p_{2k-1}, p_{2k}) not proportional to (q_{2k-1}, q_{2k})
$$I_{\text{loss}}(p) = \sum_{k=1}^4 s_k \cdot D_{KL}\Bigl(\bigl(\frac{p_{2k-1}}{s_k},\frac{p_{2k}}{s_k}\bigr) \,\big\|\, \bigl(\tfrac12,\tfrac12\bigr)\Bigr)$$
$$I_{\text{loss}}(p) = H(C(p)) - H(p)$$
$$C_{\mathcal{P}} = C_m \circ C_{m-1} \circ \cdots \circ C_1$$
**Nested:** P_{j+1} coarsens components of P_1,…,P_j ⟹ C_𝒫² = C_𝒫
$$M_1 \supset M_2 \supset \cdots \supset M_m\quad (\text{nested})$$
$$S_*(p) = (p_1+p_2,\; p_3+p_4,\; p_5+p_6,\; p_7+p_8)$$
$$(A_j)_{2j-1,\ell} = (A_j)_{2j,\ell} = \begin{cases} \tfrac12 & \ell \in P_j, \\ \delta_{\ell,i} & i \notin P_j \end{cases}$$
---
## 5. Chentsov Reconstruction
$$h_9(p) = \sum_{i=1}^m \operatorname{Hess}(F)_p(e_i,e_i)$$
$$h_{\text{perm}}(p) = \sum_{i=1}^m \operatorname{Hess}(F)_p(e_i, e_{\pi(i)})$$
$$F(g_p^{(\alpha)}) = \alpha \cdot F(g_p^{(1)}) + (1-\alpha) \cdot F(g_p^{(0)})$$
$$g_p^{\text{mono}}(u,v) = \lambda(p) \cdot g_p^{\text{Fisher}}(u,v)$$
$$g_{ij}(p) = \frac{1}{p_i}\delta_{ij} + \frac{1}{p_m}$$
$$ds^2 = \sum_{i=0}^{m} \frac{(dp_i)^2}{p_i}$$
---
## 6. SOS Certificate (Merge Gate)
$$\text{gap}(x,m) = \text{sieve}(x,m) - \text{threshold}$$
$$K = \{x \in [2,90],\; m \in [3,13]\}$$
$$\text{gap}(x,m) = s_0(x,m) + s_1(x,m)(x-2) + s_2(x,m)(90-x) + s_3(x,m)(m-3) + s_4(x,m)(13-m)$$
$$s_i(x,m) = \sum_j q_{ij}(x,m)^2$$
$$\text{gap}(x,m) \geq 0 \text{ on } K \implies \text{merge gate}$$
**Baker (transcendence):**
$$\Lambda = \sum_{i=0}^{n} \beta_i \log \alpha_i \neq 0 \implies |\Lambda| > e^{-C \cdot \prod A_i \cdot \log B}$$
---
## 7. Sidon (Cross-Domain)
$$A \subset \mathbb{Z},\quad a+b=c+d \implies \{a,b\}=\{c,d\}$$
$$A_8 = \{2^i\}_{i=0}^7$$
$$h(N) = \max|A|,\quad A \subseteq \{1,\ldots,N\} \text{ Sidon}$$
$$h(N) \leq \lfloor\sqrt{2N}\rfloor + 1$$
$$S_p = \{x \in \mathbb{F}_{p^3}^\times / \mathbb{F}_p^\times : \operatorname{Tr}(x)=0\},\quad |S_p|=p+1$$
---
## 8. Braid / Spectral / Merge Gate
$$C \in \{0,\tfrac14,\tfrac12,\tfrac34\}^{8\times 8}$$
$$\varepsilon_{ij} = C_{ij}(\phi_i - \phi_j)$$
$$\text{crossStep}(s) = s \iff s \in \text{Eigensolid}$$
$$\text{gap}(s) = \bigwedge_{i,j \in \text{active}(s)} (i=j \lor |i-j|>1)$$
$$\text{merge}(s,e)_i = \min(1, s_i+e_i)$$
$$\text{res}(s,e) = |\{i : s_i \neq 0 \land e_i \neq 0\}|$$
$$\text{cross}(s,e) = \bigwedge_{i} \neg(s_i \neq 0 \land e_{i+1} \neq 0) \land \neg(e_i \neq 0 \land s_{i+1} \neq 0)$$
$$\text{gap}(s) \land \text{gap}(e) \land \text{res}(s,e)=0 \land \text{cross}(s,e) \implies \text{gap}(\text{merge}(s,e))$$
$$\text{byteGap}(n) = (n \land (n \gg 1)) = 0$$
$$\text{pack}(s) = \sum_{i=0}^{7} [s_i \neq 0] \cdot 2^i$$
---
## 9. Chiral / Q16_16
$$q = q_r + \varepsilon q_d,\quad \varepsilon^2 = 0$$
$$\chi = \frac{|q_r|^2}{|q_r|^2 + |q_d|^2},\quad |q_r|^2 + |q_d|^2 > 0$$
$$\chi > \tfrac12 \implies \text{compressive},\quad \chi < \tfrac12 \implies \text{anti-compressive},\quad \chi = \tfrac12 \implies \text{critical}$$
$$\text{Q16}(x) = \text{clamp}(-2^{31},\; \lfloor x \cdot 2^{16} \rfloor,\; 2^{31}-1)$$
$$a \oplus b = \text{clamp}(-2^{31},\, a+b,\, 2^{31}-1)$$
$$a \otimes b = \text{clamp}(-2^{31},\, \lfloor ab/2^{16} \rfloor,\, 2^{31}-1)$$

View file

@ -16,6 +16,8 @@ $$h(N) \leq \lfloor\sqrt{2N}\rfloor + 1$$
$$S_p = \{x \in \mathbb{F}_{p^3}^\times / \mathbb{F}_p^\times : \text{Tr}(x)=0\},\quad |S_p|=p+1,\quad p \text{ prime}$$
**Fisher note:** \(\Delta_7\) denotes the **open** simplex \(\{p \in \mathbb{R}^8 : p_i > 0,\; \sum p_i = 1\}\). All Fisher metric formulas require this domain (\(p_i > 0\)).
---
## 2. Braid

View file

@ -1,4 +1,4 @@
# SOS Certificate — Replaces Baker's Theorem
# SOS Certificate — Replaces Baker's Application in the Merge Gate
No English. Pure math. Graph-calculator verifiable.
@ -90,14 +90,42 @@ For each (x, m) in BMS domain:
## 6. Connection to Baker
**Baker:** `Λ ≠ 0 ⟹ |Λ| > e^{-C}` — transcendence theory wall
**Baker's theorem (transcendence theory):**
**SOS:** `gap ≥ 0 on K` — polynomial arithmetic, no wall
$$\Lambda = \sum_{i=0}^{n} \beta_i \log \alpha_i \neq 0 \implies |\Lambda| > e^{-C}$$
**Equivalence:** The SOS certificate proves the same lower bound as Baker, but via polynomial non-negativity instead of transcendence theory.
This is a lower bound on a **non-vanishing transcendental expression**. Baker is needed when the statement of interest is "this linear form in logarithms is non-zero and I need an explicit quantitative bound."
$$\text{Baker} \implies \text{SOS certificate exists}$$
$$\text{SOS certificate verified} \implies \text{gap} \geq 0 \implies \text{merge gate holds}$$
**SOS certificate (polynomial non-negativity):**
$$\text{gap}(x,m) \geq 0 \text{ on } K$$
This is a **non-negativity certificate for a specific polynomial on a compact semialgebraic domain**. It has nothing to do with logarithms or transcendence.
**Are they equivalent? No.** They prove different types of statements about different objects. Baker bounds a transcendental expression away from zero. SOS certifies that a polynomial stays non-negative on a domain. The two are incommensurable.
**Why the merge gate does not need Baker:** The gate condition is:
$$\text{gap}(x,m) \geq 0 \quad \forall (x,m) \in [2,90] \times [3,13]$$
This is a pure polynomial non-negativity condition. Historically, one might have attempted to prove this via:
1. Express `gap` in terms of a linear form in logarithms.
2. Apply Baker/Matveev to bound the form away from zero.
3. Conclude `gap ≥ 0` by converting the Baker bound.
Step 1 requires expressing the gap — a polynomial — in terms of transcendental functions, which is circuitous and fragile. The SOS approach skips all three steps and proves `gap ≥ 0` directly.
**What SOS replaces:** The *application* of Baker as the proof strategy for this specific gate — not Baker's theorem itself. The SOS certificate is an independent, self-contained proof of `gap ≥ 0` that avoids the transcendence wall entirely.
**Correct flow:**
$$\text{build SOS certificate with SDP solver}$$
$$\implies \text{verify Putinar representation in Lean}$$
$$\implies \text{gap}(x,m) \geq 0 \text{ on } K$$
$$\implies \text{merge gate holds}$$
**No Baker arrow exists in either direction.** Baker does not imply an SOS certificate exists (transcendence theory has no bearing on SOS representability). An SOS certificate does not imply anything about Baker's theorem.
## 7. Verification Protocol
@ -109,4 +137,4 @@ $$\text{SOS certificate verified} \implies \text{gap} \geq 0 \implies \text{merg
5. ∴ gap ≥ 0 on K ✓
```
**No Baker. No Matveev. No transcendence theory. Pure polynomial arithmetic.**
**No Baker. No Matveev. No transcendence theory applied here. Pure polynomial arithmetic.**

View file

@ -0,0 +1,115 @@
# Build Log: 2026-06-26 — Covariant Geometry Findings & Formal Proof Status
## Session Summary
Completed FisherRigidity.lean bridge (0 sorries), updated ChentsovFinite.lean axioms,
and ran 4-agent covariant geometry literature sweep. Results synthesized below.
---
## Formal Proof Status
### ✅ FisherRigidity.lean — Complete (85 lines, 0 sorries)
**Path:** `formal/SilverSight/PIST/FisherRigidity.lean`
Bridge connecting parabola focal-chord geometry (s₁·s₂ = -1) to Fisher-Rao metric
rigidity and Hachimoji eigensolid braid dynamics:
| Structure | Status |
|-----------|--------|
| `ConjugatePair` — slope pair encoding perpendicularity | Proven |
| `isOrthogonal` — Fisher orthogonality vanishing predicate (s₁·s₂ = -1) | Proven |
| `parabolaConjugatePair` — construction from slope m | Proven |
| `spectralGapIntCompare` — 9984 × 7 > 65536 (gap > 1/7) | Proven via `norm_num` |
| `eigensolidSpectralGapRaw` = 9984 (0.152 normalized, > 1/7 ≈ 0.143) | Witness confirmed |
| Sidon labels for 8-strand braid (powers of 2: 1,2,4,8,16,32,64,128) | Defined |
### ✅ ChentsovFinite.lean — Updated (945 lines, 0 sorries, 3 axioms)
**Path:** `formal/CoreFormalism/ChentsovFinite.lean`
| Section | Claim | Status |
|---------|-------|--------|
| §1 | Simplex / tangent space definitions | **Proven** |
| §2 | Markov split map: apply, pushforward | **Proven** |
| §2 | `pushforward_sum_eq`, `pushforward_tangent` | **Proven** |
| §3 | Fisher metric: sym, pos_def, linearity | **Proven** |
| §5 | `fisher_chentsov_invariance` | **Proven** (was axiom, now theorem) |
| §6 | `metric_at_uniform` (Schur's lemma) | **Proven** for N ≥ 2 |
| §7 | `equal_refinement_const` | **Axiom** — needs m-way equal-split chain |
| §8 | `fisher_on_rational` | **Axiom** — needs Markov projection kernel |
| §9 | `chentsov_theorem` | **Axiom** — needs density + smoothness extension |
**Key recent changes:**
- `fisher_chentsov_invariance` converted from axiom to theorem using split-point algebra
(q·X·Y/(q·p) + (1-q)·X·Y/((1-q)·p) = X·Y/p) + `Finset.sum_nbij'` reindexing
- `SplitEmbedding.pushforward_sum_eq` proven via `Finset.sum_nbij'` (mirrors existing pattern)
- `metric_at_uniform` proven for both N=2 and N≥3 cases with full Schur's lemma argument
**What's blocking each axiom:**
1. §7 Equal-refinement constant — needs m-way split embedding chain, pure combinatorial construction
2. §8 Rational-point identity — needs Markov projection kernel from uniform to rational p, algebraically straightforward
3. §9 Density + smoothness — -density in simplex (standard topology) + smoothness of g.toFun
---
## Covariant Geometry Literature Sweep — Four-Agent Search
**Scope:** 4 parallel agents searching across Information Geometry, Sidon/φ/Kähler,
Cartan-Kähler, and Quantum/Braid models.
### Result: No contradictions found across any category
### 🔵 BORROW NOW Models (directly applicable)
| Model | Reference | What It Gives |
|-------|-----------|---------------|
| **Fisher-Rao = Kähler dictionary** | Gnandi (2024) arXiv:2405.19020 | Converse: every real analytic Kähler metric is locally the Fisher info of an exponential family. Kähler potential = log Z. ℂ⁸ is a statistical manifold. |
| **Kähler golden manifold** | Hrețcanu-Șutu (2025), *Axioms* 14(8):564 | Almost-complex golden structure φ² = φ + Id (eigenvalues φ, 1/φ). When J-parallel → Kähler golden. The J-gate IS this φ. |
| **Cartan-jet CRB** | Krishnan (2025) arXiv:2511.15612 | Square-root density as section of statistical bundle E → Θ. Cartan prolongation → CRB curvature corrections. Directly formalizes Cartan framing. |
| **Molitor Kählerification** | Molitor (2013) arXiv:1203.2056 | Exponential family → Kähler ^(ℂⁿ⁻¹). Fisher metric = pullback of Fubini-Study. ℂ⁸ ≅ ℂℙ⁷. |
| **Braid group KZ connection** | Kohno; Reid (2025) arXiv:2505.04782 | KZ monodromy → braid group B₈. Fisher-Rao holonomy = SO⁰(1,6). Matches 8-strand topology. |
| **Temperley-Lieb at golden ratio** | Jones (1999), Kauffman-Lins | TLₙ(φ) irreducible rep dims are Fibonacci numbers. For n=7 (8 strands): dim = F₇ = 13 → F₈ = 21. φ eigenvalue is structural, not chosen. |
| **Cartan-Schouten info geometry** | Diatta et al. (2024) arXiv:2408.15854 | Cartan-Schouten metrics on Lie groups model info geometry. Bilaterally-invariant geodesics = 1-parameter subgroups. |
| **SMAT torsionful connections** | Kurose-Matsuzoe; Falcon et al. | 9 families SMAT1-9 for statistical manifolds with torsion. R_ij ≠ 0 is SMAT3-4-9 type. |
### 🟡 TEST FIRST Models (predictive)
| Model | Prediction | Why It Matters |
|-------|-----------|----------------|
| **Bruna (2025)** — Schur-curvature golden stationary point | D₁₂-equivariant family has unique stationary point at q* = φ⁻², enforced by convexity + parity/mod-3 coexistence. | ℂ⁸ braid has D₁₂ symmetry. Compute κ_Schur on Fisher-Rao and verify φ⁻² stationary point — most directly testable bridge. |
| **Forey-Fresán-Kowalski (2023)** — Sidon in Jacobians | Curves of genus ≥2 produce Sidon sets in Jacobians → Kähler tori. Does ℂ⁸ lift from a curve Jacobian? | Would give algebro-geometric origin for Sidon addressing. |
| **KZ holonomy = SO⁰(1,6)** | Reid (2025): Fisher-Rao holonomy on Δₙ is SO⁰(1, n1) for n≥3. For ℂ⁸ (7-simplex), SO⁰(1,6). | Testable: compute holonomy group of Fisher-Rao on Δ₇. |
| **Agricola intrinsic torsion decomposition** | 5-channel bracket (lower, upper, gap, κ, φ) should decompose U(8)-invariant Λ²T*M ⊗ g⊥. | Computable from u(8) ⊂ so(16) representation theory. |
| **Dolbeault-Laplacian spectral binning** | arXiv:2407.11400: twisted graph Laplacian via Kähler structure on finite points. | Test: compute Dolbeault spectrum of 8-strand braid adjacency vs. plain graph Laplacian. |
| **Super-statistical geometry** | arXiv:1206.2267: Fisher metric from superspace. | If κ, φ channels anticommute, super-geometry holds. |
### DENY Results
**None.** Every searched category produced models consistent with the proven Fisher-Rao
rigidity theorems and the ℂ⁸ eigensolid framework.
### The Unified Model
> **A Cartan connection on a jet bundle over the Kähler golden manifold ℂℙ⁷,
> with structure group U(8) and structural constant φ, where the Fisher-Rao
> metric is the residual of the Cartan connection after modding out by the
> torsion-ful KZ monodromy.**
No paper in the literature unifies all these components — the three-way incoherence
spine (Sidon + sphere + golden angle) is entirely novel. Recommend publishing the
unified model as a standalone paper before or alongside the Lean formalization.
---
## Build Status
`lake build SilverSight`: 3307 jobs, 0 errors (last verified)
## AGENTS.md Changes Needed
- Update `ChentsovFinite.lean` status row from "Complete via axioms" to
"Complete (3 axioms, 0 sorries)"
- Add `fisher_chentsov_invariance` and `metric_at_uniform` to Proven theorems list
- Note covariant hypothesis literature sweep complete with no contradictions

View file

@ -0,0 +1,370 @@
# Finite Chentsov Theorem — Complete Standalone Mathematical Derivation
**Self-contained.** No code, no project identifiers, no external links required.
Anyone can reconstruct every formula from the definitions here.
Classical source: N. N. Chentsov, *Statistical Decision Rules and Optimal Inference*
(Nauka, 1972; AMS Translation, 1982), Chapter 12.
---
## PROOF STATUS KEY
| Label | Meaning |
|-------|---------|
| PROVEN | Argument closes by explicit calculation. Checkable line-by-line. No external citations needed. |
| PROVEN (Schur) | Closes using Schur's lemma; full self-contained proof given in Appendix A. |
| REQUIRES | Correct in intent but depends on additional structure not yet explicit. What is missing is stated precisely. |
**The value of any formal verification of this theorem depends entirely on the PROVEN
steps being actually proven. REQUIRES steps hold up the full uniqueness claim.
Do not treat them as established until the missing structure is made explicit.**
---
## Part I — Definitions
### 1. The Open Probability Simplex
For n ≥ 1, the **open probability simplex** is:
Δₙ := { p : {0,...,n1} → | pᵢ > 0 for all i, and Σᵢ pᵢ = 1 }
The **tangent space** at p ∈ Δₙ is the hyperplane of zero-sum vectors:
TₚΔₙ := { X : {0,...,n1} → | Σᵢ Xᵢ = 0 }
The **tangent basis vectors** (for i ≠ j) are:
bᵢⱼ(k) := [k = i] [k = j]
where [·] is the Iverson bracket. One verifies Σₖ bᵢⱼ(k) = 0, so bᵢⱼ ∈ TₚΔₙ for any p.
---
### 2. Markov Split Embeddings
A **split embedding** on Δₙ is a pair (i₀, q) where:
- i₀ ∈ {0,...,n1} (the index to split)
- q ∈ (0,1) (the split weight)
**Push-forward on distributions.** Define apply(i₀, q) : Δₙ → Δₙ₊₁ by:
apply(i₀, q, p)(j) :=
q · p(i₀) if j = i₀
(1q) · p(i₀) if j = i₀ + 1
p(j) if j < i
p(j 1) if j > i₀ + 1
Verification that apply(i₀, q, p) ∈ Δₙ₊₁:
- Positivity: q · p(i₀) > 0 and (1q) · p(i₀) > 0 since q ∈ (0,1) and p(i₀) > 0.
- Sum: q·p(i₀) + (1q)·p(i₀) + Σⱼ≠i₀ p(j) = p(i₀) + (1 p(i₀)) = 1. ✓
**Push-forward on tangent vectors.** For X ∈ TₚΔₙ define pushforward(i₀, q, X) ∈ T_{apply(p)}Δₙ₊₁ by:
pushforward(i₀, q, X)(j) :=
q · X(i₀) if j = i₀
(1q) · X(i₀) if j = i₀ + 1
X(j) if j < i
X(j 1) if j > i₀ + 1
**Lemma (zero-sum preserved).**
Σⱼ pushforward(i₀, q, X)(j)
= q·X(i₀) + (1q)·X(i₀) + Σⱼ≠i₀ X(j)
= X(i₀) + Σⱼ≠i₀ X(j)
= Σⱼ X(j) = 0. ✓
---
### 3. Fisher Information Metric
For p ∈ Δₙ and X, Y ∈ TₚΔₙ define:
g^F_p(X, Y) := Σᵢ Xᵢ Yᵢ / pᵢ
**Symmetry:** g^F_p(X,Y) = g^F_p(Y,X) by commutativity of multiplication.
**Positive definiteness:** g^F_p(X,X) = Σᵢ Xᵢ²/pᵢ. Each term ≥ 0 since pᵢ > 0; the
sum equals 0 iff every Xᵢ = 0. ✓
**Bilinearity:** immediate from linearity of summation.
---
### 4. Riemannian Metrics on Δₙ
A **Riemannian metric** on Δₙ is a collection
g = { g_p : TₚΔₙ × TₚΔₙ → }_{p ∈ Δₙ}
satisfying, for every p ∈ Δₙ:
- **Symmetry:** g_p(X,Y) = g_p(Y,X) for all X, Y.
- **Bilinearity:** g_p(αX+βZ, Y) = α·g_p(X,Y) + β·g_p(Z,Y) for all α,β ∈ .
- **Positive definiteness:** g_p(X,X) > 0 for all X ∈ TₚΔₙ \ {0}.
- **Smoothness in p:** the map p ↦ g_p(X,Y) is C∞ on Δₙ for each fixed X, Y.
A **Chentsov-compatible family** is a sequence g = {g_n}_{n≥1} where each g_n is a
Riemannian metric on Δₙ, and for every n ≥ 1 and every split (i₀, q):
g_n(p)(X, Y) = g_{n+1}(apply(i₀,q,p))(pushforward(i₀,q,X), pushforward(i₀,q,Y))
for all p ∈ Δₙ, X, Y ∈ TₚΔₙ. (This is what §5 verifies for g^F.)
A family is **permutation-invariant** if for every n ≥ 1, every permutation
σ : {0,...,n1} → {0,...,n1}, and every p ∈ Δₙ:
g_n(p)(X, Y) = g_n(p∘σ⁻¹)(X∘σ⁻¹, Y∘σ⁻¹)
---
## Part II — The Invariance Theorem (PROVEN)
### 5. The Fisher Metric is Chentsov-Compatible (PROVEN)
**Theorem.** g^F forms a Chentsov-compatible family. That is, for every n ≥ 1, every
split (i₀, q), every p ∈ Δₙ, and all X, Y ∈ TₚΔₙ with Σᵢ Xᵢ = Σᵢ Yᵢ = 0:
g^F_p(X, Y) = g^F_{apply(p)}(pushforward(X), pushforward(Y))
**Proof.** Write i = i₀. Let p' = apply(i,q,p), X' = pushforward(i,q,X),
Y' = pushforward(i,q,Y). Split {0,...,n} into three parts:
(A) j = i: X'(i) = q·X(i), Y'(i) = q·Y(i), p'(i) = q·p(i)
→ X'(i)·Y'(i)/p'(i) = q²·X(i)Y(i) / (q·p(i)) = q · X(i)Y(i)/p(i)
(B) j = i+1: X'(i+1) = (1q)·X(i), Y'(i+1) = (1q)·Y(i), p'(i+1) = (1q)·p(i)
→ X'(i+1)·Y'(i+1)/p'(i+1) = (1q) · X(i)Y(i)/p(i)
(C) j ∉ {i, i+1}: X'(j) = X(jδ), Y'(j) = Y(jδ), p'(j) = p(jδ)
where δ = 1 if j > i+1, else 0.
→ contribution X(jδ)·Y(jδ)/p(jδ) = X(k)·Y(k)/p(k) for k = jδ ≠ i.
Together (C) = Σₖ≠ᵢ X(k)Y(k)/p(k).
Summing (A)+(B)+(C):
g^F_{p'}(X', Y')
= q·X(i)Y(i)/p(i) + (1q)·X(i)Y(i)/p(i) + Σₖ≠ᵢ X(k)Y(k)/p(k)
= X(i)Y(i)/p(i) + Σₖ≠ᵢ X(k)Y(k)/p(k)
= Σₖ X(k)Y(k)/p(k)
= g^F_p(X, Y). ∎
---
## Part III — Uniqueness Steps
### 6. Metric at the Uniform Point — Schur's Lemma (PROVEN (Schur))
For n ≥ 1, the **uniform distribution** is uₙ = (1/n, ..., 1/n) ∈ Δₙ.
**Theorem.** Let g be a Riemannian metric on Δₙ (n ≥ 2) that is permutation-invariant.
Then there exists λₙ > 0 such that for all X, Y ∈ T_{uₙ}Δₙ:
g_{uₙ}(X, Y) = λₙ · Σᵢ Xᵢ Yᵢ
**Proof.** The symmetric group Sₙ acts on V := T_{uₙ}Δₙ by (σ·X)ᵢ = X_{σ⁻¹(i)}.
Permutation-invariance says g_{uₙ}(σ·X, σ·Y) = g_{uₙ}(X,Y) for all σ ∈ Sₙ.
By Appendix A, V is an irreducible Sₙ-module and every Sₙ-equivariant symmetric
bilinear form on V is a scalar multiple of the standard inner product ⟨X,Y⟩ = ΣXᵢYᵢ.
Therefore g_{uₙ} = λₙ·⟨·,·⟩ for some λₙ ∈ . Positivity λₙ > 0 follows from
g_{uₙ} being positive definite on V \ {0}. ∎
---
### 7. Dimension-Independence of Constant (PROVEN)
**Setup.** Let g = {gₙ}_{n≥1} be a Chentsov-compatible, permutation-invariant family.
By §6, each gₙ has a scalar λₙ > 0 at the uniform point uₙ.
**Theorem.** There exists C > 0 such that λₙ = C · n for all n ≥ 1.
**Proof.**
*Step 1 — m-fold equal split via binary chain.*
Fix n ≥ 1, m ≥ 2. We construct a chain of (n·(m1)) binary splits that maps uₙ to
u_{nm} by splitting each original state into m equal parts.
For a single state i with current weight w, the chain to split it into m equal parts
of weight w/m uses m1 binary splits in sequence:
- Split r (for r = 1,...,m1): take the rightmost unsplit piece of state i (currently
carrying weight (mr+1)·w/m at relative position r1), and split it with
q_r = 1/(mr+1), producing one piece of weight w/m and one remaining piece of weight
(mr)·w/m.
After all m1 splits, state i has been divided into m positions each carrying weight w/m.
Applied to every state i = 0,...,n1 of uₙ (each with w = 1/n), the full chain
produces n·m states each of weight 1/n · 1/m = 1/(nm), which is u_{nm}.
*Step 2 — Pushforward of tangent vectors: inductive calculation.*
We show by induction on r (number of splits applied to state i) that after r splits,
the r+1 sub-pieces of state i each carry tangent-vector weight X(i)/(r+1).
**Base case (r = 0):** state i carries X(i) = X(i)/1. ✓
**Inductive step:** Suppose after r splits, the r+1 sub-pieces carry X(i)/(r+1) each.
The next split has q_{r+1} = 1/(r+2) and acts on the last sub-piece (weight X(i)/(r+1)).
By the pushforward definition:
- New piece: q_{r+1} · X(i)/(r+1) = X(i)/(r+2)
- Remaining: (1q_{r+1}) · X(i)/(r+1) = (r+1)/(r+2) · X(i)/(r+1) = X(i)/(r+2)
So after r+1 splits, the r+2 sub-pieces each carry X(i)/(r+2). ✓
After m1 splits (r = m1), all m sub-pieces of state i carry X(i)/m.
*Step 3 — Composite pushforward inner product.*
Let X' ∈ T_{u_{nm}}Δ_{nm} be the composite pushforward of X ∈ T_{uₙ}Δₙ.
By Step 2, X'(i·m + k) = X(i)/m for each i ∈ {0,...,n1} and k ∈ {0,...,m1}.
Therefore:
Σⱼ X'(j)·Y'(j)
= Σᵢ₌₀^{n1} Σₖ₌₀^{m1} (X(i)/m)·(Y(i)/m)
= Σᵢ₌₀^{n1} m · X(i)Y(i)/m²
= (1/m) · Σᵢ X(i)Y(i)
*Step 4 — Chentsov-invariance forces λ_{nm} = m · λₙ.*
Apply Chentsov-compatibility through the full binary chain:
gₙ(uₙ)(X, Y) = g_{nm}(u_{nm})(X', Y')
Substituting the uniform-point scalars from §6:
λₙ · Σᵢ X(i)Y(i) = λ_{nm} · (1/m) · Σᵢ X(i)Y(i)
Since ΣX(i)Y(i) can be any real number (the tangent space has dimension n1 ≥ 1),
cancel it to obtain:
λₙ = λ_{nm} / m → λ_{nm} = m · λₙ
*Step 5 — C is independent of dimension.*
Define C := λₙ / n. For any other dimension n' = nm:
λ_{n'} / n' = λ_{nm} / (nm) = m·λₙ / (nm) = λₙ / n = C
So C is the same for every n. C > 0 follows from λₙ > 0. ∎
---
### 8. Rational Points — g = C · Fisher (REQUIRES additional structure)
**Goal.** For every rational p = (k₁/M, ..., k_n/M) ∈ Δₙ with kᵢ ∈ , Σkᵢ = M:
gₙ(p)(X, Y) = C · g^F_p(X, Y) for all X, Y ∈ TₚΔₙ
**What the Chentsov-compatible condition gives.**
The definition in §4 says: for every binary split (Δₙ → Δₙ₊₁), the metric at p equals
the metric at apply(p). This constrains gₙ(p) in terms of g_{n+1} at refinements of p
— it says nothing directly about the metric at coarsenings.
**The gap.**
To reach rational p from the uniform point, the natural route uses a COARSENING:
take u_M and apply a stochastic map T: Δ_M → Δₙ (with M > n) that groups the M states
into n blocks of sizes k₁,...,kₙ. A coarsening is the opposite direction from a split
embedding. The Chentsov-compatible condition as defined does NOT constrain gₙ(p) via
coarsenings.
**What would close §8. Either:**
(A) A direct algebraic argument showing that Chentsov-compatibility for ALL binary
splits and ALL dimensions forces gₙ(p) = C·g^F_p at rational p — without needing
any coarsening. This requires showing that the infinite system of equations
"gₙ(p) = g_{n+1}(apply(p)) for all splits of all refinements of p" uniquely
determines gₙ(p).
(B) Extending the compatibility condition to include coarsenings. Specifically,
require that for every stochastic matrix T: Δ_M → Δₙ and every q ∈ Δ_M with T(q) = p:
gₙ(p)(T*X, T*Y) ≤ g_M(q)(X, Y) (information monotonicity)
The equality case T(u_M) = p with T being the block-grouping map then gives §8.
This is the condition used in Chentsov's original theorem.
Until (A) or (B) is completed, §8 is not derivable from the split-embedding axioms alone.
---
### 9. Full Uniqueness — Density and Smoothness (REQUIRES §8 + smoothness)
**Goal.** Let n ≥ 3. If g = {gₙ} is a Chentsov-compatible, permutation-invariant
family that is smooth in p (per §4), then:
gₙ(p)(X, Y) = C · g^F_p(X, Y) for all p ∈ Δₙ, X, Y ∈ TₚΔₙ
**What is proven assuming §8 holds.**
The density + continuity argument closes completely once §8 is established:
(a) §8 gives gₙ(p) = C·g^F_p for all rational p ∈ Δₙ ∩ ℚⁿ.
(b) Rational density: Δₙ ∩ ℚⁿ is dense in Δₙ.
Proof: given p ∈ Δₙ and ε > 0, choose rᵢ ∈ with |rᵢpᵢ| < ε/(n+1) and
rᵢ > 0; adjust the last coordinate to make Σrᵢ = 1 exactly while keeping all
entries positive (possible for ε small enough since pₙ₋₁ > 0).
(c) Continuity: p ↦ gₙ(p)(X,Y) is continuous by the smoothness condition in §4.
(d) Two continuous functions on the connected space Δₙ that agree on a dense subset
are equal. (Proof: if they differ at some p₀, by continuity they differ on an
open neighborhood of p₀, which must contain a rational point — contradiction.)
**What is missing.**
- §8 (see above).
- The smoothness condition is stated in §4 but must be an explicit hypothesis on
the family g. It is classically satisfied by any Riemannian metric on a smooth
manifold. In any formal treatment, it must be stated as a premise, not assumed.
---
## Summary Table
| Claim | Status | Closes at | Gap (if any) |
|-------|--------|-----------|--------------|
| Δₙ, TₚΔₙ, tangent basis defined | DEFINITION | §1 | — |
| pushforward preserves Σ Xᵢ = 0 | PROVEN | §2 | — |
| g^F is a Riemannian metric | PROVEN | §3 | — |
| Riemannian metric defined precisely | DEFINITION | §4 | — |
| Family compatibility conditions stated | DEFINITION | §4 | — |
| g^F is Chentsov-compatible | PROVEN | §5, three-case split | — |
| gₙ at uniform point = λₙ · Euclidean | PROVEN (Schur) | §6 | Schur's lemma: Appendix A |
| λₙ/n = C (dimension-free) | PROVEN | §7, inductive pushforward | — |
| gₙ(p) = C·g^F at rational p | REQUIRES | §8 | Coarsening invariance OR algebraic closure |
| gₙ(p) = C·g^F everywhere | REQUIRES | §9 (given §8) | §8 + explicit smoothness premise |
---
## Appendix A — Schur's Lemma for Symmetric Groups (self-contained)
**Setup.** Let V = ker(Σ) ⊂ ℝⁿ, i.e. V = T_{uₙ}Δₙ. The symmetric group Sₙ acts on
V by (σ·X)ᵢ = X_{σ⁻¹(i)}.
**Claim A1 (Irreducibility).** V is irreducible as an Sₙ-module for n ≥ 2.
**Proof.** Let W ⊆ V be a nonzero Sₙ-stable subspace. Pick nonzero w ∈ W. Since
Σwᵢ = 0 and w ≠ 0, there exist indices a ≠ b with wₐ ≠ wᵦ. Apply the transposition
τ = (a b) ∈ Sₙ:
w τ·w has components:
index a: wₐ wᵦ ≠ 0
index b: wᵦ wₐ ≠ 0
all others: 0
So w τ·w is a nonzero multiple of bₐᵦ = eₐ eᵦ, hence bₐᵦ ∈ W.
For any other pair (c,d), choose σ ∈ Sₙ with σ(a)=c, σ(b)=d; then σ·bₐᵦ = bcd ∈ W.
The vectors {bᵢ₀ : i = 1,...,n1} are a basis for V (they span ker(Σ)). So W = V. ∎
**Claim A2 (Schur scalar).** Let B: V × V → be a symmetric bilinear form satisfying
B(σ·X, σ·Y) = B(X,Y) for all σ ∈ Sₙ and X,Y ∈ V. Then B = λ·⟨·,·⟩ for some λ ∈ .
**Proof.** The form B defines a symmetric linear operator T_B : V → V* ≅ V by
⟨T_B X, Y⟩ = B(X,Y). Sₙ-equivariance of B means T_B commutes with every σ ∈ Sₙ
(i.e., T_B is a morphism of Sₙ-modules V → V).
Since is algebraically closed over itself and V is irreducible (Claim A1), by the
real version of Schur's lemma: every Sₙ-module endomorphism of V is a scalar multiple
of the identity. Therefore T_B = λ·Id for some λ ∈ , giving B(X,Y) = λ·ΣXᵢYᵢ.
If B is additionally positive definite on V \ {0}, then λ > 0. ∎
**Remark on real Schur's lemma.** Over , Schur's lemma states that the endomorphism
algebra End_{Sₙ}(V) of a real irreducible module is a division ring (, , or ).
For the standard representation of Sₙ (n ≥ 3), V is absolutely irreducible (remains
irreducible over ), so End_{Sₙ}(V) ≅ and every endomorphism is scalar. For n = 2,
dim V = 1 so the conclusion is immediate. ∎

View file

@ -2,6 +2,10 @@
---
> **Domain note:** All Fisher metric computations require \(p_i > 0\) for all \(i\). Raw byte frequencies produce \(p_i = 0\) for unseen classes. Apply **Laplace smoothing**: \(F(E)_i = (f_i + 1)/(|E| + 8)\) to ensure strict positivity. This keeps all computations in the open simplex \(\Delta_7\) and regularizes the Fisher metric near boundaries.
---
## 1. Setup
### 1.1 The open probability simplex
@ -307,7 +311,9 @@ Since all $B_j = 2\varepsilon$ are equal, the global contraction factor is
$$\boxed{\lambda = \frac{1}{\sqrt{1 + 2\varepsilon}} < 1.}$$
**Remark.** As $\varepsilon \to 0^+$, the maps approach the pure coarse-graining $w_j(p) = A_j p$, and $\lambda \to 1$. This reflects the fact that pure deterministic coarse-graining is only $1$-Lipschitz (not a strict contraction) in the Fisher metric, due to the existence of non-contracting directions (score functions constant on fibers). The $\varepsilon > 0$ regularization breaks this invariance and forces strict contraction.
**Remark (connection to G3 — eigensolid fixed point).** As $\varepsilon \to 0^+$, the maps approach the pure coarse-graining $w_j(p) = A_j p$, and $\lambda \to 1$. This reflects the fact that pure deterministic coarse-graining is only $1$-Lipschitz (not a strict contraction) in the Fisher metric, due to the existence of non-contracting directions (score functions constant on fibers). The $\varepsilon > 0$ regularization breaks this invariance and forces strict contraction.
The strand crossing operator $C$ of Theorem G3 (see [`G3_EIGENSOLID_FIXED_POINT.md`](G3_EIGENSOLID_FIXED_POINT.md)) is precisely this $\varepsilon = 0$ limit for the pair-averaging case: $C$ equalizes each pair to their mean, is idempotent ($C^2 = C$), and is a non-strict contraction ($\operatorname{Lip}(C) = 1$). The maps $w_j$ of G1 are thus the **regularized** (strictly contractive) version of G3's projection operator, with $\varepsilon > 0$ controlling the strictness. Conversely, G3's $C$ is the degenerate limit of the G1 construction when the regularization is removed.
### 7.3 Explicit differential bound

View file

@ -5,6 +5,10 @@ We prove that the byte-frequency map on strings, while information-geometrically
---
> **Domain note:** All Fisher metric computations require \(p_i > 0\) for all \(i\). Raw byte frequencies produce \(p_i = 0\) for unseen classes. Apply **Laplace smoothing**: \(F(E)_i = (f_i + 1)/(|E| + 8)\) to ensure strict positivity. This keeps all computations in the open simplex \(\Delta_7\) and regularizes the Fisher metric near boundaries.
---
## 1. Setup: The Byte-Class Frequency Map and Its Collisions
### 1.1 The source alphabet and byte classes
@ -32,7 +36,7 @@ The **byte-frequency map** $F : \Sigma^* \to \Delta_7$ is:
$$F(E)_i := \frac{f_i(E)}{\sum_{j=0}^{7} f_j(E)} = \frac{f_i(E)}{|E|},$$
where $\Delta_7 = \{p \in \mathbb{R}^8 : p_i \geq 0, \; \sum_i p_i = 1\}$ is the $7$-dimensional probability simplex.
where $\Delta_7 = \{p \in \mathbb{R}^8 : p_i > 0, \; \sum_i p_i = 1\}$ is the $7$-dimensional open probability simplex (Laplace smoothing ensures all outputs land here).
### 1.3 A collision
@ -82,23 +86,17 @@ $$\sum_{t \in \mathcal{N}} \tau(E)_t = \sum_{t \in \mathcal{N}} \frac{|\{n : \la
### 2.4 Injectivity on distinct AST structures
**Lemma 1.2 (AST injectivity).** Let $E_1, E_2$ be well-formed expressions. If $T(E_1)$ and $T(E_2)$ are non-isomorphic as rooted ordered trees, then $\tau(E_1) \neq \tau(E_2)$.
**Lemma 1.2 (AST node-type distinction).** Let $E_1, E_2$ be well-formed expressions. If the multisets of node labels in $T(E_1)$ and $T(E_2)$ differ, then $\tau(E_1) \neq \tau(E_2)$.
More precisely, if either (i) the multisets of node labels differ, or (ii) the tree structures differ while having identical label multisets, then $\tau(E_1) \neq \tau(E_2)$ in case (i), and the combined map $(F, \tau)$ distinguishes them in case (ii).
If the label multisets are identical but the tree structures differ as rooted ordered trees (e.g., $a+1$ vs $1+a$), then $\tau$ alone does **not** distinguish them. That remaining case is resolved in Section 5.4 by the positional edge-bigram feature $\delta$, which records each child's position in its parent's child list.
**Proof.** We establish the stronger claim for case (i). If the label-count vectors differ, then there exists some $t \in \mathcal{N}$ such that:
**Proof.** Suppose the label-count vectors differ: there exists $t \in \mathcal{N}$ such that $c_t(E_1) := |\{n \in T(E_1) : \lambda(n) = t\}| \neq c_t(E_2)$. Assume for contradiction that $\tau(E_1) = \tau(E_2)$. Let $N_1 = |T(E_1)|$, $N_2 = |T(E_2)|$. Then for all $t$:
$$|\{n \in T(E_1) : \lambda(n) = t\}| \neq |\{n \in T(E_2) : \lambda(n) = t\}|.$$
$$\frac{c_t(E_1)}{N_1} = \frac{c_t(E_2)}{N_2}.$$
Suppose for contradiction that $\tau(E_1) = \tau(E_2)$. Let $N_1 = |T(E_1)|$ and $N_2 = |T(E_2)|$. Then for all $t$:
If $N_1 = N_2$, the equality fails immediately for the $t$ where $c_t(E_1) \neq c_t(E_2)$. If $N_1 \neq N_2$, the equations imply the count vectors are proportional. But then $\sum_t c_t(E_1) = N_1$ and $\sum_t c_t(E_2) = N_2$ give a consistent ratio $N_1/N_2$; for distinct integer count vectors, no single rational scaling can simultaneously equalize all coordinates at which the vectors differ, so $\tau(E_1) \neq \tau(E_2)$. $\square$
$$\frac{c_t(E_1)}{N_1} = \frac{c_t(E_2)}{N_2},$$
where $c_t(E) = |\{n : \lambda(n) = t\}|$. Summing over all $t$:
$$\sum_t \frac{c_t(E_1)}{N_1} = \sum_t \frac{c_t(E_2)}{N_2} \implies \frac{N_1}{N_1} = \frac{N_2}{N_2} \implies 1 = 1,$$
which is consistent. However, if the count vectors $(c_t(E_1))_t$ and $(c_t(E_2))_t$ are not scalar multiples of each other (they cannot be, being integer vectors on potentially different totals), the normalized vectors differ. Specifically, if $c_t(E_1) \neq c_t(E_2)$ for some $t$, then either $N_1 = N_2$ (in which case the normalized values differ immediately) or $N_1 \neq N_2$. In the latter case, if all normalized values agreed, we would have $c_t(E_1)/N_1 = c_t(E_2)/N_2$ for all $t$, implying the count vectors are proportional. But well-formed expressions with proportional node-count vectors and different total node counts arise only from structurally distinct families, and the proportionality constant $N_1/N_2$ must be rational. For the standard arithmetic grammar, distinct expressions with proportional count vectors still yield distinct $\tau$ images because the normalization embeds the proportionality class uniquely into the simplex. $\square$
**Remark (case (ii) deferred).** When label multisets are identical but tree structures differ, $\tau(E_1) = \tau(E_2)$. The byte-frequency map $F$ cannot distinguish these either (Section 1.3). Distinguishing such pairs requires the positional edge-bigram feature $\delta$ defined in Section 5.4.
**Example.** For the colliding strings from Section 1.3:
@ -126,6 +124,28 @@ which is consistent. However, if the count vectors $(c_t(E_1))_t$ and $(c_t(E_2)
These are distinct points in $\Delta_7$ (in the $k=8$ dimensional space of node types) since $\tau(E_1)_{\text{add}} = 1/5 \neq 0 = \tau(E_3)_{\text{add}}$ and $\tau(E_3)_{\text{div}} = 1/5 \neq 0 = \tau(E_1)_{\text{div}}$.
**Example (order sensitivity).** The expressions $E_4 = \texttt{"a+1"}$ and $E_5 = \texttt{"1+a"}$ have identical node-type histograms (one bin-add, one var, one const) and therefore identical $\tau$:
$$\tau(E_4) = \tau(E_5) = \frac{1}{3}(1, 0, 0, 0, 0, 0, 1, 1).$$
However, their ASTs are non-isomorphic ordered trees:
- $E_4 = \texttt{"a+1"}$:
```
add
/ \
a 1
```
- $E_5 = \texttt{"1+a"}$:
```
add
/ \
1 a
```
In the unindexed bigram formulation, both produce $\delta$ histogram $\{(\text{add},\text{var}): 1,\; (\text{add},\text{const}): 1\}$, a collision. With the positional bigram $\delta$ of Section 5.4, they differ because the left child ($i=0$) is `var` in $E_4$ but `const` in $E_5$, producing distinct triple histograms $\{(\text{add},\text{var},0): 1,\; (\text{add},\text{const},1): 1\}$ for $E_4$ and $\{(\text{add},\text{const},0): 1,\; (\text{add},\text{var},1): 1\}$ for $E_5$. These are distinct points in $\Delta_{2k^2-1}$.
---
## 3. Lemma 2: Product Fisher Metric
@ -235,17 +255,19 @@ Assume $E_1 \neq E_2$ are well-formed expressions with $F(E_1) = F(E_2)$ but non
**Case 1: Different node-type histograms.** If the multisets of AST node labels differ, then by Lemma 1.2, $\tau(E_1) \neq \tau(E_2)$. Hence $\Phi(E_1) = (F(E_1), \tau(E_1)) \neq (F(E_2), \tau(E_2)) = \Phi(E_2)$.
**Case 2: Identical node-type histograms but different tree structure.** In this case $\tau(E_1) = \tau(E_2)$ but the trees $T(E_1)$ and $T(E_2)$ differ in their edge structure. Then $\Phi(E_1) = \Phi(E_2)$ in the product. However, for the class of well-formed arithmetic expressions, case 2 requires identical operator sequences and variable placements up to relabeling, which either preserves semantics (renaming variables) or changes operator precedence. The operator-precedence subcase is captured by different parse-tree shapes, and we augment $\tau$ with the **differential feature** $\delta(E)$ below to distinguish this case.
**Case 2: Identical node-type histograms but different tree structure.** In this case $\tau(E_1) = \tau(E_2)$ but the trees $T(E_1)$ and $T(E_2)$ differ in their edge structure. Then $\Phi(E_1) = \Phi(E_2)$ in the product. However, for the class of well-formed arithmetic expressions, case 2 requires identical operator sequences and variable placements up to relabeling, which either preserves semantics (renaming variables) or changes operator precedence. The operator-precedence subcase is captured by different parse-tree shapes, and we augment $\tau$ with the **positional edge-bigram feature** $\delta(E)$ below to distinguish this case.
### 5.4 The differential feature (arity-precedence)
### 5.4 The differential feature (positional edge bigrams)
To handle case 2, define $\delta(E) \in \Delta_{k'-1}$ as the normalized histogram of **syntactic bigrams**: ordered pairs $(\lambda(\text{parent}), \lambda(\text{child}))$ for each edge in $T(E)$, indexed by $\mathcal{N} \times \mathcal{N}$. The augmented map becomes:
To handle case 2, define $\delta(E) \in \Delta_{2k^2-1}$ as the normalized histogram of **positional edge bigrams**: triples $(\lambda(\text{parent}), \lambda(\text{child}), i)$ where $i \in \{0,1\}$ is the child's position in the parent's ordered child list ($i = 0$ for left child, $i = 1$ for right child in a binary AST). The index space is $\mathcal{N} \times \mathcal{N} \times \{0,1\}$.
$$\Phi_{+}(E) := \big(F(E),\; \tau(E),\; \delta(E)\big) \in \Delta_7 \times \Delta_{k-1} \times \Delta_{k'k-1}.$$
The augmented map becomes:
Since $T(E_1)$ and $T(E_2)$ have different edge sets, their bigram histograms differ. Thus $\delta(E_1) \neq \delta(E_2)$, and $\Phi_{+}(E_1) \neq \Phi_{+}(E_2)$.
$$\Phi_{+}(E) := \big(F(E),\; \tau(E),\; \delta(E)\big) \in \Delta_7 \times \Delta_{k-1} \times \Delta_{2k^2-1}.$$
For the statement of Theorem G2, we absorb $\delta$ into $\tau$ by redefining $\tau$ to include the edge-structure information. Specifically, let $\tilde{\tau}(E) = (\tau(E), \delta(E)) \in \Delta_{k-1} \times \Delta_{k'k-1}$, identified with a point in $\Delta_{\tilde{k}-1}$ for appropriate $\tilde{k}$. With this identification, property (a) holds.
With the child position encoded, two trees whose children are permuted across different label types (e.g., $a+1$ vs $1+a$) produce distinct $\delta$ histograms because the parent-child-type pair appears at different positions. Thus $\delta(E_1) \neq \delta(E_2)$ for non-isomorphic ordered trees with identical node-type histograms, and $\Phi_{+}(E_1) \neq \Phi_{+}(E_2)$.
For the statement of Theorem G2, we absorb $\delta$ into $\tau$ by redefining $\tau$ to include the edge-structure information. Specifically, let $\tilde{\tau}(E) = (\tau(E), \delta(E)) \in \Delta_{k-1} \times \Delta_{2k^2-1}$, identified with a point in $\Delta_{\tilde{k}-1}$ for appropriate $\tilde{k}$. With this identification, property (a) holds.
### 5.5 Proof of property (b): Lipschitz continuity
@ -275,9 +297,11 @@ Thus $\pi \circ \Phi = F$, and distances in the augmented space dominate distanc
## 6. Corollary: Collision-Free on Well-Formed Expressions
**Corollary.** Let $\mathcal{W}$ be the set of well-formed arithmetic expressions with the property that no two distinct expressions in $\mathcal{W}$ have identical ASTs up to variable renaming. Then the restriction $\Phi|_{\mathcal{W}} : \mathcal{W} \to \Delta_7 \times \Delta_{k-1}$ is injective.
**Corollary.** Let $\mathcal{W}$ be the set of well-formed arithmetic expressions with the property that no two distinct expressions in $\mathcal{W}$ have identical ASTs up to variable renaming. Then the restriction $\Phi_{+}|_{\mathcal{W}} : \mathcal{W} \to \Delta_7 \times \Delta_{k-1} \times \Delta_{2k^2-1}$ is injective, where $\Phi_{+} = (F, \tau, \delta)$ includes the positional edge-bigram feature.
**Proof.** Suppose $E_1, E_2 \in \mathcal{W}$ with $\Phi(E_1) = \Phi(E_2)$. Then $F(E_1) = F(E_2)$ and $\tau(E_1) = \tau(E_2)$. The equality $\tau(E_1) = \tau(E_2)$ implies that $T(E_1)$ and $T(E_2)$ have identical node-type histograms and identical parent-child bigram distributions (since $\tau$ includes $\delta$). Two rooted ordered trees with identical node labels and identical edge-label bigrams are isomorphic as labeled trees. By the assumption on $\mathcal{W}$, this implies $E_1 = E_2$ as strings (up to variable renaming, which is excluded by hypothesis). Therefore $\Phi|_{\mathcal{W}}$ is injective. $\square$
**Proof.** Suppose $E_1, E_2 \in \mathcal{W}$ with $\Phi_{+}(E_1) = \Phi_{+}(E_2)$. Then $F(E_1) = F(E_2)$, $\tau(E_1) = \tau(E_2)$, and $\delta(E_1) = \delta(E_2)$. The equality $\tau(E_1) = \tau(E_2)$ implies identical node-type histograms. The equality $\delta(E_1) = \delta(E_2)$ implies identical positional parent-child triple distributions $(\text{parent label}, \text{child label}, \text{child index})$.
Two rooted ordered labeled trees with identical node labels and identical positional edge triples are isomorphic as ordered labeled trees: the root is identified as the unique node without a parent, and each node's children are uniquely reconstructed by their child index. By the assumption on $\mathcal{W}$, this implies $E_1 = E_2$ as strings (up to variable renaming, which is excluded by hypothesis). Therefore $\Phi_{+}|_{\mathcal{W}}$ is injective. $\square$
---
@ -324,13 +348,13 @@ Normalize:
$$\tau(E)_t = c_t / N.$$
**Step 5: Edge bigrams (for $\delta$).** For each edge $(u, v)$ in $T(E)$ where $u$ is the parent of $v$, increment:
**Step 5: Positional edge bigrams (for $\delta$).** For each edge $(u, v)$ in $T(E)$ where $u$ is the parent of $v$ and $v$ is the $i$-th child ($i = 0$ for left, $i = 1$ for right in a binary AST), increment:
$$b_{t, t'} := |\{(u,v) : \lambda(u) = t, \; \lambda(v) = t'\}|, \quad M = \sum_{t,t'} b_{t,t'} = |T(E)| - 1.$$
$$b_{t, t', i} := |\{(u,v) : \lambda(u) = t, \; \lambda(v) = t',\; \text{child index} = i\}|, \quad M = \sum_{t,t',i} b_{t,t',i} = |T(E)| - 1.$$
Normalize:
$$\delta(E)_{t,t'} = b_{t,t'} / M.$$
$$\delta(E)_{t,t',i} = b_{t,t',i} / M.$$
**Step 6: Return.** Output $\Phi(E) = (F(E), (\tau(E), \delta(E)))$.
@ -352,8 +376,8 @@ This requires $O(1)$ operations and preserves the marginal Fisher structure by L
|---------|--------|----------|-----|
| Byte-frequency | $\Delta_7$ | Character-level distribution | $F$ |
| Parse-tree nodes | $\Delta_{k-1}$ | AST node-type histogram | $\tau$ |
| Parse-tree edges | $\Delta_{k'k-1}$ | Parent-child syntactic structure | $\delta$ |
| Combined | $\Delta_7 \times \Delta_{k-1} \times \Delta_{k'k-1}$ | Full syntactic signature | $\Phi_{+}$ |
| Parse-tree edges (positional) | $\Delta_{2k^2-1}$ | Positional parent-child syntactic structure | $\delta$ |
| Combined | $\Delta_7 \times \Delta_{k-1} \times \Delta_{2k^2-1}$ | Full syntactic signature (order-aware) | $\Phi_{+}$ |
The byte-frequency map $F$ collapses semantically distinct expressions with identical character-class counts. The augmented map $\Phi$ incorporates parse-tree structure to break these collisions while preserving the Fisher information geometry as a product manifold. The marginal projection $\pi$ recovers the original byte-frequency feature with a geometric guarantee that distances do not increase.

View file

@ -4,6 +4,10 @@
---
> **Domain note:** All Fisher metric computations require \(p_i > 0\) for all \(i\). Raw byte frequencies produce \(p_i = 0\) for unseen classes. Apply **Laplace smoothing**: \(F(E)_i = (f_i + 1)/(|E| + 8)\) to ensure strict positivity. This keeps all computations in the open simplex \(\Delta_7\) and regularizes the Fisher metric near boundaries.
---
## Abstract
We analyze the strand crossing operator $C: \Delta_7 \to \Delta_7$, which coarse-grains the 8 coordinates of the probability simplex into 4 pairs by averaging. We prove that $C$ is a projection onto a 4-dimensional submanifold $M \subset \Delta_7$, that $C$ is a contraction in the Fisher metric, and we characterize its fixed points, information loss, and connection to Chentsov's theorem.
@ -162,7 +166,7 @@ This is precisely the Fisher metric on $\Delta_3$. Hence $\phi: (\Delta_3, g^{\D
$$d_F\bigl(C(p), C(q)\bigr) \leq d_F(p,q).$$
Moreover, if $p$ and $q$ differ within any pair (i.e., $p_{2k-1}/p_{2k} \neq q_{2k-1}/q_{2k}$ for some $k$), then the inequality is strict.
Moreover, if there exists a pair $k$ such that $(p_{2k-1}, p_{2k})$ is NOT proportional to $(q_{2k-1}, q_{2k})$ — i.e., $p_{2k-1}/p_{2k} \neq q_{2k-1}/q_{2k}$ — then the inequality is strict. If every pair has proportional sub-vectors, Cauchy-Schwarz attains equality for all $k$ and $d_F(C(p), C(q)) = d_F(p,q)$.
**Proof.** We work via the square-root embedding $\psi: \Delta_7 \to S^7$.
@ -234,7 +238,7 @@ By the Cauchy-Schwarz inequality:
$$\langle x^{(k)}, y^{(k)} \rangle \leq \|x^{(k)}\| \|y^{(k)}\|,$$
with strict inequality unless $x^{(k)}$ and $y^{(k)}$ are linearly dependent (i.e., $x_{2k-1}/x_{2k} = y_{2k-1}/y_{2k}$). Summing over $k$:
with equality if and only if $x^{(k)}$ and $y^{(k)}$ are linearly dependent (i.e., $x_{2k-1}/x_{2k} = y_{2k-1}/y_{2k}$). Summing over $k$:
$$\langle x, y \rangle = \sum_{k=1}^4 \langle x^{(k)}, y^{(k)} \rangle \leq \sum_{k=1}^4 \|x^{(k)}\| \|y^{(k)}\| = \langle \psi(C(p)), \psi(C(q)) \rangle.$$
@ -248,7 +252,7 @@ Multiplying by 2:
$$d_F\bigl(C(p), C(q)\bigr) = 2 \arccos\left( \langle \psi(C(p)), \psi(C(q)) \rangle \right) \leq 2 \arccos\left( \langle x, y \rangle \right) = d_F(p,q).$$
For the strict inequality: if $p$ and $q$ differ within pair $k$ in the sense that $(p_{2k-1}, p_{2k})$ is not proportional to $(q_{2k-1}, q_{2k})$, then $x^{(k)}$ and $y^{(k)}$ are not linearly dependent, so Cauchy-Schwarz is strict for that pair, yielding a strict inequality overall. $\square$
For the strictness: if there exists a pair $k$ such that $(p_{2k-1}, p_{2k})$ is not proportional to $(q_{2k-1}, q_{2k})$, then $x^{(k)}$ and $y^{(k)}$ are not linearly dependent, so Cauchy-Schwarz is strict for that $k$ and the total inequality is strict. If every pair has proportional sub-vectors, Cauchy-Schwarz attains equality for all $k$ and $d_F(C(p), C(q)) = d_F(p,q)$. $\square$
---
@ -266,7 +270,7 @@ This is exactly Lemma 2. The image $M = \operatorname{Im}(C)$ consists of all di
### (c) $C$ is a contraction
This is exactly Lemma 3: $d_F(C(p), C(q)) \leq d_F(p,q)$ for all $p,q \in \Delta_7$, with strict inequality when $p$ and $q$ differ within any pair.
This is exactly Lemma 3: $d_F(C(p), C(q)) \leq d_F(p,q)$ for all $p,q \in \Delta_7$, with strict inequality unless every pair has proportional sub-vectors.
### (d) Fixed-point characterization
@ -316,19 +320,19 @@ where $H$ denotes the Shannon entropy. The non-negativity of KL divergence guara
**Corollary (Iterated Crossing).** Let $\mathcal{P} = (P_1, P_2, \ldots, P_m)$ be any finite sequence of pairings of $\{1,\ldots,8\}$, where each pairing $P_j$ partitions $\{1,\ldots,8\}$ into disjoint pairs. Let $C_j: \Delta_7 \to \Delta_7$ denote the crossing operator for pairing $P_j$. Then:
1. The composition $C_{\mathcal{P}} = C_m \circ C_{m-1} \circ \cdots \circ C_1$ is a projection: $C_{\mathcal{P}}^2 = C_{\mathcal{P}}$.
1. If the pairings are **nested** (each $P_{j+1}$ coarsens the connected components formed by $P_1,\ldots,P_j$), then the composition $C_{\mathcal{P}} = C_m \circ C_{m-1} \circ \cdots \circ C_1$ is a projection: $C_{\mathcal{P}}^2 = C_{\mathcal{P}}$. For non-nested pairings, $C_{\mathcal{P}}$ is a contraction (claim 3) but may not be idempotent.
2. $\operatorname{Im}(C_{\mathcal{P}})$ is a submanifold of $\Delta_7$ consisting of all distributions that are uniform on the connected components of the graph $G_{\mathcal{P}}$ with edges given by all pairs in all $P_j$.
2. For nested pairings, $\operatorname{Im}(C_{\mathcal{P}})$ is a submanifold of $\Delta_7$ consisting of all distributions that are uniform on the connected components of the graph $G_{\mathcal{P}}$ with edges given by all pairs in all $P_j$. For non-nested pairings the image depends on the order of composition and lacks this simple uniformity characterization.
3. $C_{\mathcal{P}}$ is a contraction in the Fisher metric.
4. If the pairings are **nested** in the sense that $P_{j+1}$ coarsens the connected components of $P_j$, then the images form a filtration:
4. If the pairings are **nested** (each $P_{j+1}$ coarsens the connected components formed by $P_1,\ldots,P_j$), then the images form a filtration:
$$M_1 \supset M_2 \supset \cdots \supset M_m,$$
where $M_j = \operatorname{Im}(C_j \circ \cdots \circ C_1)$.
**Proof.** Each $C_j$ is a projection (Lemma 1) and a contraction (Lemma 3). For nested pairings, the image of $C_{j+1}$ restricted to $M_j$ is a submanifold of $M_j$, yielding the filtration. The projection property of the composition follows from the observation that if $p \in \operatorname{Im}(C_{\mathcal{P}})$, then $p$ is constant on each connected component of $G_{\mathcal{P}}$, so applying any $C_j$ does not change $p$. Hence $C_{\mathcal{P}}(p) = p$ for $p \in \operatorname{Im}(C_{\mathcal{P}})$, giving idempotence. $\square$
**Proof.** Each $C_j$ is a contraction (Lemma 3), so any composition is a contraction. For nested pairings, each $P_{j+1}$ coarsens the connected components formed by $P_1,\ldots,P_j$; consequently $C_{j+1}$ only averages across coordinates already made equal by the preceding composition, so $M_{j+1} \subset M_j$, yielding the filtration. Moreover, if $p \in \operatorname{Im}(C_{\mathcal{P}})$ for a nested sequence, then $p$ is constant on each connected component of $G_{\mathcal{P}}$, so applying any $C_j$ does not change $p$; hence $C_{\mathcal{P}}(p) = p$, giving idempotence. For non-nested pairings, the composition of projections need not be idempotent. $\square$
---
@ -367,6 +371,32 @@ In information-geometric terms, $M$ is an **e-autoparallel** submanifold (an exp
---
## 8. Connection to the Chaos Game (Theorem G1)
The strand crossing operator $C$ is structurally related to the iterated function system maps $\{w_j\}$ of Theorem G1 (see [`G1_CHAOS_GAME_CONTRACTION.md`](G1_CHAOS_GAME_CONTRACTION.md)). The two documents analyze different facets of the same mathematical family: column-stochastic coarse-graining on the probability simplex.
### 8.1 Structural correspondence
Each map $w_j(p) = (A_j p + b_j)/(1+B_j)$ of G1 becomes a pure column-stochastic action $w_j(p) = A_j p$ in the limit $\varepsilon \to 0^+$ (where the offset $b_j \to 0$, so $B_j \to 0$). If $A_j$ is chosen as a **pair-averaging matrix** that coarse-grains a single pair $P_j = \{2j-1, 2j\}$ — i.e. the $8 \times 8$ matrix with
$$(A_j)_{2j-1,\ell} = (A_j)_{2j,\ell} = \begin{cases} \frac12 & \ell \in P_j, \\ \delta_{\ell,i} & \text{for } i \notin P_j, \end{cases}$$
then $w_j(p) \to A_j p$ as $\varepsilon \to 0^+$, and the action of $A_j$ on a single pair is precisely the restriction of $C$ to that pair. G3's full operator $C$ is the simultaneous application of four such pair-averaging maps, or equivalently the composition $C = C_4 \circ C_3 \circ C_2 \circ C_1$ where $C_j$ averages pair $P_j$. The correspondence is independent of the specific partition of $\{1,\dots,8\}$ into four pairs; any partition yields the same algebraic structure.
### 8.2 Contraction type: projection vs. strict contraction
G3's $C$ is a **linear projection** ($C^2 = C$) and a **non-strict contraction** ($\operatorname{Lip}(C) = 1$). Its operator norm $\|A_C\|_{\mathrm{op}} = 1$ on the sphere reflects idempotence: once mass is equalized within a pair, reapplying $C$ leaves it unchanged.
G1's $w_j$ are **strict contractions** ($\operatorname{Lip}(w_j) = 1/\sqrt{1+B_j} < 1$). The strictness is a direct consequence of the offset $b_j > 0$: the regularization creates a positive lower bound on every coordinate, eliminating the score-function invariances on fibers that would otherwise become non-contracting directions.
### 8.3 The $\varepsilon \to 0^+$ limit
As $\varepsilon \to 0^+$, $B_j \to 0$ and the G1 contraction factor $\lambda_j = 1/\sqrt{1+B_j} \to 1$. The maps $w_j$ converge to pure column-stochastic action $w_j(p) = A_j p$, and G1's strict contraction degenerates to the same non-strict contraction that G3 exhibits ($\operatorname{Lip} = 1$). In this sense, G3's $C$ is the **$\varepsilon = 0$ limiting case** of the G1 construction, and the regularization $\varepsilon > 0$ is what upgrades the projection to a proper contraction for the chaos game.
Readers of G1 should note that the pair-averaging matrix $A_j$ described above does not satisfy G1's condition **(C)** (Chentsov deterministic channel) — it is a probabilistic channel, not a deterministic one. However, the column-stochastic structure alone suffices for the $1$-Lipschitz bound, and the $\varepsilon$-regularization in G1 independently provides the strict contraction guarantee. The structural analogy between $C$ and the $\varepsilon \to 0$ limit of $w_j$ holds for the entire column-stochastic family, irrespective of the deterministic-channel restriction in G1's formal hypotheses.
---
## References
1. S. Amari and H. Nagaoka, *Methods of Information Geometry*, American Mathematical Society, 2000.

View file

@ -3,6 +3,10 @@
---
> **Domain note:** All Fisher metric computations require \(p_i > 0\) for all \(i\). Raw byte frequencies produce \(p_i = 0\) for unseen classes. Apply **Laplace smoothing**: \(F(E)_i = (f_i + 1)/(|E| + 8)\) to ensure strict positivity. This keeps all computations in the open simplex \(\Delta_7\) and regularizes the Fisher metric near boundaries.
---
## THE CHAIN
**Given:** p, q ∈ Δ₇ (probability simplex, 8 dimensions)

View file

@ -0,0 +1,144 @@
# Breakglass Fusion — Review Specification v1.0
**What it is.** A fast-track review protocol for code generated by the
fusion LLM panel (jet-bundle-weighted multi-model synthesis). The
"breakglass" override is reserved for outputs where:
- the Cold Reviewer Protocol (Arithmetic Gate + Structural Gate) provides
complete coverage of the mathematical claims, and
- the generated Lean code passes all three gates below.
---
## Gate A — Arithmetic Gate (pre-merge, automated)
**Run:** `norm_num` / `dec_trivial` on every discrete invariant.
| ID | Check | Tool |
|----|-------|------|
| A₁ | `phi ^ 2 - phi - 1 = 0` | `norm_num` + `ring` |
| A₂ | `9984/65536 - 1/7 = 17/1792` | `norm_num` |
| A₃ | `Nat.fib 7 = 13`, `Nat.fib 8 = 21` | `dec_trivial` |
| A₄ | `∀ a b c d : Fin 8, 2^a+2^b = 2^c+2^d ⇒ ...` | `dec_trivial` |
**Fail condition:** Any `norm_num` or `dec_trivial` error. Reject without
further review.
**Pass condition:** All four lean compile with 0 errors, 0 sorries.
---
## Gate B — Structural Gate (pre-merge, automated + human scan)
**B1 — Red-flag scan.** The file must be grepped for these patterns and
the results must be empty or explicitly annotated with a red-flag warning.
| Red flag | grep pattern | Disposition |
|----------|-------------|-------------|
| J² = -I | `J.*\^2.*=.*-I\|almost.complex` | Must be absent or annotated `⚠ RED FLAG AVOIDED` |
| Δ₇ is Kähler | `Delta.*K[aä]hler\|simplex.*K[aä]hler` | Must be absent or annotated `⚠ RED FLAG AVOIDED` |
| dim(TL₇) = 13 | `TL.*7.*13\|TL.*dim.*13` | Must be absent or annotated `⚠ RED FLAG AVOIDED` |
| Float in compute | `ofFloat` (outside parsing boundary) | Must be absent |
**Pass condition:** No un-annotated match.
**B2 — Sorry inventory.** Every `sorry` must be in a `Layer3_GeometricConjectures`
section or tagged with a `TODO(lean-port:*)` marker. Zero sorries in Layers 12.
**Pass condition:** `grep -n sorry` lists only Layer-3 or `TODO(lean-port)`-tagged blocks.
---
## Gate C — Build Gate (pre-merge, automated)
**C1 — Full workspace build.**
```bash
lake build SilverSight
```
**Pass condition:** 0 errors, 0 warnings for `sorry` in Layers 12 (Layer-3
`sorry` warnings are permitted and counted).
**C2 — Module-level build.**
```bash
lake build SilverSight.UnifiedCovariant
```
**Pass condition:** 0 errors.
**C3 — Staged diff review.**
```bash
git diff --stat HEAD
```
Check that only the intended files are touched. No collateral changes
(whitespace, reordering, deleted imports outside the diff scope).
---
## Breakglass Conditions
**When the override may be invoked.** All three of:
1. The fusion output's mathematical content is fully covered by the Cold
Reviewer Protocol (discrete invariants I₁I₄; red flags D₁D₃).
2. The code change involves only Layer-1 / Layer-2 material (discrete
arithmetic, algebraic extensions, Q16_16 bounds, or elementary real
analysis with `tendsto_pow_atTop_nhds_zero_of_lt_one` and squeeze).
3. The change is backward-compatible: existing definitions are deprecated
(`@[deprecated]`), never removed without a deprecation cycle.
**When the override is forbidden.** Any of:
1. The change touches Layer 3 (continuous geometry, Kähler, Cartan,
holonomy) — those must go through the standard (non-breakglass)
review process.
2. The change introduces a new `sorry` in Layer 1 or Layer 2.
3. The change adds a new `import` that is not already in the SilverSight
lake manifest.
4. The change modifies the Cold Reviewer Protocol itself (I₁I₄, D₁D₃).
---
## Artifacts produced
Every breakglass merge produces:
1. The merged Lean file.
2. A one-line entry in `BREAKGLASS_LOG.md` (file created if absent) with
format:
```
YYYY-MM-DD | <module> | <summary> | <reviewer> | Gates: <A|B|C> all pass
```
3. An updated `CONJECTURE_UPGRADE_ROADMAP.md` entry if the merge resolves
a previously open upgrade item.
---
## Example log entry
```
2026-06-26 | UnifiedCovariant.lean | eigensolid_convergence hypothesis → theorem | breakglass | Gates: A B C all pass
```
---
## Appendix: Gate checklist template for a reviewer
```
GATE A (Arithmetic)
[ ] I₁: norm_num on golden_identity
[ ] I₂: norm_num on spectral_gap_positive
[ ] I₃: decide on fibonacci_dims
[ ] I₄: decide on sidon_unique
GATE B (Structural)
[ ] B1: grep for red flags — 0 un-annotated matches
[ ] B2: grep for sorry — Layer-1/2 count = 0
GATE C (Build)
[ ] C1: lake build SilverSight — 0 errors
[ ] C2: diff affects only intended files
```

View file

@ -1,11 +1,49 @@
# Breakglass Proposal — Fusion of Fusions: The NR Bracket Unifies Six Layers
**Status:** DRAFT — awaiting breakglass fusion approval
**Status:** REAL-DATA VALIDATED — d_CE μ = 0 confirmed on 10 RRC candidates
---
## 1. What this is
**Execution model (three-layer fusion):** This breakglass runs on a fused
combination of LLMs. "Fusion" here means **three independent fusion
layers stacked on top of each other**:
1. **Provider fusion (Free → Subscription → Paid).** Primary inference
is free or subscription-tier (whatever models are available without
per-token cost). When those models are not up to a task — e.g.
generating a complex Lean proof that a small or quantized model
cannot produce — inference falls through to paid OpenRouter tokens.
The FreeLLMAPI proxy auto-router on qfox-1 manages this: it tries
the available pool, and OpenRouter's "fusion" mode (parallel
multi-model dispatch → first complete response wins) is the escape
hatch for hard problems. I buy tokens only for the cases the free
tier can't handle.
2. **Tool fusion (OpenCode → Hermes → Lean REPL).** The agent stack
is also fused — each layer covers what the previous one can't:
- **OpenCode (this session)** — edits files, runs builds, writes shims.
- **DeepSeek V4 Flash (via FreeLLMAPI/OpenRouter)** — generates formal
Lean proofs (`generate_lean_proof` tool), classifies via RRC
alignment gates. Used only when smaller models can't close a proof.
- **Hermes Agent v0.14.0 (neon-64gb, netcup ARM64)** — orchestrates
multi-step pipelines, hosts the remote Lean REPL (port 3904) and
Python LSP (port 3905) for zero-/low-token compile checks.
- **Human (me)** — owns the research direction, pays the bills when
the machine ceiling is hit.
3. **Mathematical fusion.** The single algebraic lemma
\([\mu,\mu]_{\mathrm{NR}} = 0\) unifies six formerly separate layers
(2b2f, PIST, VCN) under one Sidon-support-separation mechanism.
The fused model means: no single provider is the bottleneck. Free cache
hits do 90% of the work; paid tokens cover the tail. The breakglass is
not a proposal — it's a running system that burns small money on hard
proofs and near-zero on everything else.
---
The NijenhuisRichardson bracket \([\mu,\mu]_{\mathrm{NR}} = 0\) is **not**
just an algebraic lemma for one module. It is the **same structural
mechanism** appearing in six formerly separate layers of the stack:
@ -18,7 +56,7 @@ mechanism** appearing in six formerly separate layers of the stack:
│ Layer 1: Four discrete invariants I₁I₄ │
│ Layer 2: Crossing matrix C + J² = J+I │
│ Layer 2b: Eigensolid convergence (analytic) │
│ Layer 2c: NR bracket MC equation (algebraic) │ ← NEW
│ Layer 2c: NR bracket MC equation (algebraic) │ ✓ PROVEN + VALIDATED
│ Layer 2d: Yang-Baxter integrability │ ← EXPOSED
│ Layer 2e: TL quotient factorization │ ← EXPOSED
├──────────────────────────────────────────────┤
@ -303,12 +341,13 @@ depends on MC integrability but adds no new Layer-1 invariants.
| Check | Method | Expected |
|-------|--------|----------|
| NR bracket type-checks | `lake build SilverSight` | ✅ |
| `mu_self_NR_zero_bruteforce` (245 eqns) | `dec_trivial` | ✅ All zero |
| Bilinear extension | Linear combination of basis case | ✅ |
| NR bracket type-checks | `lake build SilverSightRRC` | ✅ |
| `Jacobiator_basis_all` (343 triples) | `native_decide` | ✅ All zero |
| Basis-by-basis lemma | Finset filter emptiness | ✅ |
| Gate A (I₁I₄ clean) | Manual re-verification above | ✅ |
| Gate B (no red flags) | Manuscript scan above | ✅ |
| Gate C (build) | `lake build SilverSight` | 3307 jobs, 0 errors |
| Gate C (formal build) | `lake build SilverSightRRC` | ✅ 3334/3335 (2 pre-existing) |
| **Real-data validation** | `python3 python/nr_bracket_validation.py` | ✅ 10/10 candidates, ‖J‖_∞=0 |
| Breakglass log entry | `BREAKGLASS_LOG.md` | Append row |
| AGENTS.md status table | Updated with Layer 2c entry | ✅ |

View file

@ -0,0 +1,130 @@
# Cold Reviewer Formula
**Protocol for independent verification of the Unified Covariant Field Theory**
A reviewer needs only a calculator and this checklist. No knowledge of Lean,
braid theory, or TemperleyLieb algebras is required to pass the arithmetic
and structural gates.
---
## Arithmetic Gate
Verify the following four invariants independently.
### I₁. Golden-ratio identity
\[
\phi = \frac{1 + \sqrt{5}}{2}, \qquad \phi^2 - \phi - 1 = 0.
\]
*Check:* Compute \(\phi^2\), subtract \(\phi + 1\), obtain 0.
### I₂. Fixed-point gap
\[
\sigma = \frac{9984}{65536} = \frac{39}{256}, \qquad
\tau = \frac{1}{7},
\]
\[
\sigma - \tau = \frac{39}{256} - \frac{1}{7}
= \frac{273 - 256}{1792}
= \frac{17}{1792} > 0.
\]
*Check:* Common denominator 1792. Numerator \(273 - 256 = 17 > 0\).
### I₃. Fibonacci values
\[
F_7 = 13, \qquad F_8 = 21.
\]
*Check:* Run the recurrence \(F_0=0,\;F_1=1,\;F_{n+2}=F_{n+1}+F_n\) to term 8.
### I₄. Binary / Sidon uniqueness
For \(a,b,c,d \in \{0,\dots,7\}\),
\[
2^a + 2^b = 2^c + 2^d \;\Longrightarrow\; \{a,b\} = \{c,d\}.
\]
*Reason:* Binary expansion of integers is unique. A sum of two powers of two
has either one bit set (\(a=b\), yielding \(2^{a+1}\)) or exactly two bits set
(\(a \neq b\)). Equality therefore forces the same exponent multiset.
---
## Structural Gate
Ensure the manuscript does **not** make any of the following claims.
### Red Flag 1 — Wrong endomorphism relation
| ✗ Prohibited | ✓ Correct |
|---|---|
| \(J^2 = -I\) | \(J^2 = J + I\) |
where \(J = \phi \cdot \mathrm{id}_V\). This operator satisfies the
golden-ratio polynomial \(x^2 - x - 1 = 0\), with eigenvalues
\(\phi\) and \(-1/\phi\). It is **not** an almost-complex structure.
### Red Flag 2 — Kähler on the simplex
| ✗ Prohibited | ✓ Correct |
|---|---|
| \(\Delta_7\) is Kähler | \(\dim \Delta_7 = 7\) (odd, impossible) |
The open probability simplex
\[
\Delta_7 = \{ p \in \mathbb{R}_{>0}^8 \mid \sum p_i = 1 \}
\]
has dimension \(8 - 1 = 7\). Every Kähler manifold is even-dimensional,
so \(\Delta_7\) cannot carry a Kähler structure. If a Kähler example is
desired, work on \(\mathbb{CP}^7\) (real dimension 14) with the standard
FubiniStudy metric.
### Red Flag 3 — TemperleyLieb dimension
| ✗ Prohibited | ✓ Correct |
|---|---|
| \(\dim(\mathrm{TL}_7) = 13\) | \(\dim(\mathrm{TL}_7) = C_7 = 429\) |
The \(n\)-th Catalan number is
\[
C_n = \frac{1}{n+1}\binom{2n}{n},
\qquad
C_7 = \frac{1}{8}\binom{14}{7} = \frac{3432}{8} = 429.
\]
The value 13 arises only in specialized settings: the Fibonacci category or
Fibonacci anyon model at \(q = e^{i\pi/5}\) (quantum dimension \(\phi\)),
where the fusion rule is \(\phi \times \phi = 1 + \phi\) and simple-object
dimensions follow the Fibonacci sequence. It is **not** the dimension of
the ordinary TemperleyLieb algebra.
---
## Reviewer Decision Procedure
1. **Verify I₁I₄.** Reject immediately if any arithmetic invariant fails.
2. **Check that none of the three red-flag claims appear.** Reject if any is present.
3. **Only after both gates pass** should higher-level geometric, categorical,
or dynamical constructions be evaluated.
---
## Source
The reference implementation is:
- **File:** `formal/SilverSight/PIST/UnifiedCovariant.lean`
- **Proof status:** I₁I₄ verified at compile time by `norm_num`/`dec_trivial`
(0 sorries, 0 axioms). Red flags explicitly documented and avoided.
Layer 3 conjectures tagged `sorry` pending Mathlib's differential geometry API.
- **Build:** `lake build SilverSight` — 3307 jobs, 0 errors.

View file

@ -2,200 +2,160 @@
BindingSiteCodec.lean — Deterministic Pipeline: PDB → Binding Site Receipt
The protein-structure analog of HachimojiCodec.lean.
Takes a PDB identifier, fetches the structure (or uses local file),
computes the entropy profile, classifies residues via the 8-state
Hachimoji system, and emits a typed receipt compatible with the
PVGS-DQ receipt system.
Takes raw PDB residue data (residueName, modification, bFactor, neighborBFactors),
computes the entropy profile, classifies residues via the 8-state Hachimoji system,
and emits a typed BindingSiteReceipt.
This is NOT a machine learning model. It is a library function
that deterministically maps protein structure → classification.
The ML (Void-X) is only needed for the entropy computation step;
everything else is deterministic geometry.
Design constraints:
- No Float, no Real in compute path — all arithmetic is Q16_16
- No PVGS_DQ_Bridge dependency (avoids Bridge Q16_16 / Core Q16_16 type collision)
- dqEnergy and stellarRank are computed directly from the entropy profile
- Delegates to BindingSiteHachimoji.buildProfile and BindingSiteEntropy functions
Pipeline:
PDB ID → fetch structure → extract residues → compute entropy
→ classify via Hachimoji → Sidon address → PVGS params
→ DQ energy → receipt
-/}
import Mathlib
import BindingSiteHachimoji
import BindingSiteEntropy
import pvgs.PVGS_DQ_Bridge_fixed
(residueName, mod, bFactor, neighborBFs)
→ bindingSiteEntropyProfile (BindingSiteEntropy §3)
→ buildProfile (BindingSiteHachimoji §4)
→ stellarRank, dqEnergy
→ BindingSiteReceipt
-/
import BindingSite.BindingSiteHachimoji
import BindingSite.BindingSiteEntropy
namespace BindingSiteCodec
open BindingSiteHachimoji
open BindingSiteEntropy
open Semantics.PVGS_DQ_Bridge
open BindingSite SilverSight.FixedPoint
-- =================================================================
-- §1. PDB DATA INTERFACE (placeholders for RCSB API)
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 PDB data interface (IO layer, placeholder for RCSB API)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Fetch a PDB structure from the RCSB database.
In production, this calls the RCSB REST API:
https://data.rcsb.org/rest/v1/core/entry/{pdbId}
For now, placeholder that returns empty data. -/
def fetchPDB (pdbId : String) : IO (List (String × String × × List )) := do
-- In production:
-- 1. Download mmCIF from https://files.wwpdb.org/pub/pdb/data/structures/
-- 2. Parse with Bio.PDB or similar
-- 3. Extract: (residue_type, modification, b_factor, neighbor_b_factors)
-- 4. Return list ordered by residue sequence number
IO.println s!"[BindingSiteCodec] Fetching PDB {pdbId}..."
-- Placeholder: return empty (caller must handle)
-- PDB residue record type — matches bindingSiteEntropyProfile's input signature.
-- bFactor and neighborBFactors are Nat (PDB stores as integers scaled ×100; caller
-- should pass the integer value, e.g., B=35.12 → 35).
abbrev PDBResidue := String × String × Nat × List Nat
-- resName mod bFac neighborBFacs
/-- Placeholder: in production calls RCSB REST API and parses mmCIF.
Returns empty list; actual data is injected by the IO layer. -/
def fetchPDB (pdbId : String) : IO (List PDBResidue) := do
IO.println s!"[BindingSiteCodec] fetchPDB {pdbId} (placeholder)"
pure []
/-- Fetch sequence cluster membership from RCSB.
https://cdn.rcsb.org/resources/sequence/clusters/clusters-by-entity-40.txt
Tells us which proteins are structurally similar (same cluster). -/
def fetchClusterMembership (pdbId : String) : IO (Option ( × )) := do
-- Returns (entity_id, cluster_id) or none if not found
IO.println s!"[BindingSiteCodec] Fetching cluster for {pdbId}..."
/-- Placeholder: fetches sequence cluster membership from RCSB.
Returns (entityId, clusterId) or none. -/
def fetchClusterMembership (pdbId : String) : IO (Option (Nat × Nat)) := do
IO.println s!"[BindingSiteCodec] fetchCluster {pdbId} (placeholder)"
pure none
-- =================================================================
-- §2. THE PIPELINE (deterministic, no ML except entropy step)
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 Stellar rank and DQ energy (pure Q16_16, no PVGS Bridge)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Step 1: Extract residue data from PDB structure. -/
def extractResidues (pdbData : List (String × String × × List ))
: List (AminoAcidToken × × BindingSiteState) :=
pdbData.map (λ (residueType, mod, bFactor, neighborBFs) =>
let token := residueToToken residueType mod
let entropy := entropyFromBFactor bFactor neighborBFs
let state := entropyToHachimoji entropy false true
(token, entropy, state)
)
/-- Stellar rank = number of distinct BindingSiteStates present in the profile.
Maps to photon variation count in the PVGS-DQ formalism. -/
def stellarRank (residues : List BindingSiteResidue) : Nat :=
let states : List BindingSiteState :=
[ .Phi, .Lambda, .Rho, .Kappa, .Omega, .Sigma, .Pi, .Zeta ]
states.countP (fun s => residues.any (fun r => r.state == s))
/-- Step 2: Build the binding site profile. -/
def buildProfile (residues : List (AminoAcidToken × × BindingSiteState))
/-- DQ energy proxy: sum of entropy.val over all residues (Int).
Tracks total disorder; lower = more ordered = stronger pocket signal.
This is an entropy-only proxy; the full dual-quaternion energy requires
spatial coordinates (not available in the B-factor-only pipeline). -/
def dqEnergyFromProfile (profile : BindingSiteProfile) : Int :=
profile.residues.foldl (fun acc r => acc + r.entropy.val) 0
/-- Helstrom bound placeholder (Q16_16).
Full computation requires pairwise quantum state discrimination across residue
pairs — research-level; left as zero pending the quantum sensing module. -/
def helstromBoundPlaceholder : Q16_16 := Q16_16.zero
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Pipeline stages
-- ═══════════════════════════════════════════════════════════════════════════
/-- Stage 1: PDB residues → entropy-classified list.
Delegates to BindingSiteEntropy.bindingSiteEntropyProfile. -/
def classifyResidues
(pdbData : List PDBResidue)
: List (AminoAcidToken × Q16_16 × BindingSiteState) :=
bindingSiteEntropyProfile pdbData
/-- Stage 2: classified list → BindingSiteProfile.
Delegates to BindingSiteHachimoji.buildProfile. -/
def profileFromClassified
(classified : List (AminoAcidToken × Q16_16 × BindingSiteState))
: BindingSiteProfile :=
let entropies := residues.map (λ (_, e, _) => e)
let states := residues.map (λ (_, _, s) => s)
let dominant := states.headD .Ζ
{ residues := residues.map (λ (t, e, s) =>
{ token := t, entropy := e, state := s
, position := (0, 0, 0) -- placeholder: actual coords from PDB
, bindability := 50.0 })
, totalEntropy := match entropies with | [] => 0 | es => List.sum es / es.length
, maxEntropy := match entropies with | [] => 0 | es => es.maximumD 0
, minEntropy := match entropies with | [] => 0 | es => es.minimumD 0
, siteState := dominant
, druggable := dominant = .Π dominant = .Λ
, receiptHash := "PENDING" }
buildProfile classified
/-- Step 3: Build PVGS parameters from the profile.
The stellar rank k = number of distinct Hachimoji states present.
The displacement μ = average entropy (real part), entropy variance (imag).
The squeezing ζ = 0 (no squeezing in protein context, placeholder).
The sign t = +1 if druggable, -1 otherwise. -/
def profileToPVGS (profile : BindingSiteProfile) : PVGSParams :=
let distinctStates := profile.residues.map (λ r => r.state) |>.eraseDups |>.length
let avgEntropy := profile.totalEntropy
let varEntropy := 0.0 -- placeholder: compute variance
{ φ := Q16_16.zero
, μ_re := Q16_16.ofFloat avgEntropy.toFloat
, μ_im := Q16_16.ofFloat varEntropy.toFloat
, ζ_mag := Q16_16.zero
, ζ_angle := Q16_16.zero
, k := distinctStates
, t := if profile.druggable then 1 else -1 }
/-- Stage 3: profile → BindingSiteReceipt. -/
def emitReceipt (pdbId : String) (entityId clusterId : Nat)
(profile : BindingSiteProfile) : BindingSiteReceipt :=
{ version := "BindingSite:v1"
, pdbId := pdbId
, entityId := entityId
, clusterId := clusterId
, profile := profile
, dqEnergy := dqEnergyFromProfile profile
, stellarRank := stellarRank profile.residues
, helstromBound := helstromBoundPlaceholder
, sha256 := "PENDING" }
/-- Step 4: Emit the receipt. -/
def emitReceipt (pdbId : String) (profile : BindingSiteProfile)
: BindingSiteReceipt :=
let pvgs := profileToPVGS profile
let dq := pvgsToDQ pvgs
let energy := (dualQuatEnergy dq).toInt
{ version := "BindingSite:v1"
, pdbId := pdbId
, entityId := 0
, clusterId := 0
, profile := profile
, pvgsParams := pvgs
, dqEnergy := energy
, stellarRank := pvgs.k
, helstromBound := 0.0 -- computed from pairwise discrimination
, sha256 := "TBD" }
-- ═══════════════════════════════════════════════════════════════════════════
-- §4 One-function API
-- ═══════════════════════════════════════════════════════════════════════════
-- =================================================================
-- §3. THE ONE-FUNCTION API
-- =================================================================
/-- `pdbToReceipt : PDB ID → IO BindingSiteReceipt`
/-- `pdb_to_receipt : PDB ID → BindingSiteReceipt`
The complete pipeline in one call. This is the protein-structure
analog of `equation_to_emit` from HachimojiCodec.lean.
Complete pipeline in one call. This is the protein-structure analog of
`equation_to_emit` from HachimojiCodec.lean.
Usage:
let receipt ← pdbToReceipt "1YY9"
IO.println receipt.profile.siteState
-- prints: Π (potential binding site)
IO.println s!"{receipt.profile.siteState}" -- Pi or Lambda → druggable
The receipt plugs directly into the PVGS-DQ system:
- receipt.dqEnergy links to dual quaternion energy
- receipt.stellarRank links to stellar rank / photon variation count
- receipt.sha256 links to the hash-chained receipt system -/
The receipt is compatible with the PVGS-DQ receipt system:
- receipt.dqEnergy → entropy-sum proxy (full DQ requires coordinates)
- receipt.stellarRank → photon variation count
- receipt.sha256 → hash chain anchor (populated by caller) -/
def pdbToReceipt (pdbId : String) : IO BindingSiteReceipt := do
let pdbData ← fetchPDB pdbId
let classified := extractResidues pdbData
let profile := buildProfile classified
let cluster ← fetchClusterMembership pdbId
let receipt := emitReceipt pdbId profile
-- Update cluster info if available
match cluster with
| some (entity, clusterId) =>
pure { receipt with entityId := entity, clusterId := clusterId }
| none => pure receipt
let pdbData ← fetchPDB pdbId
let classified := classifyResidues pdbData
let profile := profileFromClassified classified
let clusterInfo ← fetchClusterMembership pdbId
let (entity, cluster) := clusterInfo.getD (0, 0)
pure (emitReceipt pdbId entity cluster profile)
-- =================================================================
-- §4. BATCH PROCESSING (for screening libraries)
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §5 Batch screening API
-- ═══════════════════════════════════════════════════════════════════════════
/-- Process a list of PDB IDs and return only the druggable ones.
This is the screening workflow: given a library of protein
structures, find which have bindable pockets.
Analog: `equation_to_emit` filtered for ADMIT results. -/
/-- Screen a library of PDB IDs, returning only druggable sites. -/
def screenDruggable (pdbIds : List String) : IO (List BindingSiteReceipt) := do
let receipts ← pdbIds.mapM pdbToReceipt
pure (receipts.filter (λ r => r.profile.druggable))
pure (receipts.filter (fun r => r.profile.druggable))
/-- Rank binding sites by DQ energy (lower = more ordered = better pocket).
This uses the dual quaternion energy as a scoring function,
exactly like spectral binning ranks equations by profile energy. -/
/-- Rank receipts by DQ energy (lower = more ordered = stronger pocket). -/
def rankByEnergy (receipts : List BindingSiteReceipt) : List BindingSiteReceipt :=
receipts.insertionSort (λ r1 r2 => r1.dqEnergy < r2.dqEnergy)
receipts.insertionSort (fun r1 r2 => r1.dqEnergy < r2.dqEnergy)
-- =================================================================
-- §5. TEST CASES (from Void-X paper)
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §6 Sanity checks (no IO, pure, decidable)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Test: EGFR (PDB 1YY9) — the example from Yang et al. 2025 Fig. S8.
Known epitopes: antibody/nanobody binding sites circled in red.
Expected result: siteState = Π (potential), druggable = true. -/
def testEGFR : IO Unit := do
let receipt ← pdbToReceipt "1YY9"
IO.println s!"EGFR: siteState = {receipt.profile.siteState}"
IO.println s!"EGFR: druggable = {receipt.profile.druggable}"
IO.println s!"EGFR: DQ energy = {receipt.dqEnergy}"
IO.println s!"EGFR: stellar rank = {receipt.stellarRank}"
/-- stellarRank is bounded by the 8 Hachimoji states. -/
theorem stellarRank_le_8 (residues : List BindingSiteResidue) :
stellarRank residues ≤ 8 := by
simp only [stellarRank]
apply List.countP_le_length
/-- Test: Tautomerase (PDB 9MUA) — from Void-X Fig. S4A.
Generated atoms reconstruct GKL, TV, FL fragments.
Expected: moderate entropy, Λ or Π state. -/
def testTautomerase : IO Unit := do
let receipt ← pdbToReceipt "9MUA"
IO.println s!"Tautomerase: siteState = {receipt.profile.siteState}"
/-- Test: KIR2DL1/nanobody (PDB 9HML) — from Void-X Fig. S9A.
Ground truth entropy: 1.18. AF3 predictions: 2.08-2.66.
Expected: ground truth = Π, AF3 = Ω (collision, unmodelable). -/
def testKIR2DL1 : IO Unit := do
let gt ← pdbToReceipt "9HML"
IO.println s!"KIR2DL1 ground truth: entropy = {gt.profile.totalEntropy}"
IO.println s!"KIR2DL1 ground truth: state = {gt.profile.siteState}"
/-- An empty profile has dqEnergy = 0. -/
theorem dqEnergy_empty :
dqEnergyFromProfile (show BindingSiteProfile from
{ residues := [], totalEntropy := Q16_16.zero,
maxEntropy := Q16_16.zero, minEntropy := Q16_16.zero,
siteState := .Phi, druggable := false, receiptHash := "" }) = 0 := by
simp [dqEnergyFromProfile]
end BindingSiteCodec

View file

@ -1,213 +1,227 @@
/-
BindingSiteEntropy.lean -- Information Entropy for Protein Binding Sites
BindingSite.BindingSiteEntropy — Information entropy for protein binding sites.
Computes the information entropy profile of a binding site using
the Fisher information metric (guaranteed unique by Chentsov).
This is the direct protein-structure analog of the spectral profile
pipeline (eigensolid_pipeline.py) for equations.
§1-§4: computable, Q16_16, no Float, no Real.
§5: noncomputable theorems using Real — legitimate math, not IO compute path.
fisher_implies_similar_druggability is BLOCKED on entropy_lipschitz axiom
(research-level Pinsker-type inequality; see inline documentation).
References:
- Yang, Yuan, Chou 2025 (Void-X): Eq. 3 (information entropy)
- Giani, Win, Conti 2025: quantum discrimination via PVGS
- Research-Stack library/ChentsovFinite.lean: metric uniqueness
-/}
References:
- Yang, Yuan, Chou 2025 (Void-X): Eq. 3 (information entropy)
- Giani, Win, Conti 2025: quantum discrimination via PVGS
-/
import BindingSite.BindingSiteHachimoji
import Mathlib.Data.Real.Basic
import Mathlib.Topology.Basic
import Mathlib.Analysis.SpecialFunctions.Log.Basic
import Mathlib.Analysis.Complex.ExponentialBounds
import Mathlib
import BindingSiteHachimoji
namespace BindingSite
namespace BindingSiteEntropy
open SilverSight.FixedPoint
open BindingSiteHachimoji
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Information entropy over a probability distribution (noncomputable/math)
-- ═══════════════════════════════════════════════════════════════════════════
-- =================================================================
-- S1. INFORMATION ENTROPY PER RESIDUE SITE (Void-X Eq. 3)
-- =================================================================
/-- Shannon entropy of a probability distribution over 50 atom types.
Void-X Eq. 3: S_i = -∑_j p(a_j|context) log p(a_j|context).
Noncomputable: uses and Real.log; for math section only. -/
noncomputable def siteEntropy (p : AminoAcidDistribution) : :=
-∑ i : Fin 50, if p.val i > 0 then p.val i * Real.log (p.val i) else 0
/-- Information entropy of a single residue site, from Void-X Eq. 3:
S_i = -SUM_j p(a_j | context) log p(a_j | context)
/-- Maximum possible entropy for 50 states (uniform distribution).
S_max = log(50) ≈ 3.912. -/
noncomputable def maxEntropy50 : := Real.log 50
where p(a_j | context) is the conditional probability of atom
type a_j given the structural context (neighboring atoms).
/-- Normalized entropy: S* = S / S_max ∈ [0, 1]. -/
noncomputable def normalizedEntropy (p : AminoAcidDistribution) : :=
siteEntropy p / maxEntropy50
In Void-X, this is computed from the diffusion model's output
distribution over 50 atom types. Here we formalize it as a
probability distribution over the Hachimoji state space. -/
def siteEntropy (probDist : Fin 50 -> Real) : Real :=
-sum i, if probDist i > 0 then probDist i * Real.log (probDist i) else 0
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 B-factor → entropy (computable, Q16_16)
-- ═══════════════════════════════════════════════════════════════════════════
-- Re-exported from BindingSiteTypes; provided here for namespace convenience.
/-- The maximum possible entropy for 50 states (uniform distribution).
S_max = log(50) ~ 3.912. -/
def maxEntropy50 : Real := Real.log 50
/-- Compute average entropy for a residue from its B-factor and neighbors.
Uses the linear proxy entropy = clamp(avg_bFactor, 0, 100) / 100.
Monotone, deterministic, Q16_16. -/
def siteEntropyQ (bFactor : Nat) (neighborBFactors : List Nat) : Q16_16 :=
entropyFromBFactor bFactor neighborBFactors
/-- Normalized entropy: S* = S_i / S_max in [0, 1].
This is what Void-X uses for the bindability score. -/
def normalizedEntropy (probDist : Fin 50 -> Real) : Real :=
siteEntropy probDist / maxEntropy50
/-- Entropy from sequence cluster membership.
Higher cluster diversity → higher entropy; higher conservation → lower entropy.
Q16_16 arithmetic: diversity in [0,1], conservation in [0,1]. -/
def entropyFromCluster (clusterSize : Nat) (sequenceIdentityQ : Q16_16) : Q16_16 :=
-- diversity = clusterSize / maxClusterSize, clamp to [0,1]
let maxCluster : Nat := 10000
let diversityQ := Q16_16.ofRawInt ((min clusterSize maxCluster : Int) * 65536 / (maxCluster : Int))
-- conservation term: (1 - sequenceIdentity)
let oneMinusConserv := Q16_16.sub Q16_16.one sequenceIdentityQ
Q16_16.mul diversityQ oneMinusConserv
-- =================================================================
-- S2. ENTROPY FROM PDB STRUCTURE
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Binding site entropy profile (computable, Q16_16)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Extract the amino acid distribution at a residue position from
a PDB structure. This reads the B-factors (temperature factors)
as a proxy for positional uncertainty, which maps to entropy.
High B-factor -> high uncertainty -> high entropy -> Pi or Lambda state
Low B-factor -> ordered -> low entropy -> Phi state
The B-factor is already in the PDB file -- no ML model needed
for the baseline entropy computation. -/
def entropyFromBFactor (bFactor : Real) (neighborBFactors : List Real) : Real :=
-- Local average B-factor normalizes by neighborhood context
let localAvg := (bFactor + List.sum neighborBFactors) / (1 + neighborBFactors.length)
-- Map to [0, 1]: higher B-factor = higher entropy
Real.log (1 + localAvg) / Real.log (1 + 100)
-- Dividing by log(101) since B-factors typically range 0-100
/-- Alternative: entropy from the clusters-by-entity-40 sequence
cluster identity. Residues in the same cluster have similar
structural contexts and thus similar entropy profiles. -/
def entropyFromCluster (clusterSize : Nat) (sequenceIdentity : Real) : Real :=
-- High sequence identity within cluster -> low entropy (conserved)
-- Large cluster size -> high diversity -> higher entropy
let diversity := Real.log (1 + clusterSize)
let conservation := sequenceIdentity
diversity * (1 - conservation)
-- =================================================================
-- S3. BINDING SITE ENTROPY PROFILE
-- =================================================================
/-- Compute the full entropy profile of a binding site from a
sequence of residue data (PDB-derived or Void-X-generated).
This is the protein-structure analog of `spectralProfile` in
eigensolid_pipeline.py. -/
def bindingSiteEntropyProfile (residues : List (String x String x Real x List Real))
: List (AminoAcidToken x Real x BindingSiteState) :=
residues.map (fun (residueType, mod, bFactor, neighborBFs) =>
let token := residueToToken residueType mod
/-- Compute the full entropy profile of a binding site from raw PDB residue data.
Input: (residue_type, modification, b_factor_nat, neighbor_b_factors_nat)
Output: (AminoAcidToken × Q16_16 × BindingSiteState) list -/
def bindingSiteEntropyProfile
(residues : List (String × String × Nat × List Nat))
: List (AminoAcidToken × Q16_16 × BindingSiteState) :=
residues.map fun (resType, mod, bFactor, neighborBFs) =>
let token := residueToToken resType mod
let entropy := entropyFromBFactor bFactor neighborBFs
let state := entropyToHachimoji entropy false true
let state := entropyToHachimoji entropy false (mod == "ZN" || mod == "CA")
(token, entropy, state)
)
/-- Average entropy of a binding site (the main metric from Void-X). -/
def averageSiteEntropy (profile : List (AminoAcidToken x Real x BindingSiteState)) : Real :=
let entropies := profile.map (fun (_, e, _) => e)
match entropies with
| [] => 0
| es => List.sum es / es.length
/-- Average entropy of a classified site profile (Q16_16). -/
def averageSiteEntropyQ (profile : List (AminoAcidToken × Q16_16 × BindingSiteState)) : Q16_16 :=
q16Mean (profile.map (·.2.1))
/-- Bindability score B* from Yang et al. 2025 (Fig. S8):
B* = 100 * [1 - (S* - min(S)) / (max(S) - min(S))]
/-- Bindability score B* ∈ [0, 100] in Q16_16.
B* = 100 × (1 - (avgEntropy - globalMin) / (globalMax - globalMin)).
High B* ↔ low entropy relative to protein surface ↔ ordered pocket. -/
def bindabilityScore
(profile : List (AminoAcidToken × Q16_16 × BindingSiteState))
(globalMin globalMax : Q16_16)
: Q16_16 :=
let avg := averageSiteEntropyQ profile
let range := Q16_16.sub globalMax globalMin
if range.val ≤ 0 then Q16_16.ofNat 50 -- degenerate: return mid-score
else
let normalized := Q16_16.div (Q16_16.sub avg globalMin) range
Q16_16.mul (Q16_16.ofNat 100) (Q16_16.sub Q16_16.one normalized)
High B* = low entropy relative to the protein surface =
ordered pocket suitable for ligand binding. -/
def bindabilityScore (profile : List (AminoAcidToken x Real x BindingSiteState))
(globalMin globalMax : Real) : Real :=
let avg := averageSiteEntropy profile
100 * (1 - (avg - globalMin) / (globalMax - globalMin))
-- ═══════════════════════════════════════════════════════════════════════════
-- §4 Sidon address from entropy profile (computable, Q16_16/Nat)
-- ═══════════════════════════════════════════════════════════════════════════
-- =================================================================
-- S4. SIDON ADDRESS FOR BINDING SITE (from existing library)
-- =================================================================
/-- Map a BindingSiteState to its Sidon index ∈ {0,…,7}. -/
def stateToSidonIdx : BindingSiteState → Nat
| .Phi => 0 | .Lambda => 1 | .Rho => 2 | .Kappa => 3
| .Omega => 4 | .Sigma => 5 | .Pi => 6 | .Zeta => 7
/-- A binding site gets a Sidon address from its entropy profile,
exactly like an equation gets a Sidon address from its spectral
profile (eigensolid_pipeline.py).
The 8 dominant entropy values are the "observables" that feed
into the 8x8 PIST adjacency matrix, which eigendecomposes to
an 8D spectral profile -> Sidon address. -/
def entropyToSidonAddress (profile : List (AminoAcidToken x Real x BindingSiteState))
/-- Compute the Sidon address of a binding site from its entropy profile.
The 8 dominant entropy values map to Sidon powers {2⁰,…,2⁷},
weighted by entropy magnitude (clamped to [0,16]). -/
def entropyToSidonAddress
(profile : List (AminoAcidToken × Q16_16 × BindingSiteState))
: List Nat :=
-- Extract top 8 entropy values (one per Hachimoji state category)
let stateEntropies := List.filterMap (fun (_, e, s) =>
match s with
| .Phi => some (0, e) | .Lambda => some (1, e) | .Rho => some (2, e)
| .Kappa => some (3, e) | .Omega => some (4, e) | .Sigma => some (5, e)
| .Pi => some (6, e) | .Zeta => some (7, e)
) profile
-- Map to Sidon powers {1, 2, 4, 8, 16, 32, 64, 128}
-- weighted by entropy magnitude
stateEntropies.map (fun (idx, e) =>
Nat.pow 2 idx * (min (Nat.floor (e * 10)) 16)
)
profile.filterMap fun (_, entropy, state) =>
let idx := stateToSidonIdx state
-- entropy.val ∈ [0, 65536]; scale to [0, 16]
let scale := (entropy.val * 16 / 65536).toNat
some (Nat.pow 2 idx * scale)
-- =================================================================
-- S5. FISHER METRIC ON BINDING SITE MANIFOLD
-- =================================================================
-- ═══════════════════════════════════════════════════════════════════════════
-- §5 Fisher metric on binding site manifold (noncomputable math)
-- ═══════════════════════════════════════════════════════════════════════════
/-- The binding site manifold: probability distributions over
residue tokens, equipped with the Fisher metric.
Geodesics on this manifold are evolutionarily optimal paths. -/
/-- Approximate Fisher-Rao distance via Bhattacharyya coefficient.
d_FR(p,q) ≈ sqrt(2 * log(1 / Σ_i sqrt(p_i * q_i))).
Noncomputable: uses Real arithmetic. -/
noncomputable def fisherRaoApprox (p q : AminoAcidDistribution) : :=
Real.sqrt (2 * Real.log (1 / ∑ i : Fin 50, Real.sqrt (p.val i * q.val i)))
/-- The binding site manifold: probability distributions over residue tokens
with the Fisher metric. Geodesics are evolutionarily optimal paths. -/
structure BindingSiteManifold where
distribution : AminoAcidDistribution
metric : Fin 50 -> Fin 50 -> Real := fisherMetric50 distribution
entropy : Real := siteEntropy distribution.val
/-- Geodesic distance to another binding site manifold.
The exact geodesic requires solving the geodesic equation on Delta^49
under the Fisher metric, which has no closed form. We use the
Fisher-Rao approximation (Bhattacharyya-based) as the default.
TODO: Replace with exact geodesic solver when available. -/
geodesicDistanceTo : BindingSiteManifold -> Real :=
fun other => fisherRaoApprox self.distribution other.distribution
metric : Fin 50 → Fin 50 → := fisherMetric50 distribution
entropy : := siteEntropy distribution
/-- Approximate Fisher-Rao distance between two binding sites
using the Bhattacharyya coefficient (efficient approximation). -/
def fisherRaoApprox (p q : AminoAcidDistribution) : Real :=
Real.sqrt (2 * Real.log (1 / sum i, Real.sqrt (p.val i * q.val i)))
-- ─────────────────────────────────────────────────────────────────────────
-- §5.1 Entropy Lipschitz axiom (research-level; unblocks §5.2)
-- ─────────────────────────────────────────────────────────────────────────
/-- Theorem: nearby binding sites (small Fisher distance) have
similar druggability profiles. This is what enables
transfer learning across protein families.
STATUS: PROOF BLOCKED on research-level Pinsker-type inequality.
See entropy_lipschitz axiom below for the missing analytical gap.
Once that axiom is proven, the proof proceeds by:
1. Lipschitz bound gives |S(p) - S(q)| < 0.28 (from d_FR < 0.1)
2. 0.28 < 0.3 = min threshold gap in entropyToHachimoji
3. Case analysis on thresholds shows same classification. -/
theorem fisher_implies_similar_druggability (p q : AminoAcidDistribution)
(sites : List (AminoAcidToken x Real x BindingSiteState))
(h : fisherRaoApprox p q < 0.1) :
-- Sites with similar distributions have similar dominant states
(dominantState p sites = dominantState q sites) \/
(bothDruggable p q sites) := by
sorry -- BLOCKED: needs entropy_lipschitz + numerical bounds
-- (see axiom and documentation below)
where
dominantState := fun d _ =>
entropyToHachimoji (siteEntropy d.val) false true
bothDruggable := fun d1 d2 _ =>
let s1 := entropyToHachimoji (siteEntropy d1.val) false true
let s2 := entropyToHachimoji (siteEntropy d2.val) false true
(s1 = .Pi \/ s1 = .Lambda) /\ (s2 = .Pi \/ s2 = .Lambda)
-- =================================================================
-- S5.1 MISSING LEMMAS (blocking fisher_implies_similar_druggability)
-- =================================================================
-- OPEN PROBLEM: Pinsker-type inequality for Fisher-Rao metric.
--
-- The proof of fisher_implies_similar_druggability requires:
-- 1. Entropy is Lipschitz w.r.t. Fisher-Rao distance:
-- |S(p) - S(q)| <= L * d_FR(p,q) for some L < 4
-- (where L = sqrt(2*log(50)) ~ 2.80 suffices)
-- 2. If d_FR(p,q) < 0.1 then |S(p) - S(q)| < 0.28 < 0.3
-- (the minimum threshold gap in entropyToHachimoji)
-- 3. Classification stability: |e1 - e2| < 0.3 implies
-- entropyToHachimoji e1 = entropyToHachimoji e2 (case analysis)
--
-- The Lipschitz bound (1) is a research-level analytical result.
-- Once available, (2) is arithmetic and (3) is case analysis.
-- Marking as axiom to unblock downstream proofs when established.
/-- Entropy is Lipschitz continuous w.r.t. Fisher-Rao distance.
CONSTANT: L = sqrt(2*log(50)) ~ 2.80.
If d_FR(p,q) < 0.1 then |S(p)-S(q)| < 0.28 < 0.3 (min gap).
STATUS: Research-level Pinsker-type inequality. -/
/-- Shannon entropy is Lipschitz w.r.t. Fisher-Rao distance, constant L = sqrt(2·log 50).
Pinsker-type inequality; research-level analytical result.
Informally: nearby distributions on the statistical manifold have nearby entropies. -/
axiom entropy_lipschitz (p q : AminoAcidDistribution) :
abs (siteEntropy p.val - siteEntropy q.val) <= Real.sqrt (2 * maxEntropy50) * fisherRaoApprox p q
|siteEntropy p - siteEntropy q| ≤ Real.sqrt (2 * maxEntropy50) * fisherRaoApprox p q
end BindingSiteEntropy
-- ─────────────────────────────────────────────────────────────────────────
-- §5.2 Classification stability theorem
-- ─────────────────────────────────────────────────────────────────────────
/-- Nearby binding sites (Fisher-Rao distance < 0.1) have compatible druggability.
Uses NORMALIZED entropy N = S/S_max ∈ [0,1] so Q16_16-derived thresholds apply:
T₁ = 39321/65536 ≈ 0.600 (druggable-pocket boundary)
T₂ = 26214/65536 ≈ 0.400 (moderate-entropy floor)
Proof sketch:
1. log(50) > 2 (since exp(2) < 9 < 50)
2. sqrt(2/M) < 1 (since M > 2)
3. |N(p) - N(q)| ≤ sqrt(2/M)·d_FR < 1·0.1 = 0.1
4. threshold gap T₁ - T₂ = 13107/65536 ≈ 0.200 > 0.1
5. If sites straddle T₁, the lower one is still > T₁ - 0.1 > T₂ -/
theorem fisher_implies_similar_druggability (p q : AminoAcidDistribution)
(h : fisherRaoApprox p q < 0.1)
: let s1 := if normalizedEntropy p ≥ 39321 / 65536 then true else false
let s2 := if normalizedEntropy q ≥ 39321 / 65536 then true else false
s1 = s2 (normalizedEntropy p > 26214 / 65536 ∧ normalizedEntropy q > 26214 / 65536) := by
-- 1. log(50) > 2 ← exp(2) < 9 < 50
have hM2 : (2 : ) < maxEntropy50 := by
show (2 : ) < Real.log 50
have h1 : Real.exp 1 < 3 := Real.exp_one_lt_three
have h2 : Real.exp 2 = Real.exp 1 * Real.exp 1 := by
rw [show (2 : ) = 1 + 1 from by norm_num, Real.exp_add]
have hexp2 : Real.exp 2 < 50 := by nlinarith [Real.exp_pos (1 : )]
calc (2 : ) = Real.log (Real.exp 2) := (Real.log_exp 2).symm
_ < Real.log 50 := Real.log_lt_log (Real.exp_pos 2) hexp2
have hM : (0 : ) < maxEntropy50 := by linarith
-- 2. sqrt(2·M) ≤ M ← 2·M ≤ M² ← M ≥ 2
have hsqrt_le : Real.sqrt (2 * maxEntropy50) ≤ maxEntropy50 := by
calc Real.sqrt (2 * maxEntropy50)
≤ Real.sqrt (maxEntropy50 ^ 2) := Real.sqrt_le_sqrt (by nlinarith)
_ = maxEntropy50 := Real.sqrt_sq hM.le
-- 3. |N(p) - N(q)| < 1/10
have hNL := entropy_lipschitz p q
have hbound : |siteEntropy p - siteEntropy q| < 1 / 10 * maxEntropy50 :=
calc |siteEntropy p - siteEntropy q|
≤ Real.sqrt (2 * maxEntropy50) * fisherRaoApprox p q := hNL
_ ≤ maxEntropy50 * fisherRaoApprox p q :=
mul_le_mul_of_nonneg_right hsqrt_le (Real.sqrt_nonneg _)
_ < maxEntropy50 * (1 / 10) := mul_lt_mul_of_pos_left (by linarith) hM
_ = 1 / 10 * maxEntropy50 := by ring
have hNdiff : |normalizedEntropy p - normalizedEntropy q| < 1 / 10 := by
have heq : normalizedEntropy p - normalizedEntropy q =
(siteEntropy p - siteEntropy q) / maxEntropy50 := by
simp [normalizedEntropy, sub_div]
-- |N|·M = |S| (by dividing), then nlinarith from |S| < (1/10)·M
have hmul : |normalizedEntropy p - normalizedEntropy q| * maxEntropy50 =
|siteEntropy p - siteEntropy q| := by
rw [heq, abs_div, abs_of_pos hM]; field_simp [hM.ne']
nlinarith [abs_nonneg (normalizedEntropy p - normalizedEntropy q)]
-- 4. Case analysis
show (if normalizedEntropy p ≥ 39321 / 65536 then true else false) =
(if normalizedEntropy q ≥ 39321 / 65536 then true else false)
(normalizedEntropy p > 26214 / 65536 ∧ normalizedEntropy q > 26214 / 65536)
split_ifs with h1 h2
· left; rfl
· -- p ≥ T₁, q < T₁ → N(q) > N(p) - 0.1 ≥ T₁ - 0.1 > T₂
right
have h2' : normalizedEntropy q < 39321 / 65536 := not_le.mp h2
have hnn : (0 : ) ≤ normalizedEntropy p - normalizedEntropy q := by linarith
have hd : normalizedEntropy p - normalizedEntropy q < 1 / 10 := by
rwa [abs_of_nonneg hnn] at hNdiff
constructor
· linarith [show (39321 : ) / 65536 > 26214 / 65536 from by norm_num]
· linarith [show (39321 : ) / 65536 - 1 / 10 > 26214 / 65536 from by norm_num]
· -- p < T₁, q ≥ T₁ → N(p) > N(q) - 0.1 ≥ T₁ - 0.1 > T₂
right
have h1' : normalizedEntropy p < 39321 / 65536 := not_le.mp h1
have hneg : normalizedEntropy p - normalizedEntropy q ≤ 0 := by linarith
have habsform : |normalizedEntropy p - normalizedEntropy q| =
normalizedEntropy q - normalizedEntropy p := by
rw [abs_of_nonpos hneg]; ring
have hd : normalizedEntropy q - normalizedEntropy p < 1 / 10 := habsform ▸ hNdiff
constructor
· linarith [show (39321 : ) / 65536 - 1 / 10 > 26214 / 65536 from by norm_num]
· linarith [show (39321 : ) / 65536 > 26214 / 65536 from by norm_num]
· left; rfl
end BindingSite

View file

@ -1,17 +1,85 @@
/-
BindingSiteHachimoji.lean — Minimal shim for Chentsov 50-state theorem
BindingSite.BindingSiteHachimoji — Amino acid encoding and Fisher metric.
Defines the computable core of the binding site pipeline and the noncomputable
Fisher metric used in the §5 theorems of BindingSiteEntropy.lean.
Chentsov uniqueness (ChentsovFinite.lean) is quarantined — it has 15+ sorries
and is a deep geometry result. This file provides the amino acid / state
machinery WITHOUT depending on the Chentsov proof.
-/
import Mathlib.Data.Fin.Basic
import Mathlib.Topology.Basic
import BindingSite.BindingSiteTypes
import Mathlib.Data.Real.Basic
import CoreFormalism.ChentsovFinite
import Mathlib.Data.Fin.Basic
open Real Set
namespace BindingSite
noncomputable def fisherMetric50 (p : Fin 50 → ) (i j : Fin 50) : :=
if i = j then 1 / (p i) else 0
open SilverSight.FixedPoint
theorem chentsov_50 (g : (Fin 50 → ) → Fin 50 → Fin 50 → ) :
∃ c > 0, ∀ p : Fin 50 → , (∀ i, p i > 0) → (∑ i, p i = 1) →
∀ i j, g p i j = c * fisherMetric50 p i j := by
sorry -- TODO: apply chentsov_theorem from ChentsovFinite.lean
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Amino acid probability distribution (for math §5 only)
-- ═══════════════════════════════════════════════════════════════════════════
/-- A probability distribution over 50 atom types (Void-X parameterization).
Used only in noncomputable Fisher metric theorems; not in the compute path. -/
structure AminoAcidDistribution where
val : Fin 50 →
pos : ∀ i, 0 < val i
sum_eq : ∑ i, val i = 1
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 Fisher metric (noncomputable — appears only in math section)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Fisher information metric on Δ⁴⁹ (50-dimensional probability simplex).
Diagonal form: g_ij(p) = δ_ij / p_i.
Uniqueness up to positive scalar: Chentsov's theorem (quarantined). -/
noncomputable def fisherMetric50 (p : AminoAcidDistribution) (i j : Fin 50) : :=
if i = j then 1 / p.val i else 0
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Dominant state extractor
-- ═══════════════════════════════════════════════════════════════════════════
/-- Return the most common BindingSiteState in a list of classified residues.
Tie-breaking: earlier states win. -/
def dominantState (residues : List BindingSiteResidue) : BindingSiteState :=
let counts : List (BindingSiteState × Nat) :=
[ (.Phi, residues.countP (·.state == .Phi))
, (.Lambda, residues.countP (·.state == .Lambda))
, (.Rho, residues.countP (·.state == .Rho))
, (.Kappa, residues.countP (·.state == .Kappa))
, (.Omega, residues.countP (·.state == .Omega))
, (.Sigma, residues.countP (·.state == .Sigma))
, (.Pi, residues.countP (·.state == .Pi))
, (.Zeta, residues.countP (·.state == .Zeta))
]
(counts.foldl (fun (best : BindingSiteState × Nat) pair =>
if pair.2 > best.2 then pair else best) (.Zeta, 0)).1
-- ═══════════════════════════════════════════════════════════════════════════
-- §4 Profile builder
-- ═══════════════════════════════════════════════════════════════════════════
/-- Build a BindingSiteProfile from a list of classified residues.
All arithmetic is Q16_16; no Float. -/
def buildProfile
(classified : List (AminoAcidToken × Q16_16 × BindingSiteState))
: BindingSiteProfile :=
let entropies := classified.map (·.2.1)
let dominant := dominantState (classified.map fun (t, e, s) =>
{ token := t, entropy := e, state := s
, position := (Q16_16.zero, Q16_16.zero, Q16_16.zero)
, bindability := Q16_16.ofNat 50 })
{ residues := classified.map fun (t, e, s) =>
{ token := t, entropy := e, state := s
, position := (Q16_16.zero, Q16_16.zero, Q16_16.zero)
, bindability := Q16_16.ofNat 50 }
, totalEntropy := q16Mean entropies
, maxEntropy := q16Max entropies
, minEntropy := q16Min entropies
, siteState := dominant
, druggable := dominant == .Pi || dominant == .Lambda
, receiptHash := "PENDING" }
end BindingSite

View file

@ -700,12 +700,12 @@ theorem eigensolid_trivial (s : BraidState) (h_eig : IsEigensolid s)
_ = PhaseVec.normApprox PhaseVec.zero := by rw [hzi_zero]
_ = Q16_16.zero := by
have : PhaseVec.normApprox PhaseVec.zero = Q16_16.zero := by
native_decide
rfl
rw [this]
calc
(s.strands i).bracket.kappa = Q16_16.zero := h_kappa
_ ≤ Q16_16.ofRawInt 16384 := by
native_decide
decide
/-- The zero genus layer: eigensolid states that are topologically trivial.
Every element of this set encodes a genus-0 braid state with no persistent
@ -738,26 +738,10 @@ example : inZeroGenusLayer
constructor
· unfold IsEigensolid
intro i
match i with
| 0 => native_decide
| 1 => native_decide
| 2 => native_decide
| 3 => native_decide
| 4 => native_decide
| 5 => native_decide
| 6 => native_decide
| 7 => native_decide
fin_cases i <;> simp [crossStep, BraidStrand.zero, braidCross, PhaseVec.add, PhaseVec.zero, BraidBracket.fromPhaseVec, crossSlot] <;> decide
· unfold IsTopologicallyTrivial
intro i
match i with
| 0 => native_decide
| 1 => native_decide
| 2 => native_decide
| 3 => native_decide
| 4 => native_decide
| 5 => native_decide
| 6 => native_decide
| 7 => native_decide
fin_cases i <;> decide
-- ============================================================
-- §9. STARS SPECTRAL PROXY

View file

@ -191,7 +191,6 @@ def append (mmr : MMR) (m : Mountain) : MMR :=
else
cons m (cons top rest)
go mmr m
termination_by mmr
/-- Stability predicate: all mountains have distinct heights.
True iff no merge is pending — the RG fixed point condition. -/
@ -242,7 +241,7 @@ def geometryCost (curvature : ) (_ideal : ) (_metric : Metric) : Q16_16 :=
Q16_16.ofNat (curvature * 65536 / 2)
/-- Adaptation cost function: ratio of current to optimal convergence rate. -/
def adaptationCost (current : ) (optimal : ) (_metric : Metric) : Q16_16 :=
def adaptationCost (current : ) (_optimal : ) (_metric : Metric) : Q16_16 :=
if current == 0 then Q16_16.one
else Q16_16.ofNat (65536 / (current + 1))

View file

@ -5,12 +5,43 @@
(up to positive constant) on the probability simplex Δⁿ that is
invariant under all Markov embeddings (stochastic refinements).
Proof structure (adversarial-reviewed):
1. Permutation invariance → Schur's lemma → metric = λ_N · Euclidean at uniform
2. Equal refinements → λ_{Nm} = mλ_N → C = λ_N/N is dimension-independent
3. Rational points → refine to uniform → g_p = C · fisherMetric
4. Density + smoothness → extends to all p ∈ Δⁿ
5. Positivity → C > 0
Classical source: N.N. Chentsov, "Statistical Decision Rules and Optimal Inference"
(Nauka, 1972; AMS Translation, 1982), Chapter 12.
Proof structure — TRACEABILITY MAP:
┌─────────────────────────────────────────────────────────────────────────────┐
│ STEP │ CLAIM │ STATUS │
├──────┼────────────────────────────────────────────┼─────────────────────────┤
│ §1 │ Simplex / tangent space definitions │ PROVEN (Lean) │
│ §2 │ Markov split map: apply, pushforward │ PROVEN (Lean) │
│ §2 │ pushforward_sum_eq, pushforward_tangent │ PROVEN (Lean) │
│ §3 │ Fisher metric: sym, pos_def, linearity │ PROVEN (Lean) │
│ §5 │ fisher_chentsov_invariance │ PROVEN (Lean) │
│ §6 │ metric_at_uniform (Schur's lemma) │ PROVEN (Lean) │
│ §7 │ equal_refinement_const: λ_N/N = C const │ AXIOM — see §7 note │
│ §8 │ fisher_on_rational: g_p = C·fisher at │ AXIOM — see §8 note │
│ §9 │ chentsov_theorem: extends to all p ∈ Δⁿ │ AXIOM — see §9 note │
└─────────────────────────────────────────────────────────────────────────────┘
Axiom grounding (what remains to formalize):
§7 Equal-refinements scaling — Chentsov 1982 §12.3: splitting each of N states
into m equal substates maps uniform_N → uniform_{Nm} via a Markov kernel, and
Chentsov-invariance forces λ_{Nm} = m·λ_N, so C = λ_N/N is independent of N.
Requires: constructing the m-way equal-split SplitEmbedding chain.
§8 Rational-point identity — Chentsov 1982 §12.4: any rational p = (k₁/M,…,kₙ/M)
can be reached from uniform_M by a Markov projection kernel. Applying §7
gives g(p) = C·fisherMetric(p) for all rational p.
Requires: existence of a Markov kernel mapping uniform → rational p.
§9 Density + smoothness extension — classical real analysis: rational points are
dense in the open simplex, and smooth functions agreeing on a dense subset
agree everywhere. This closes the theorem for all p ∈ openSimplex n.
Requires: smoothness of g.toFun (given by RiemannianMetric structure) +
density of rationals in openSimplex (standard topology).
ULP note: all fixed-point computations in this file use (not Q16_16).
The Q16_16 / Fisher-Rao bridge lives in FisherRigidity.lean.
-/
import Mathlib.Data.Fin.Basic
@ -88,9 +119,7 @@ def SplitEmbedding.apply {n : } (f : SplitEmbedding n) (p : openSimplex n) :
else
pFn ⟨j.val - 1, by have := i.isLt; omega⟩,
⟨fun j => by
-- beta-reduce (fun j ↦ ...) j before split_ifs can fire
simp only []
have hjlt : j.val < n + 1 := j.isLt
split_ifs with h h' h''
· exact mul_pos f.hq_pos (p.2.1 i)
· exact mul_pos (by linarith [f.hq_lt_one]) (p.2.1 i)
@ -101,18 +130,18 @@ def SplitEmbedding.apply {n : } (f : SplitEmbedding n) (p : openSimplex n) :
have hi1N_lt : i.val + 1 < n + 1 := by have := i.isLt; omega
let iN : Fin (n+1) := ⟨i.val, hiN_lt⟩
let i1N : Fin (n+1) := ⟨i.val + 1, hi1N_lt⟩
-- rfl facts so omega can reason through Fin constructors
have hiN_val : iN.val = i.val := rfl
have hi1N_val : i1N.val = i.val + 1 := rfl
have hi1N_ne_iN : i1N ≠ iN := by
intro h; exact absurd (congr_arg Fin.val h) (by simp [hiN_val, hi1N_val]; omega)
intro h; exact absurd (congr_arg Fin.val h) (by simp [hiN_val, hi1N_val])
have hi1N_mem : i1N ∈ Finset.univ.erase iN :=
Finset.mem_erase.mpr ⟨hi1N_ne_iN, Finset.mem_univ _⟩
-- dite so branch conditions are in scope for the Fin bound proofs
let body : Fin (n+1) → := fun j =>
if j.val = i.val then q * pFn i
else if j.val = i.val + 1 then (1 - q) * pFn i
else if j.val < i.val then pFn ⟨j.val, by have := i.isLt; omega⟩
else pFn ⟨j.val - 1, by have := i.isLt; omega⟩
if h1 : j.val = i.val then q * pFn i
else if h2 : j.val = i.val + 1 then (1 - q) * pFn i
else if h3 : j.val < i.val then pFn ⟨j.val, by omega⟩
else pFn ⟨j.val - 1, by have := j.isLt; omega⟩
show ∑ j : Fin (n+1), body j = 1
have hbody_iN : body iN = q * pFn i := by dsimp only [body, iN]; simp
have hbody_i1N : body i1N = (1 - q) * pFn i := by
@ -127,64 +156,52 @@ def SplitEmbedding.apply {n : } (f : SplitEmbedding n) (p : openSimplex n) :
have hrest : ∑ j ∈ (Finset.univ.erase iN).erase i1N, body j =
∑ k ∈ Finset.univ.erase i, pFn k :=
Finset.sum_nbij'
(fun j => if j.val < i.val then (⟨j.val, by have := i.isLt; omega⟩ : Fin n)
else ⟨j.val - 1, by have := i.isLt; omega⟩)
(fun k => if k.val < i.val then (⟨k.val, by have := i.isLt; omega⟩ : Fin (n+1))
(fun j => if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩)
(fun k => if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩)
-- forward image ∈ erase i
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
-- extract numeric ne conditions via congr_arg Fin.val
have hj1 : j.val ≠ i.val + 1 :=
fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val :=
fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
split_ifs with h
· exact fun heq => hj2 (congr_arg Fin.val heq)
· exact fun heq => absurd (congr_arg Fin.val heq) (by omega))
-- backward image ∈ rest
intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
constructor
· split_ifs with h
· exact fun heq => absurd (congr_arg Fin.val heq) (by rw [hi1N_val]; omega)
· exact fun heq => absurd (congr_arg Fin.val heq) (by rw [hi1N_val]; omega)
· split_ifs with h
· exact fun heq => absurd (congr_arg Fin.val heq) (by rw [hiN_val]; omega)
· exact fun heq => absurd (congr_arg Fin.val heq) (by rw [hiN_val]; omega))
-- left inverse: ψ(φ(j)) = j
· intro heq
have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega
· intro heq
have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 :=
fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val :=
fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
split_ifs with h1 h2
· exact Fin.ext rfl
· omega
· omega
· exact Fin.ext (by omega))
-- right inverse: φ(ψ(k)) = k
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
apply Fin.ext; simp only []
have key : (if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩).val =
if j.val < i.val then j.val else j.val - 1 := by
split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
split_ifs with h1 h2
· exact Fin.ext rfl
· omega
· omega
· exact Fin.ext (by omega))
-- body(j) = pFn(φ(j))
apply Fin.ext; simp only []
have key : (if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩).val =
if k.val < i.val then k.val else k.val + 1 := by
split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 :=
fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val :=
fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
dsimp only [body]
simp only [if_neg hj2, if_neg hj1]
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
dsimp only [body]; simp only [dif_neg hj2, dif_neg hj1]
split_ifs <;> rfl)
linarith [hea1, hea2, hbody_iN, hbody_i1N, hrest, hpsum_erase,
show q * pFn i + (1 - q) * pFn i = pFn i from by ring]
@ -193,29 +210,102 @@ def SplitEmbedding.apply {n : } (f : SplitEmbedding n) (p : openSimplex n) :
def SplitEmbedding.pushforward {n : } (f : SplitEmbedding n) (p : openSimplex n)
(X : Fin n → ) : Fin (refinedSize f) → :=
let i := f.splitIdx
-- Simple duplication: X_i appears at both i and i+1
let q := f.q
let pFn := p.1
fun (j : Fin (n+1)) =>
if h : j.val = i.val then
X i
q * X i
else if h' : j.val = i.val + 1 then
X i
(1 - q) * X i
else if h'' : j.val < i.val then
X ⟨j.val, by omega⟩
else
X ⟨j.val - 1, by omega⟩
/-- Fisher invariance pushforward property: the pushforward of a zero-sum vector
remains zero-sum when using the correct Fisher pushforward formula. -/
axiom pushforward_sum_fisher (n : ) (f : SplitEmbedding n) (p : openSimplex n)
lemma SplitEmbedding.pushforward_sum_eq {n : } (f : SplitEmbedding n) (p : openSimplex n) (X : Fin n → ) :
∑ j : Fin (n+1), f.pushforward p X j = ∑ i : Fin n, X i := by
let i := f.splitIdx
have hi_lt : i.val < n + 1 := by have := i.isLt; omega
have hi1_lt : i.val + 1 < n + 1 := by have := i.isLt; omega
let iN : Fin (n+1) := ⟨i.val, hi_lt⟩
let i1N : Fin (n+1) := ⟨i.val + 1, hi1_lt⟩
have hiN_val : iN.val = i.val := rfl
have hi1N_val : i1N.val = i.val + 1 := rfl
have hi1N_ne_iN : i1N ≠ iN :=
fun h => absurd (congr_arg Fin.val h) (by simp [hiN_val, hi1N_val])
have hi1N_mem : i1N ∈ Finset.univ.erase iN :=
Finset.mem_erase.mpr ⟨hi1N_ne_iN, Finset.mem_univ _⟩
have hea1 : ∑ j ∈ Finset.univ.erase iN, f.pushforward p X j + f.pushforward p X iN =
∑ j : Fin (n+1), f.pushforward p X j :=
Finset.sum_erase_add Finset.univ _ (Finset.mem_univ iN)
have hea2 : ∑ j ∈ (Finset.univ.erase iN).erase i1N, f.pushforward p X j + f.pushforward p X i1N =
∑ j ∈ Finset.univ.erase iN, f.pushforward p X j :=
Finset.sum_erase_add (Finset.univ.erase iN) _ hi1N_mem
have h_sf_eq : (↑f.splitIdx : ) = ↑i := rfl
have hpf_iN : f.pushforward p X iN = f.q * X i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have hpf_i1N : f.pushforward p X i1N = (1 - f.q) * X i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have hpsum_erase : ∑ k ∈ Finset.univ.erase i, X k + X i = ∑ k : Fin n, X k :=
Finset.sum_erase_add Finset.univ X (Finset.mem_univ i)
have hrest : ∑ j ∈ (Finset.univ.erase iN).erase i1N, f.pushforward p X j =
∑ k ∈ Finset.univ.erase i, X k :=
Finset.sum_nbij'
(fun j => if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩)
(fun k => if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
constructor
· intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega
· intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
apply Fin.ext; simp only []
have key : (if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩).val =
if j.val < i.val then j.val else j.val - 1 := by split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
apply Fin.ext; simp only []
have key : (if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩).val =
if k.val < i.val then k.val else k.val + 1 := by split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
simp only [SplitEmbedding.pushforward, dif_neg hj2, dif_neg hj1]
split_ifs <;> first | rfl | omega)
linarith [hea1, hea2, hpf_iN, hpf_i1N, hpsum_erase, hrest,
show f.q * X i + (1 - f.q) * X i = X i from by ring]
theorem SplitEmbedding.pushforward_preserves_sum {n : } (f : SplitEmbedding n) (p : openSimplex n)
(X : Fin n → ) (hX : ∑ i, X i = 0) :
∑ j, f.pushforward p X j = 0
∑ j : Fin (n+1), f.pushforward p X j = 0 := by
rw [f.pushforward_sum_eq p X, hX]
lemma SplitEmbedding.pushforward_tangent {n : } (f : SplitEmbedding n) (p : openSimplex n)
(X : Fin n → ) (hX : X ∈ tangentSpace p) :
f.pushforward p X ∈ tangentSpace (f.apply p) := by
exact pushforward_sum_fisher n f p X hX
end MarkovEmbeddings
exact f.pushforward_preserves_sum p X hX
-- ============================================================
-- §3 FISHER INFORMATION METRIC
@ -310,21 +400,114 @@ end ChentsovInvariance
section FisherIsInvariant
/-! Axiom: Fisher metric invariance under Markov split embeddings.
This is the core Chentsov invariance property, proven via:
/-! Theorem: Fisher metric invariance under Markov split embeddings.
The Fisher-Rao cotangent lift preserves the metric:
g(p', pushforward X, pushforward Y) = g(p, X, Y)
where pushforward uses the Fisher-Rao cotangent lift formula. -/
axiom fisher_chentsov_invariance (n : ) (f : SplitEmbedding n) (p : openSimplex n)
because q·X_i·(q·Y_i)/(q·p_i) + (1-q)·X_i·((1-q)·Y_i)/((1-q)·p_i) = X_i·Y_i/p_i. -/
theorem fisher_chentsov_invariance (n : ) (f : SplitEmbedding n) (p : openSimplex n)
(X Y : Fin n → ) (hXsum : ∑ i, X i = 0) (hYsum : ∑ i, Y i = 0) :
fisherMetric p X Y = fisherMetric (f.apply p) (f.pushforward p X) (f.pushforward p Y)
lemma fisherMetric_chentsov_invariant {n : } :
IsChentsovInvariant (⟨fisherMetric, fisherMetric_linear_left, fisherMetric_linear_right,
fisherMetric_sym, @fisherMetric_pos_def n⟩ : RiemannianMetric n)
(⟨fisherMetric, fisherMetric_linear_left, fisherMetric_linear_right,
fisherMetric_sym, @fisherMetric_pos_def (n+1)⟩ : RiemannianMetric (n+1)) := by
intro f p X Y hXsum hYsum
exact fisher_chentsov_invariance n f p X Y hXsum hYsum
fisherMetric p X Y = fisherMetric (f.apply p) (f.pushforward p X) (f.pushforward p Y) := by
let i := f.splitIdx
let q := f.q
have hi_lt : i.val < n + 1 := by have := i.isLt; omega
have hi1_lt : i.val + 1 < n + 1 := by have := i.isLt; omega
let iN : Fin (n+1) := ⟨i.val, hi_lt⟩
let i1N : Fin (n+1) := ⟨i.val + 1, hi1_lt⟩
have hiN_val : iN.val = i.val := rfl
have hi1N_val : i1N.val = i.val + 1 := rfl
have hi1N_ne_iN : i1N ≠ iN :=
fun h => absurd (congr_arg Fin.val h) (by simp [hiN_val, hi1N_val])
have hi1N_mem : i1N ∈ Finset.univ.erase iN :=
Finset.mem_erase.mpr ⟨hi1N_ne_iN, Finset.mem_univ _⟩
-- Compute sum over (erase iN).erase i1N via bijection
have h_rest : ∑ j ∈ (Finset.univ.erase iN).erase i1N,
(f.pushforward p X j) * (f.pushforward p Y j) / (f.apply p).1 j =
∑ k ∈ Finset.univ.erase i, X k * Y k / p.1 k :=
Finset.sum_nbij'
(fun j => if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩)
(fun k => if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
simp only [Finset.mem_erase, Finset.mem_univ, and_true]
constructor
· intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega
· intro heq; have h_eq := congr_arg Fin.val heq
split_ifs at h_eq with h <;> dsimp only [] at h_eq <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
apply Fin.ext; simp only []
have key : (if h : j.val < i.val then (⟨j.val, by omega⟩ : Fin n)
else ⟨j.val - 1, by have := j.isLt; omega⟩).val =
if j.val < i.val then j.val else j.val - 1 := by split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun k hk => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hk
have hkne : k.val ≠ i.val := fun h => hk (Fin.ext h)
apply Fin.ext; simp only []
have key : (if k.val < i.val then (⟨k.val, by have := k.isLt; omega⟩ : Fin (n+1))
else ⟨k.val + 1, by have := k.isLt; omega⟩).val =
if k.val < i.val then k.val else k.val + 1 := by split_ifs <;> rfl
simp only [key]; split_ifs <;> dsimp only [] <;> omega)
(fun j hj => by
simp only [Finset.mem_erase, Finset.mem_univ, and_true] at hj
have hj1 : j.val ≠ i.val + 1 := fun h => hj.1 (Fin.ext (by rw [hi1N_val]; exact h))
have hj2 : j.val ≠ i.val := fun h => hj.2 (Fin.ext (by rw [hiN_val]; exact h))
simp only [SplitEmbedding.pushforward, SplitEmbedding.apply, dif_neg hj2, dif_neg hj1]
split_ifs <;> first | rfl | omega)
-- Split-point contributions cancel: q*X*Y/(q*p) + (1-q)*X*Y/((1-q)*p) = X*Y/p
-- h_sf_eq gives omega the arithmetic link between f.splitIdx and i (both -valued)
have h_sf_eq : (↑f.splitIdx : ) = ↑i := rfl
have hpf_iN_X : f.pushforward p X iN = q * X i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have hpf_iN_Y : f.pushforward p Y iN = q * Y i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have hpf_i1N_X : f.pushforward p X i1N = (1 - q) * X i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have hpf_i1N_Y : f.pushforward p Y i1N = (1 - q) * Y i := by
simp only [SplitEmbedding.pushforward]; split_ifs <;> first | rfl | omega
have happly_iN : (f.apply p).1 iN = q * p.1 i := by
simp only [SplitEmbedding.apply]; split_ifs <;> first | rfl | omega
have happly_i1N : (f.apply p).1 i1N = (1 - q) * p.1 i := by
simp only [SplitEmbedding.apply]; split_ifs <;> first | rfl | omega
have h_split : (f.pushforward p X iN) * (f.pushforward p Y iN) / (f.apply p).1 iN +
(f.pushforward p X i1N) * (f.pushforward p Y i1N) / (f.apply p).1 i1N =
X i * Y i / p.1 i := by
rw [hpf_iN_X, hpf_iN_Y, happly_iN, hpf_i1N_X, hpf_i1N_Y, happly_i1N]
have hpi_pos : p.1 i > 0 := p.2.1 i
have hq_pos : q > 0 := f.hq_pos
have hq_lt : q < 1 := f.hq_lt_one
field_simp [ne_of_gt hpi_pos, ne_of_gt hq_pos, show (1 : ) - q ≠ 0 by linarith]
ring
-- Combine: split fisherMetric sums
have hea_lhs : ∑ j ∈ Finset.univ.erase iN, f.pushforward p X j * f.pushforward p Y j / (f.apply p).1 j +
f.pushforward p X iN * f.pushforward p Y iN / (f.apply p).1 iN =
∑ j : Fin (n+1), f.pushforward p X j * f.pushforward p Y j / (f.apply p).1 j :=
Finset.sum_erase_add Finset.univ _ (Finset.mem_univ iN)
have hea2_lhs : ∑ j ∈ (Finset.univ.erase iN).erase i1N, f.pushforward p X j * f.pushforward p Y j / (f.apply p).1 j +
f.pushforward p X i1N * f.pushforward p Y i1N / (f.apply p).1 i1N =
∑ j ∈ Finset.univ.erase iN, f.pushforward p X j * f.pushforward p Y j / (f.apply p).1 j :=
Finset.sum_erase_add (Finset.univ.erase iN) _ hi1N_mem
have hea_rhs : ∑ k ∈ Finset.univ.erase i, X k * Y k / p.1 k + X i * Y i / p.1 i =
∑ k : Fin n, X k * Y k / p.1 k :=
Finset.sum_erase_add Finset.univ _ (Finset.mem_univ i)
-- Prove sum equality first (notation stays consistent with hypotheses: p.1 not ↑p)
have sum_eq : ∑ j : Fin (n+1), f.pushforward p X j * f.pushforward p Y j / (f.apply p).1 j =
∑ k : Fin n, X k * Y k / p.1 k :=
by linarith [hea_lhs, hea2_lhs, hea_rhs, h_rest, h_split]
simp only [fisherMetric]; exact sum_eq.symm
end FisherIsInvariant
@ -655,8 +838,16 @@ end UniformMetric
section RefinementConstant
/-- Equal refinement: split each state into m equal substates.
This axiom captures the dimension-independent constant derivation. -/
/-- Equal refinement: split each state into m equal substates → constant C = λ_N/N is
dimension-independent.
Classical ground: Chentsov 1982 §12.3. Argument: the m-way equal split of N states
produces a Markov embedding mapping uniform_N to uniform_{Nm}. Chentsov-invariance
then forces g(uniform_{Nm}) = m · g(uniform_N), i.e. λ_{Nm} = m · λ_N. Setting
C = λ_N / N (which equals λ_{Nm} / (Nm) = C) shows C is independent of N and m.
To formalize: build the chain of m equal-split SplitEmbeddings and compose apply/
pushforward; the sum constraints close by induction. -/
axiom equal_refinement_const_axiom {N m : } (hN : N ≥ 2) (hm : m ≥ 1)
(g : ∀ n, RiemannianMetric n)
(h_inv : ∀ n, IsChentsovInvariant (g n) (g (n+1)))
@ -680,7 +871,16 @@ end RefinementConstant
section RationalPoints
/-- For rational p: g_p = C · fisherMetric (axiomatized). -/
/-- For rational p: g_p = C · fisherMetric.
Classical ground: Chentsov 1982 §12.4. Argument: any rational distribution
p = (k₁/M, …, k_N/M) with Σkᵢ = M is a marginal of uniform_M under the
Markov projection kernel that maps state j ∈ {1,…,M} to state i iff
j ∈ {k₁+…+kᵢ₋₁+1, …, k₁+…+kᵢ}. Chentsov-invariance + equal_refinement_const
then gives g(p) = C · fisherMetric(p).
To formalize: construct the Markov projection kernel as a composition of
SplitEmbeddings with appropriate weights; equal_refinement_const supplies C. -/
axiom fisher_on_rational_axiom {N : } (hN : N ≥ 2)
(g : ∀ n, RiemannianMetric n)
(h_inv : ∀ n, IsChentsovInvariant (g n) (g (n+1)))
@ -708,9 +908,24 @@ end RationalPoints
section ChentsovTheorem
/-- Chentsov's theorem: IsChentsovInvariant + IsPermutationInvariant → scalar multiple of Fisher metric -/
/-- Chentsov's theorem: IsChentsovInvariant + IsPermutationInvariant → scalar multiple of Fisher metric.
Classical ground: Chentsov 1982 §12.5 + standard real analysis.
Chain of reasoning:
(a) metric_at_uniform (§6, PROVEN): g at uniform_N = λ_N · Euclidean (Schur's lemma).
(b) equal_refinement_const (§7, AXIOM): C = λ_N/N is dimension-independent.
(c) fisher_on_rational (§8, AXIOM): g_p = C · fisherMetric for rational p ∈ Δⁿ.
(d) Density + smoothness (this axiom): rational points are dense in openSimplex n
(standard: -valued distributions form a dense subset of the open simplex),
and g.toFun is smooth by the RiemannianMetric structure axiom (h_smooth).
Two smooth functions agreeing on a dense set agree everywhere. QED.
h_smooth : True is a placeholder; the proof requires g.toFun to be C∞ in p.
Formalizing (d) requires: Mathlib.Topology.Algebra.Order.LiminfLimsup or
Mathlib.Analysis.SpecificLimits.Basic for rational density + continuity of g. -/
axiom chentsov_theorem_axiom (n : ) (hn : n ≥ 3) (g : RiemannianMetric n)
(h_inv : IsChentsovInvariant g)
(g_succ : RiemannianMetric (n + 1))
(h_inv : IsChentsovInvariant g g_succ)
(h_perm : IsPermutationInvariant g)
(h_smooth : True) :
∃ (c : ), c > 0 ∧ ∀ (p : openSimplex n) (X Y : Fin n → ),
@ -718,12 +933,13 @@ axiom chentsov_theorem_axiom (n : ) (hn : n ≥ 3) (g : RiemannianMetric n)
g.toFun p X Y = c * fisherMetric p X Y
theorem chentsov_theorem (n : ) (hn : n ≥ 3) (g : RiemannianMetric n)
(h_inv : IsChentsovInvariant g)
(g_succ : RiemannianMetric (n + 1))
(h_inv : IsChentsovInvariant g g_succ)
(h_perm : IsPermutationInvariant g)
(h_smooth : True) :
∃ (c : ), c > 0 ∧ ∀ (p : openSimplex n) (X Y : Fin n → ),
(∑ i, X i = 0) → (∑ i, Y i = 0) →
g.toFun p X Y = c * fisherMetric p X Y := by
exact chentsov_theorem_axiom n hn g h_inv h_perm h_smooth
exact chentsov_theorem_axiom n hn g g_succ h_inv h_perm h_smooth
end ChentsovTheorem

View file

@ -25,7 +25,7 @@
the same phenomenon in the Baker landscape.
-/
import Mathlib.Data.Equiv.Basic
import Mathlib.Logic.Equiv.Basic
import Mathlib.Tactic
import CoreFormalism.HachimojiManifoldAxiom
import SilverSight.RRCLogogramProjection
@ -44,8 +44,8 @@ inductive HachimojiBase where
| Ρ -- rho: tight regime — near spectral radius ρ(J) = 1 stability boundary
| Κ -- kap: marginal — at complementarity threshold κ (BraidBracket.kappa)
| Ω -- ome: collision — Λ(m,n) = 0 exactly, terminal eigensolid state
| Σ -- sig: symmetric partner — σ-symmetry of a known Goormaghtigh solution
| Π -- pi: potential violation — Π density probe below Baker threshold
| Sig -- sig: symmetric partner — σ-symmetry of a known Goormaghtigh solution
| Pi -- pi: potential violation — Π density probe below Baker threshold
| Ζ -- zet: zero region — near ζ-zeros; |Λ| ≈ 0 but no integer lattice point
deriving DecidableEq, Repr, Fintype
@ -65,8 +65,8 @@ def hachimojiGreekEquiv : HachimojiBase ≃ Greek.HachimojiBase where
| .G => .Ρ
| .C => .Κ
| .B => .Ω
| .S => .Σ
| .P => .Π
| .S => .Sig
| .P => .Pi
| .Z => .Ζ
invFun := fun g => match g with
| .Φ => .A
@ -74,8 +74,8 @@ def hachimojiGreekEquiv : HachimojiBase ≃ Greek.HachimojiBase where
| .Ρ => .G
| .Κ => .C
| .Ω => .B
| .Σ => .S
| .Π => .P
| .Sig => .S
| .Pi => .P
| .Ζ => .Z
left_inv := by intro b; cases b <;> rfl
right_inv := by intro g; cases g <;> rfl
@ -168,8 +168,8 @@ def Greek.HachimojiBase.phase : Greek.HachimojiBase →
| .Ρ => 90
| .Κ => 135
| .Ω => 180
| .Σ => 225
| .Π => 270
| .Sig => 225
| .Pi => 270
| .Ζ => 315
/-- Chirality derived from phase per Omindirection Principle 3. -/
@ -193,10 +193,7 @@ def Greek.HachimojiBase.direction (g : Greek.HachimojiBase) : FlowDirection :=
theorem forward_states_are_normal (g : Greek.HachimojiBase)
(h : g.direction = .forward) :
g = .Φ g = .Λ g = .Ρ g = .Κ := by
cases g <;> simp [Greek.HachimojiBase.direction, Greek.HachimojiBase.phase] at h ⊢ <;>
first | exact Or.inl rfl | exact Or.inr (Or.inl rfl) |
exact Or.inr (Or.inr (Or.inl rfl)) | exact Or.inr (Or.inr (Or.inr rfl)) |
simp at h
cases g <;> simp [Greek.HachimojiBase.direction, Greek.HachimojiBase.phase] at h ⊢
-- ============================================================
-- §6 BIDIRECTIONAL QAOA DECODER → LOGOGRAM RECEIPT
@ -210,13 +207,13 @@ theorem forward_states_are_normal (g : Greek.HachimojiBase)
-- bit 0 → Φ bit 1 → Λ bit 2 → Ρ bit 3 → Κ
-- bit 4 → Ω bit 5 → Σ bit 6 → Π bit 7 → Ζ
open Semantics.RRCLogogramProjection
open SilverSight.RRCLogogramProjection
/-- Decode a single bit index to its Greek state. -/
def bitToGreek (i : Fin 8) : Greek.HachimojiBase :=
match i.val with
| 0 => .Φ | 1 => .Λ | 2 => .Ρ | 3 => .Κ
| 4 => .Ω | 5 => .Σ | 6 => .Π | _ => .Ζ
| 4 => .Ω | 5 => .Sig | 6 => .Pi | _ => .Ζ
/-- Decode a Greek state to the LogogramReceipt Bool fields it controls.
Returns (payloadBound, contradictionWitness, tearBoundary, detachedMass, residualLane). -/
@ -228,8 +225,8 @@ def greekToReceiptBits (g : Greek.HachimojiBase) :
| .Ρ => (false, false, false, false, true) -- residualLane active
| .Κ => (false, false, false, true, false) -- detachedMass (marginal)
| .Ω => (true, true, true, true, true) -- full tear repair witness
| .Σ => (false, false, true, false, false) -- tearBoundary (symmetric)
| .Π => (false, false, false, false, false) -- no Bool fields; regime=horrible
| .Sig => (false, false, true, false, false) -- tearBoundary (symmetric)
| .Pi => (false, false, false, false, false) -- no Bool fields; regime=horrible
| .Ζ => (false, false, false, true, false) -- detachedMass (near-zero)
/-- Derive SemanticRegime from the dominant Greek state. -/
@ -237,7 +234,7 @@ def greekToRegime (g : Greek.HachimojiBase) : SemanticRegime :=
match g with
| .Φ | .Λ => .beautifulTopologicalFolding
| .Ρ | .Κ => .uglyAsymmetricPruning
| .Ω | .Σ | .Π | .Ζ => .horribleManifoldTearing
| .Ω | .Sig | .Pi | .Ζ => .horribleManifoldTearing
/-- Full bidirectional decoder: QAOA bitstring → LogogramReceipt.
Uses the Greek state of the LOWEST active bit as the dominant state.
@ -250,8 +247,8 @@ def fromQAOABitstring (bits : Fin 8 → Bool) : LogogramReceipt :=
else if bits ⟨2, by omega⟩ then .Ρ
else if bits ⟨3, by omega⟩ then .Κ
else if bits ⟨4, by omega⟩ then .Ω
else if bits ⟨5, by omega⟩ then .Σ
else if bits ⟨6, by omega⟩ then .Π
else if bits ⟨5, by omega⟩ then .Sig
else if bits ⟨6, by omega⟩ then .Pi
else .Ζ
-- Accumulate Bool fields from ALL active bits
let fold8 (init : Bool × Bool × Bool × Bool × Bool)
@ -285,7 +282,7 @@ def toQAOABitstring (r : LogogramReceipt) : Fin 8 → Bool
| ⟨5, _⟩ => r.tearBoundary -- Σ
| ⟨6, _⟩ => r.regime == .horribleManifoldTearing -- Π
| ⟨7, _⟩ => r.status == .hold -- Ζ
| ⟨i, _⟩ => false
| ⟨_, _⟩ => false
-- ============================================================
-- §7 COLLISION STATES IN GREEK ENCODING

View file

@ -145,13 +145,13 @@ def latinIndex (b : LatinBase) : Fin 8 :=
/-- Classify a non-negative real x by threshold t > 0.
Mirrors hachimojiClassify in HachimojiManifoldAxiom.
Noncomputable because has noncomputable DecidableEq. -/
noncomputable def classifyThreshold (x t : ) (ht : t > 0) : LatinBase :=
if hx0 : x = 0 then .B
else if h : x < t / 4 then .Z
else if h : x < t then .P
else if h : x < 2 * t then .C
else if h : x < 4 * t then .G
else if h : x < 8 * t then .T
noncomputable def classifyThreshold (x t : ) (_ht : t > 0) : LatinBase :=
if _ : x = 0 then .B
else if _ : x < t / 4 then .Z
else if _ : x < t then .P
else if _ : x < 2 * t then .C
else if _ : x < 4 * t then .G
else if _ : x < 8 * t then .T
else .A
-- ============================================================
@ -347,7 +347,7 @@ theorem canonical_states_consistent :
consistencyInvariant StateSigma = true ∧
consistencyInvariant StatePi = true ∧
consistencyInvariant StateΖ = true := by
native_decide
decide
/-- The admission function assigns forward states (Φ, Λ, Ρ, Κ) and
symmetric-partner (Σ) to ADMIT; collision (Ω), potential (Π), and
@ -363,7 +363,7 @@ theorem admission_matches_latin_role :
admission StateSigma = Admission.ADMIT ∧
admission StatePi = Admission.QUARANTINE ∧
admission StateΖ = Admission.QUARANTINE := by
native_decide
decide
/-- For any threshold classification, admission through the Latin bridge
matches the direct admission of the Greek canonical state. -/
@ -380,14 +380,14 @@ theorem pipeline_admits_marginal (t : ) (ht : t > 0) :
admission (fullThresholdPipeline t t ht) = Admission.ADMIT := by
unfold fullThresholdPipeline
rw [classify_t_to_2t_is_C t t ht (by linarith) (by nlinarith)]
native_decide
rfl
/-- The full threshold pipeline quarantines x = 0 (collision case B → Ω → QUARANTINE). -/
theorem pipeline_quarantines_collision (t : ) (ht : t > 0) :
admission (fullThresholdPipeline (0 : ) t ht) = Admission.QUARANTINE := by
unfold fullThresholdPipeline
rw [classify_zero_is_B t ht]
native_decide
decide
-- ============================================================
-- §10 MARKOV PARTITION FOR THE DOUBLING MAP (discrete shadow)
@ -503,7 +503,7 @@ noncomputable def entropyRatio (H_measured : ) (N : ) : :=
placing the system in the room (Λ / T) Hachimoji regime.
This is confirmed by the N=20000 sweep at p=12,14 where
λ > 0.99 and η ≈ 0.81. -/
theorem lambda_near_one_implies_room_regime (p N : ) (hp : p > 0) (hN : N > 0)
(hlam : lambdaBMCTE p N > 0.99) : True := by
theorem lambda_near_one_implies_room_regime (p N : ) (_hp : p > 0) (_hN : N > 0)
(_hlam : lambdaBMCTE p N > 0.99) : True := by
trivial

View file

@ -362,5 +362,4 @@ def isForward (s : HachimojiState4D) : Bool :=
theorem forward_states_exactly (s : HachimojiState4D)
(hφ : s = StateΦ) (hL : s = StateΛ) (hρ : s = StateΡ) (hκ : s = StateΚ) :
isForward s = true := by
rcases hφ <;> rcases hL <;> rcases hρ <;> rcases hκ <;> simp [isForward]
<;> rfl
subst hφ; exact absurd hL (by decide)

View file

@ -306,7 +306,7 @@ theorem canonical_phases_preserved :
stateToPhase StateSigma = ⟨225, by norm_num⟩ ∧
stateToPhase StatePi = ⟨270, by norm_num⟩ ∧
stateToPhase StateΖ = ⟨315, by norm_num⟩ := by
native_decide
decide
-- ============================================================
-- §4 EQUATION → MANIFOLD POSITION
@ -335,7 +335,7 @@ theorem E_mc2_position :
unfold equationPosition
have hclass : classifyEquation { n_vars := 2, n_ops := 2, max_depth := 0,
n_quantifiers := 0, n_relations := 1 } = StateΦ := by
native_decide
decide
rw [hclass, canonical_phases_preserved.1]
/-- Pythagorean theorem lives at the Σ (symmetric) vertex. -/
@ -346,9 +346,9 @@ theorem pythagorean_position :
unfold equationPosition
have hclass : classifyEquation { n_vars := 3, n_ops := 7, max_depth := 0,
n_quantifiers := 0, n_relations := 1 } = StateSigma := by
native_decide
obtain ⟨-, -, -, -, -, hΣ, -, -⟩ := canonical_phases_preserved
rw [hclass, hΣ]
decide
obtain ⟨-, -, -, -, -, hSig, -, -⟩ := canonical_phases_preserved
rw [hclass, hSig]
/-- Contradiction "0 = 1" lives at the Ω (collision) vertex. -/
theorem contradiction_position :
@ -358,7 +358,7 @@ theorem contradiction_position :
unfold equationPosition
have hclass : classifyEquation { n_vars := 0, n_ops := 0, max_depth := 0,
n_quantifiers := 0, n_relations := 1 } = StateΩ := by
native_decide
decide
obtain ⟨-, -, -, -, hΩ, -, -, -⟩ := canonical_phases_preserved
rw [hclass, hΩ]
@ -437,7 +437,7 @@ theorem stability_points :
∀ θ : PhaseCircle, isStabilityPoint θ = true ↔
θ.val = 0 θ.val = 180 := by
have h : ∀ θ : PhaseCircle, isStabilityPoint θ = true ↔ θ.val = 0 θ.val = 180 := by
native_decide
intro θ; fin_cases θ <;> decide
exact h
/-- Φ (phase 0°) is a stability point. -/
@ -456,7 +456,7 @@ theorem other_bases_not_stable :
isStabilityPoint ⟨225, by norm_num⟩ = false ∧
isStabilityPoint ⟨270, by norm_num⟩ = false ∧
isStabilityPoint ⟨315, by norm_num⟩ = false := by
native_decide
decide
-- ============================================================
-- §7 THE MASTER MANIFEST

View file

@ -11,7 +11,7 @@
→ goormaghtigh_from_manifold (derived: uses goormaghtigh_conditional)
IMPORTS:
Semantics.GoormaghtighEnumeration — repunit, bms_bounds, goormaghtigh_conditional
SilverSight.GoormaghtighEnumeration — repunit, bms_bounds, goormaghtigh_conditional
Fixes applied (2026-06-19):
· Import corrected to GoormaghtighEnumeration (not GoormaghtighCert)
@ -20,7 +20,7 @@
· Fixed ∃ barcode, P → Q (vacuous) to ∃ barcode, P ∧ Q (non-vacuous)
· bms_from_manifold returns Finset.Icc membership matching bms_bounds signature
· goormaghtigh_from_manifold uses goormaghtigh_conditional (not missing _complete)
· repunit_mul_pred + repunit_cross_mul stated as lemmas (sorry pending geom-series)
· repunit_mul_pred + repunit_cross_mul proven (geom-series identity via repunit_mul_pred + omega)
· HachimojiBase.card_eq uses Fintype.card, not a bare nat literal
-/
@ -29,9 +29,10 @@ import Mathlib.Analysis.SpecialFunctions.Log.Basic
import Mathlib.Topology.MetricSpace.Basic
import Mathlib.Tactic
import CoreFormalism.ChentsovFinite
import CoreFormalism.GoormaghtighEnumeration
open Real
open Semantics.GoormaghtighEnumeration
open SilverSight.GoormaghtighEnumeration
-- ============================================================
-- §0 THE HACHIMOJI ALPHABET
@ -93,7 +94,7 @@ structure BakerManifold (x y C : ) where
-- Key identity: R(x,m) · (x1) = x^m 1 (geometric series in )
-- Proof: by induction on m, or from (x-1) | (x^m-1) + Nat.div_mul_cancel.
-- Pending: Mathlib name for `(x-1 : ) (x^m - 1 : )`.
lemma repunit_mul_pred (x m : ) (hx : x ≥ 2) (hm : m ≥ 1) :
lemma repunit_mul_pred (x m : ) (hx : x ≥ 2) (_hm : m ≥ 1) :
repunit x m * (x - 1) = x ^ m - 1 := by
simp only [repunit, show ¬(x ≤ 1) from by omega, if_false]
exact Nat.div_mul_cancel (Nat.sub_one_dvd_pow_sub_one x m)
@ -130,11 +131,11 @@ def PersistentClass.persistence (c : PersistentClass) : := c.death - c.birth
lemma PersistentClass.persistence_pos (c : PersistentClass) : 0 < c.persistence :=
sub_pos.mpr c.h_persistent
def PersistenceBarcode := List PersistentClass
abbrev PersistenceBarcode := List PersistentClass
structure BakerBarcode (x y C : ) where
classes : PersistenceBarcode
h_classes : ∀ c ∈ classes, c.dimension ≤ 2
h_classes : ∀ (c : PersistentClass), c ∈ classes → c.dimension ≤ 2
end PersistentHomology
@ -173,7 +174,7 @@ section ManifoldAxiom
LOGICAL STRUCTURE: ∃ barcode, P ∧ Q (NOT the vacuous ∃ barcode, P → Q). -/
axiom hachimoji_manifold_bound :
∀ (x y : ) (hx : x ≥ 2) (hy : y ≥ 2) (hxy : x ≠ y) (C : ) (hC : C ≥ 18),
∀ (x y : ) (_hx : x ≥ 2) (_hy : y ≥ 2) (_hxy : x ≠ y) (C : ) (_hC : C ≥ 18),
∃ (flow : RicciFlow x y C) (t_converge : ),
t_converge > 0 ∧
(∀ p q : × ,
@ -181,7 +182,7 @@ axiom hachimoji_manifold_bound :
hachimojiBakerField x y C p.1 p.2 = hachimojiBakerField x y C q.1 q.2) ∧
∃ (barcode : BakerBarcode x y C),
-- (a) persistence condition (non-vacuous conjunction)
(∀ c ∈ barcode.classes, c.dimension = 0 → c.persistence > 1 / 100) ∧
(∀ (c : PersistentClass), c ∈ barcode.classes → c.dimension = 0 → c.persistence > 1 / 100) ∧
-- (b) B-state ↔ known solution
(∀ m n : , m ≥ 3 → n ≥ 3 →
hachimojiBakerField x y C m n = HachimojiBase.B →
@ -213,16 +214,25 @@ section Derivation
established axiom that is already in place.
The `hne0` side-goal (repunit x m ≠ 0 for x ≥ 2, m ≥ 3) follows from
R(x,m) ≥ 1 + x ≥ 3 but requires the geometric-series identity; left as sorry. -/
repunit_mul_pred: if R(x,m)=0 then x^m-1=0, but x≥2 and m≥1 gives x^m≥x≥2. -/
theorem bms_from_manifold (x m y n : )
(hx : x ≥ 2) (hy : y ≥ 2) (hm : m ≥ 3) (hn : n ≥ 3)
(hx : x ≥ 2) (_hy : y ≥ 2) (hm : m ≥ 3) (_hn : n ≥ 3)
(hxy : x ≠ y) (heq : repunit x m = repunit y n) :
x ∈ Finset.Icc 2 90 ∧ m ∈ Finset.Icc 3 13 ∧
y ∈ Finset.Icc 2 90 ∧ n ∈ Finset.Icc 3 13 := by
apply bms_bounds x m y n heq _ hxy
-- repunit x m ≠ 0: for x ≥ 2, m ≥ 3, R(x,m) ≥ 1+x+x² ≥ 7
simp only [repunit, show ¬(x ≤ 1) from by omega, if_false]
sorry -- Requires geometric-series lower bound: (x^m-1)/(x-1) ≥ x ≥ 2 > 0
-- repunit x m ≠ 0: for x ≥ 2, m ≥ 3, R(x,m) ≥ 1+x ≥ 3 > 0
-- Proof: repunit_mul_pred gives R(x,m)·(x-1) = x^m-1.
-- If R(x,m)=0, then x^m-1=0, so x^m≤1. But x≥2 and m≥1 gives x^m≥x≥2.
-- Contradiction via omega.
have hru := repunit_mul_pred x m hx (by omega)
by_contra h
rw [h, zero_mul] at hru
have hxm : x ≤ x ^ m := by
have h1 : 1 ≤ x := by omega
have h2 : 1 ≤ m := by omega
simpa using (Nat.pow_le_pow_right h1 h2)
omega
/-- **Goormaghtigh from the manifold axiom.**
@ -232,7 +242,7 @@ theorem bms_from_manifold (x m y n : )
AXIOMS USED: hachimoji_manifold_bound (this file) + bms_bounds + ramanujan_nagell
(GoormaghtighEnumeration). -/
theorem goormaghtigh_from_manifold (x m y n : )
(hx : x ≥ 2) (hy : y ≥ 2) (hm : m ≥ 3) (hn : n ≥ 3)
(_hx : x ≥ 2) (_hy : y ≥ 2) (_hm : m ≥ 3) (_hn : n ≥ 3)
(hxy : x ≠ y) (heq : repunit x m = repunit y n)
(hne0 : repunit x m ≠ 0) :
(repunit x m = 31 ∧ ((x = 2 ∧ m = 5 ∧ y = 5 ∧ n = 3)

View file

@ -164,22 +164,22 @@ def pow (base e : Q16_16) : Q16_16 :=
/-- exp(0) = 1 (delegates to FixedPoint.exp). -/
theorem exp_zero : exp zero = one := by
simp only [exp, FixedPoint.Q16_16.exp]
native_decide
rfl
/-- sqrt(0) = 0 (delegates to FixedPoint.sqrt). -/
theorem sqrt_zero : sqrt zero = zero := by
simp only [sqrt, FixedPoint.Q16_16.sqrt]
native_decide
rfl
/-- ln(1) = 0 (delegates to FixedPoint.ln). -/
theorem ln_one : ln one = zero := by
simp only [ln, FixedPoint.Q16_16.ln]
native_decide
rfl
/-- sin(0) = 0 (delegates to FixedPoint.sin). -/
theorem sin_zero : sin zero = zero := by
simp only [sin, FixedPoint.Q16_16.sin]
native_decide
rfl
-- cos(0) = 1 is approximated as sin(pi/2) = 65526 due to Q16.16 quantization.
-- Exact equality would require infinite-precision pi/2.

View file

@ -502,7 +502,7 @@ theorem bms_implies_sieve (x m : ) (hx : x ≥ 2) (hm : m ≥ 3)
(h_bms : x ≤ 90 ∧ m ≤ 13) : sieveCondition x m := by
rcases h_bms with ⟨hx90, hm13⟩
unfold sieveCondition Hkdf hermitePoly
interval_cases x <;> interval_cases m <;> native_decide
interval_cases x <;> interval_cases m <;> decide
-- ---------------------------------------------------------------------------
-- 2e. Sieve Discriminates Repunit Collisions

View file

@ -229,7 +229,7 @@ theorem bms_implies_sieve (x m : ) (hx : x ≥ 2) (hm : m ≥ 3)
-- For each pair, the diagonal H-KdF polynomial evaluates to zero by
-- construction from the PVGS generating function.
-- PROOF: finite enumeration via interval_cases + native_decide.
interval_cases x <;> interval_cases m <;> native_decide
interval_cases x <;> interval_cases m <;> decide
-- ---------------------------------------------------------------------------
-- §2e SIEVE CONDITION DISCRIMINATES REPNIT COLLISIONS

View file

@ -367,7 +367,7 @@ lemma bmsSearchSpace_card_le : bmsSearchSpace.card ≤ 979 := by
unfold bmsSearchSpace
rw [Finset.filter_card_add_filter_neg_card_eq_card]
simp
<;> native_decide
<;> decide
/-- Membership in the BMS search space: characterization. -/
lemma bmsSearchSpace_mem (x m : ) :

View file

@ -1,8 +1,11 @@
import SilverSight.Schema
/-
SilverSight.Semantics.ProductSchema
namespace SilverSight
Extends SilverSight.Semantics.Schema with instances for product types (α × β).
-/
import SilverSight.Semantics.Schema
open Semantics.FixedPoint
namespace SilverSight.Semantics
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Product Schema instance
@ -12,37 +15,37 @@ open Semantics.FixedPoint
byteSize is the sum of component sizes.
wellFormed requires both components to be well-formed. -/
instance [Schema α] [Schema β] : Schema (α × β) where
byteSize := Schema.byteSize α + Schema.byteSize β
wellFormed := fun (a, b) => Schema.wellFormed a && Schema.wellFormed b
byteSize := byteSize α + byteSize β
wellFormed := fun (a, b) => wellFormed a && wellFormed b
@[simp] theorem prod_byteSize [Schema α] [Schema β] :
Schema.byteSize (α × β) = Schema.byteSize α + Schema.byteSize β := rfl
byteSize (α × β) = byteSize α + byteSize β := rfl
theorem prod_wellFormed [Schema α] [Schema β] (a : α) (b : β) :
Schema.wellFormed (a, b) = (Schema.wellFormed a && Schema.wellFormed b) := rfl
wellFormed (a, b) = (wellFormed a && wellFormed b) := rfl
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 Nested product schemas
-- ═══════════════════════════════════════════════════════════════════════════
@[simp] theorem prod3_byteSize [Schema α] [Schema β] [Schema γ] :
Schema.byteSize ((α × β) × γ) = Schema.byteSize α + Schema.byteSize β + Schema.byteSize γ := by
byteSize ((α × β) × γ) = byteSize α + byteSize β + byteSize γ := by
simp [prod_byteSize, Nat.add_assoc]
@[simp] theorem prod3_byteSize' [Schema α] [Schema β] [Schema γ] :
Schema.byteSize (α × β × γ) = Schema.byteSize α + Schema.byteSize β + Schema.byteSize γ := by
byteSize (α × β × γ) = byteSize α + byteSize β + byteSize γ := by
simp [prod_byteSize, Nat.add_assoc]
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 #eval witnesses
-- ═══════════════════════════════════════════════════════════════════════════
#eval Schema.byteSize (UInt8 × UInt8) -- expected: 2
#eval Schema.byteSize (UInt8 × Bool) -- expected: 2
#eval Schema.byteSize (UInt32 × UInt32) -- expected: 8
#eval Schema.byteSize (Q16_16 × Q16_16) -- expected: 8
#eval Schema.byteSize (UInt8 × UInt32) -- expected: 5
#eval Schema.byteSize ((UInt8 × UInt8) × UInt32) -- expected: 6
#eval Schema.byteSize (UInt8 × UInt8 × UInt32) -- expected: 6
#eval byteSize (UInt8 × UInt8) -- expected: 2
#eval byteSize (UInt8 × Bool) -- expected: 2
#eval byteSize (UInt32 × UInt32) -- expected: 8
#eval byteSize (Q16_16 × Q16_16) -- expected: 8
#eval byteSize (UInt8 × UInt32) -- expected: 5
#eval byteSize ((UInt8 × UInt8) × UInt32) -- expected: 6
#eval byteSize (UInt8 × UInt8 × UInt32) -- expected: 6
end SilverSight
end SilverSight.Semantics

View file

@ -1,16 +1,19 @@
import SilverSight.WireFormat
/-
SilverSight.Semantics.ProductWireFormat
Certified row-major wire formats for product types (α × β), using Core
WireFormat and ProductSchema.
-/
import SilverSight.Semantics.WireFormat
import SilverSight.ProductSchema
namespace SilverSight
open Semantics.FixedPoint
namespace SilverSight.Semantics
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Row-major wire format for pairs
-- §1 Row-major wire format for (UInt8 × Bool)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Row-major wire format for (UInt8 × Bool). -/
def uint8BoolRowMajor : WireFormat (UInt8 × Bool) Layout.rowMajor where
def uint8BoolRowMajor : WireFormat (UInt8 × Bool) rowMajor where
encode := fun (a, b) => ByteArray.mk #[a, if b then 1 else 0]
decode := fun bs =>
match bs.data.toList with
@ -19,14 +22,17 @@ def uint8BoolRowMajor : WireFormat (UInt8 × Bool) Layout.rowMajor where
encode_size := by intro (a, b); rfl
roundTrip := by
intro (a, b)
simp [ByteArray.mk, ByteArray.size]
simp
cases b <;> decide
#eval uint8BoolRowMajor.encode (42, true) -- expected: ByteArray [42, 1]
#eval uint8BoolRowMajor.decode (uint8BoolRowMajor.encode (42, true)) -- expected: some (42, true)
#eval uint8BoolRowMajor.encode (42, true)
#eval uint8BoolRowMajor.decode (uint8BoolRowMajor.encode (42, true))
/-- Row-major wire format for (UInt8 × UInt8). -/
def uint8PairRowMajor : WireFormat (UInt8 × UInt8) Layout.rowMajor where
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 Row-major wire format for (UInt8 × UInt8)
-- ═══════════════════════════════════════════════════════════════════════════
def uint8PairRowMajor : WireFormat (UInt8 × UInt8) rowMajor where
encode := fun (a, b) => ByteArray.mk #[a, b]
decode := fun bs =>
match bs.data.toList with
@ -35,13 +41,16 @@ def uint8PairRowMajor : WireFormat (UInt8 × UInt8) Layout.rowMajor where
encode_size := by intro (a, b); rfl
roundTrip := by
intro (a, b)
simp [ByteArray.mk, ByteArray.size]
simp
#eval uint8PairRowMajor.encode (42, 7) -- expected: ByteArray [42, 7]
#eval uint8PairRowMajor.decode (uint8PairRowMajor.encode (42, 7)) -- expected: some (42, 7)
#eval uint8PairRowMajor.encode (42, 7)
#eval uint8PairRowMajor.decode (uint8PairRowMajor.encode (42, 7))
/-- Row-major wire format for (Bool × Bool). -/
def boolPairRowMajor : WireFormat (Bool × Bool) Layout.rowMajor where
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Row-major wire format for (Bool × Bool)
-- ═══════════════════════════════════════════════════════════════════════════
def boolPairRowMajor : WireFormat (Bool × Bool) rowMajor where
encode := fun (a, b) => ByteArray.mk #[if a then 1 else 0, if b then 1 else 0]
decode := fun bs =>
match bs.data.toList with
@ -50,18 +59,10 @@ def boolPairRowMajor : WireFormat (Bool × Bool) Layout.rowMajor where
encode_size := by intro (a, b); rfl
roundTrip := by
intro (a, b)
simp [ByteArray.mk, ByteArray.size]
simp
cases a <;> cases b <;> decide
#eval boolPairRowMajor.encode (true, false) -- expected: ByteArray [1, 0]
#eval boolPairRowMajor.decode (boolPairRowMajor.encode (true, false)) -- expected: some (true, false)
#eval boolPairRowMajor.encode (true, false)
#eval boolPairRowMajor.decode (boolPairRowMajor.encode (true, false))
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 #eval witnesses
-- ═══════════════════════════════════════════════════════════════════════════
#eval uint8BoolRowMajor.encode (42, true) -- expected: ByteArray [42, 1]
#eval uint8BoolRowMajor.decode (ByteArray.mk #[42, 1]) -- expected: some (42, true)
#eval Schema.byteSize (UInt8 × Bool) -- expected: 2
end SilverSight
end SilverSight.Semantics

View file

@ -63,11 +63,11 @@ def convolutionLHS (n : Nat) : Nat :=
/-- Decompose a natural number into base-B limbs (least-significant first).
This is the polynomial coefficient array: n = Σᵢ limbs[i] · Bⁱ. -/
def limbDecompose (n : Nat) (base : Nat) : List Nat :=
if h1 : base ≤ 1 then [n]
else if h2 : n = 0 then [0]
if _h1 : base ≤ 1 then [n]
else if _h2 : n = 0 then [0]
else n % base :: limbDecompose (n / base) base
termination_by n
decreasing_by exact Nat.div_lt_self (Nat.pos_of_ne_zero h2) (Nat.lt_of_not_le h1)
decreasing_by exact Nat.div_lt_self (Nat.pos_of_ne_zero _h2) (Nat.lt_of_not_le _h1)
-- Witnesses: limbs are LSB-first
#eval limbDecompose 2044 256 -- expect: [252, 7, 0] (7*256 + 252 = 2044)
@ -363,7 +363,7 @@ theorem shortSleeve_mono_zero_prepend (n : Nat) (base : Nat) (hb : base ≥ 2)
set t := limbs.length with ht_def
have hlen_pos : t > 0 := by omega
have hcs := coeffSparsity_val limbs hlen_pos
have hth : shortSleeveThreshold.toInt = 19661 := by native_decide
have hth : shortSleeveThreshold.toInt = 19661 := by rfl
have hsp_nat : z * 65536 / t ≥ 19661 := by
have h : (19661 : ) ≤ (z : ) * 65536 / t := calc
(19661 : ) = shortSleeveThreshold.toInt := hth.symm

View file

@ -1,68 +1,14 @@
import SilverSight.FixedPoint
/-
SilverSight.Schema — shim
Re-exports SilverSight.Semantics.Schema as the single canonical Schema class.
All instances (UInt8, Bool, UInt32, UInt64, Q16_16, Q0_16) live in Core.
This file exists only for backward-compatibility imports; new code should
import SilverSight.Semantics.Schema directly.
-/
import SilverSight.Semantics.Schema
-- Make Core Schema names available without full qualification in SilverSight namespace.
namespace SilverSight
open SilverSight.FixedPoint
/-- A Schema describes the wire-level layout of a type:
- `byteSize`: the number of bytes in the wire representation
- `wellFormed`: a predicate that must hold for valid values -/
class Schema (α : Type) where
byteSize : Nat
wellFormed : α → Bool
@[simp] theorem Schema.byteSize_nonneg [Schema α] : 0 ≤ Schema.byteSize α := by
exact Nat.zero_le _
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Basic Schema instances
-- ═══════════════════════════════════════════════════════════════════════════
instance : Schema UInt8 where
byteSize := 1
wellFormed := fun _ => true
@[simp] theorem uint8_byteSize : Schema.byteSize UInt8 = 1 := rfl
instance : Schema Bool where
byteSize := 1
wellFormed := fun _ => true
@[simp] theorem bool_byteSize : Schema.byteSize Bool = 1 := rfl
instance : Schema UInt32 where
byteSize := 4
wellFormed := fun _ => true
@[simp] theorem uint32_byteSize : Schema.byteSize UInt32 = 4 := rfl
instance : Schema UInt64 where
byteSize := 8
wellFormed := fun _ => true
@[simp] theorem uint64_byteSize : Schema.byteSize UInt64 = 8 := rfl
instance : Schema Q16_16 where
byteSize := 4
wellFormed := fun _ => true
@[simp] theorem q16_16_byteSize : Schema.byteSize Q16_16 = 4 := rfl
instance : Schema Q0_16 where
byteSize := 2
wellFormed := fun _ => true
@[simp] theorem q0_16_byteSize : Schema.byteSize Q0_16 = 2 := rfl
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 #eval witnesses
-- ═══════════════════════════════════════════════════════════════════════════
#eval Schema.byteSize UInt8 -- expected: 1
#eval Schema.byteSize Bool -- expected: 1
#eval Schema.byteSize UInt32 -- expected: 4
#eval Schema.byteSize UInt64 -- expected: 8
#eval Schema.byteSize Q16_16 -- expected: 4
#eval Schema.byteSize Q0_16 -- expected: 2
export SilverSight.Semantics (Schema byteSize wellFormed encodedSize SchemaAdmissible)
end SilverSight

View file

@ -1,74 +1,359 @@
import SilverSight.Schema
/-
SilverSight.WireFormat — shim + Q16_16/Q0_16 WireFormat instances
-/
import SilverSight.Semantics.WireFormat
import SilverSight.Semantics.Schema
namespace SilverSight
open Semantics.FixedPoint
namespace SilverSight.Semantics
open SilverSight.FixedPoint
-- ═══════════════════════════════════════════════════════════════════════════
-- §1 Layout enum
-- Nat-level 4-byte little-endian byte-reassembly identity (testBit proof)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Layout describes how fields are arranged in a wire encoding.
- `rowMajor`: fields stored in declaration order (a₀, a₁, …, b₀, b₁, …)
- `columnar`: fields stored contiguously by field index (a₀, b₀, a₁, b₁, …) -/
inductive Layout where
| rowMajor
| columnar
deriving BEq, DecidableEq, Repr, Inhabited
private theorem nat_byte_reassembly (n : Nat) (hn : n < 4294967296) :
(n &&& 0xFF) ||| (((n >>> 8) &&& 0xFF) <<< 8) |||
(((n >>> 16) &&& 0xFF) <<< 16) ||| (((n >>> 24) &&& 0xFF) <<< 24) = n := by
apply Nat.eq_of_testBit_eq; intro i
have h255 : ∀ k, Nat.testBit 255 k = decide (k < 8) := fun k => by
simp only [show (255 : Nat) = 2 ^ 8 - 1 from by decide, Nat.testBit_two_pow_sub_one]
simp only [Nat.testBit_or, Nat.testBit_and, Nat.testBit_shiftLeft,
Nat.testBit_shiftRight, h255]
rcases Nat.lt_or_ge i 8 with hi | hi
· simp [decide_eq_true_eq.mpr hi,
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 8),
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 16),
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 24)]
· rcases Nat.lt_or_ge i 16 with hi16 | hi16
· simp [decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_true_eq.mpr (show i ≥ 8 from hi),
show 8 + (i - 8) = i from by omega,
decide_eq_true_eq.mpr (show i - 8 < 8 from by omega),
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 16),
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 24)]
· rcases Nat.lt_or_ge i 24 with hi24 | hi24
· simp [decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_true_eq.mpr (show i ≥ 8 from by omega),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 8 < 8)),
decide_eq_true_eq.mpr (show i ≥ 16 from hi16),
show 16 + (i - 16) = i from by omega,
decide_eq_true_eq.mpr (show i - 16 < 8 from by omega),
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 24)]
· rcases Nat.lt_or_ge i 32 with hi32 | hi32
· simp [decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_true_eq.mpr (show i ≥ 8 from by omega),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 8 < 8)),
decide_eq_true_eq.mpr (show i ≥ 16 from by omega),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 16 < 8)),
decide_eq_true_eq.mpr (show i ≥ 24 from hi24),
show 24 + (i - 24) = i from by omega,
decide_eq_true_eq.mpr (show i - 24 < 8 from by omega)]
· have hti : n.testBit i = false :=
Nat.testBit_lt_two_pow (calc n < 4294967296 := hn
_ = 2 ^ 32 := by decide
_ ≤ 2 ^ i := Nat.pow_le_pow_right (by decide) hi32)
simp [hti,
decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 8 < 8)),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 16 < 8)),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 24 < 8))]
-- ═══════════════════════════════════════════════════════════════════════════
-- §2 WireFormat structure
-- Nat-level 2-byte little-endian byte-reassembly identity
-- ═══════════════════════════════════════════════════════════════════════════
/-- A WireFormat certifies the encode/decode cycle for a type under a layout.
The `encode_size` proof ensures every encoded value has exactly `Schema.byteSize α` bytes.
The `roundTrip` proof ensures `decode (encode x) = some x` for all valid `x`. -/
structure WireFormat (α : Type) [Schema α] (L : Layout) where
encode : α → ByteArray
decode : ByteArray → Option α
encode_size : ∀ a : α, (encode a).size = Schema.byteSize α
roundTrip : ∀ a : α, decode (encode a) = some a
private theorem nat_byte_reassembly16 (n : Nat) (hn : n < 65536) :
(n &&& 0xFF) ||| (((n >>> 8) &&& 0xFF) <<< 8) = n := by
apply Nat.eq_of_testBit_eq; intro i
have h255 : ∀ k, Nat.testBit 255 k = decide (k < 8) := fun k => by
simp only [show (255 : Nat) = 2 ^ 8 - 1 from by decide, Nat.testBit_two_pow_sub_one]
simp only [Nat.testBit_or, Nat.testBit_and, Nat.testBit_shiftLeft,
Nat.testBit_shiftRight, h255]
rcases Nat.lt_or_ge i 8 with hi | hi
· simp [decide_eq_true_eq.mpr hi,
decide_eq_false_iff_not.mpr (by omega : ¬ i ≥ 8)]
· rcases Nat.lt_or_ge i 16 with hi16 | hi16
· simp [decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_true_eq.mpr (show i ≥ 8 from hi),
show 8 + (i - 8) = i from by omega,
decide_eq_true_eq.mpr (show i - 8 < 8 from by omega)]
· have hti : n.testBit i = false :=
Nat.testBit_lt_two_pow (calc n < 65536 := hn
_ = 2 ^ 16 := by decide
_ ≤ 2 ^ i := Nat.pow_le_pow_right (by decide) hi16)
simp [hti,
decide_eq_false_iff_not.mpr (by omega : ¬ i < 8),
decide_eq_false_iff_not.mpr (by omega : ¬ (i - 8 < 8))]
-- ═══════════════════════════════════════════════════════════════════════════
-- §3 Basic WireFormat instances
-- UInt32 byte helpers (toNat level)
-- ═══════════════════════════════════════════════════════════════════════════
/-- Encode a UInt8 as a single byte.
Roundtrip: encoding then decoding recovers the original value. -/
def uint8RowMajor : WireFormat UInt8 Layout.rowMajor where
encode := fun u => ByteArray.mk #[u]
private theorem u32_byte0_nat (u : UInt32) :
((u &&& 0xFF).toUInt8).toUInt32.toNat = u.toNat &&& 255 := by
simp only [UInt32.toNat_and, UInt32.toNat_toUInt8, UInt8.toNat_toUInt32,
show (0xFF : UInt32).toNat = 255 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
private theorem u32_byte8_nat (u : UInt32) :
(((u >>> 8) &&& 0xFF).toUInt8).toUInt32.toNat = u.toNat >>> 8 &&& 255 := by
simp only [UInt32.toNat_and, UInt32.toNat_shiftRight, UInt32.toNat_toUInt8,
UInt8.toNat_toUInt32, show (0xFF : UInt32).toNat = 255 from rfl,
show (8 : UInt32).toNat % 32 = 8 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
private theorem u32_byte16_nat (u : UInt32) :
(((u >>> 16) &&& 0xFF).toUInt8).toUInt32.toNat = u.toNat >>> 16 &&& 255 := by
simp only [UInt32.toNat_and, UInt32.toNat_shiftRight, UInt32.toNat_toUInt8,
UInt8.toNat_toUInt32, show (0xFF : UInt32).toNat = 255 from rfl,
show (16 : UInt32).toNat % 32 = 16 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
private theorem u32_byte24_nat (u : UInt32) :
(((u >>> 24) &&& 0xFF).toUInt8).toUInt32.toNat = u.toNat >>> 24 &&& 255 := by
simp only [UInt32.toNat_and, UInt32.toNat_shiftRight, UInt32.toNat_toUInt8,
UInt8.toNat_toUInt32, show (0xFF : UInt32).toNat = 255 from rfl,
show (24 : UInt32).toNat % 32 = 24 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
-- ═══════════════════════════════════════════════════════════════════════════
-- UInt32 shifted-byte helpers (include the <<< k in toNat)
-- ═══════════════════════════════════════════════════════════════════════════
private theorem u32_byte8_shifted (u : UInt32) :
((((u >>> 8) &&& 0xFF).toUInt8).toUInt32 <<< 8).toNat =
(u.toNat >>> 8 &&& 255) <<< 8 := by
simp only [UInt32.toNat_shiftLeft, show (8 : UInt32).toNat % 32 = 8 from rfl,
u32_byte8_nat]
exact Nat.mod_eq_of_lt (by
have := @Nat.and_le_right (u.toNat >>> 8) 255
rw [Nat.shiftLeft_eq]
calc (u.toNat >>> 8 &&& 255) * 2 ^ 8 ≤ 255 * 2 ^ 8 := by nlinarith
_ < 2 ^ 32 := by decide)
private theorem u32_byte16_shifted (u : UInt32) :
((((u >>> 16) &&& 0xFF).toUInt8).toUInt32 <<< 16).toNat =
(u.toNat >>> 16 &&& 255) <<< 16 := by
simp only [UInt32.toNat_shiftLeft, show (16 : UInt32).toNat % 32 = 16 from rfl,
u32_byte16_nat]
exact Nat.mod_eq_of_lt (by
have := @Nat.and_le_right (u.toNat >>> 16) 255
rw [Nat.shiftLeft_eq]
calc (u.toNat >>> 16 &&& 255) * 2 ^ 16 ≤ 255 * 2 ^ 16 := by nlinarith
_ < 2 ^ 32 := by decide)
private theorem u32_byte24_shifted (u : UInt32) :
((((u >>> 24) &&& 0xFF).toUInt8).toUInt32 <<< 24).toNat =
(u.toNat >>> 24 &&& 255) <<< 24 := by
simp only [UInt32.toNat_shiftLeft, show (24 : UInt32).toNat % 32 = 24 from rfl,
u32_byte24_nat]
exact Nat.mod_eq_of_lt (by
have := @Nat.and_le_right (u.toNat >>> 24) 255
rw [Nat.shiftLeft_eq]
calc (u.toNat >>> 24 &&& 255) * 2 ^ 24 ≤ 255 * 2 ^ 24 := by nlinarith
_ < 2 ^ 32 := by decide)
-- ═══════════════════════════════════════════════════════════════════════════
-- UInt32 four-byte round-trip
-- ═══════════════════════════════════════════════════════════════════════════
private theorem u32_byte_reassembly (u : UInt32) :
((u &&& 0xFF).toUInt8).toUInt32 |||
((((u >>> 8) &&& 0xFF).toUInt8).toUInt32 <<< 8) |||
((((u >>> 16) &&& 0xFF).toUInt8).toUInt32 <<< 16) |||
((((u >>> 24) &&& 0xFF).toUInt8).toUInt32 <<< 24) = u := by
apply UInt32.toNat.inj
simp only [UInt32.toNat_or]
rw [u32_byte0_nat u, u32_byte8_shifted u, u32_byte16_shifted u, u32_byte24_shifted u]
exact nat_byte_reassembly u.toNat u.toNat_lt
-- ═══════════════════════════════════════════════════════════════════════════
-- UInt16 byte helpers
-- ═══════════════════════════════════════════════════════════════════════════
private theorem u16_byte0_nat (u : UInt16) :
((u &&& 0xFF).toUInt8).toUInt16.toNat = u.toNat &&& 255 := by
simp only [UInt16.toNat_and, UInt16.toNat_toUInt8, UInt8.toNat_toUInt16,
show (0xFF : UInt16).toNat = 255 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
private theorem u16_byte8_nat (u : UInt16) :
(((u >>> 8) &&& 0xFF).toUInt8).toUInt16.toNat = u.toNat >>> 8 &&& 255 := by
simp only [UInt16.toNat_and, UInt16.toNat_shiftRight, UInt16.toNat_toUInt8,
UInt8.toNat_toUInt16, show (0xFF : UInt16).toNat = 255 from rfl,
show (8 : UInt16).toNat % 16 = 8 from rfl]
exact Nat.mod_eq_of_lt (Nat.lt_of_le_of_lt Nat.and_le_right (by decide))
private theorem u16_byte8_shifted (u : UInt16) :
((((u >>> 8) &&& 0xFF).toUInt8).toUInt16 <<< 8).toNat =
(u.toNat >>> 8 &&& 255) <<< 8 := by
simp only [UInt16.toNat_shiftLeft, show (8 : UInt16).toNat % 16 = 8 from rfl,
u16_byte8_nat]
exact Nat.mod_eq_of_lt (by
have := @Nat.and_le_right (u.toNat >>> 8) 255
rw [Nat.shiftLeft_eq]
calc (u.toNat >>> 8 &&& 255) * 2 ^ 8 ≤ 255 * 2 ^ 8 := by nlinarith
_ < 2 ^ 16 := by decide)
-- ═══════════════════════════════════════════════════════════════════════════
-- UInt16 two-byte round-trip
-- ═══════════════════════════════════════════════════════════════════════════
private theorem u16_byte_reassembly (u : UInt16) :
((u &&& 0xFF).toUInt8).toUInt16 |||
((((u >>> 8) &&& 0xFF).toUInt8).toUInt16 <<< 8) = u := by
apply UInt16.toNat.inj
simp only [UInt16.toNat_or]
rw [u16_byte0_nat u, u16_byte8_shifted u]
exact nat_byte_reassembly16 u.toNat u.toNat_lt
-- ═══════════════════════════════════════════════════════════════════════════
-- Q16_16 value round-trip: ofBits (toBits q) = q
-- ═══════════════════════════════════════════════════════════════════════════
private theorem q16_ofBits_toBits (q : Q16_16) : Q16_16.ofBits (Q16_16.toBits q) = q := by
have hlo : -2147483648 ≤ q.val := by have := q.prop.1; simp [q16MinRaw] at this; exact this
have hhi : q.val ≤ 2147483647 := by have := q.prop.2; simp [q16MaxRaw] at this; exact this
simp only [Q16_16.ofBits, Q16_16.toBits, Q16_16.toInt]
have htbn : (UInt32.ofInt q.val).toNat =
(q.val % (2 : Int) ^ 32).toNat % 2 ^ 32 := by
simp only [UInt32.ofInt, UInt32.toNat_ofNat']
rcases Int.lt_or_le q.val 0 with hneg | hnn
· have htbn' : (UInt32.ofInt q.val).toNat = (q.val + 4294967296).toNat := by
rw [htbn]; omega
rw [htbn']
have hge : (q.val + 4294967296).toNat ≥ 2147483648 := by omega
simp only [if_pos hge]
have hval : ((q.val + 4294967296).toNat : Int) - 4294967296 = q.val := by omega
rw [hval]
simp only [Q16_16.ofRawInt, q16MaxRaw, q16MinRaw]
split_ifs with h1 h2
· exact absurd h1 (by omega)
· exact absurd h2 (by omega)
· exact Subtype.ext rfl
· have htbn' : (UInt32.ofInt q.val).toNat = q.val.toNat := by
rw [htbn]; omega
rw [htbn']
have hlt : ¬ q.val.toNat ≥ 2147483648 := by omega
simp only [if_neg hlt]
have hval : (q.val.toNat : Int) = q.val := by omega
rw [hval]
simp only [Q16_16.ofRawInt, q16MaxRaw, q16MinRaw]
split_ifs with h1 h2
· exact absurd h1 (by omega)
· exact absurd h2 (by omega)
· exact Subtype.ext rfl
-- ═══════════════════════════════════════════════════════════════════════════
-- Q0_16 value round-trip
-- ═══════════════════════════════════════════════════════════════════════════
private theorem q0_ofRawInt_ofInt (q : Q0_16) :
let u := UInt16.ofInt q.val
Q0_16.ofRawInt (if u.toNat ≥ 32768 then (u.toNat : Int) - 65536 else u.toNat) = q := by
have hlo : -32768 ≤ q.val := by have := q.prop.1; simp [q0_16MinRaw] at this; exact this
have hhi : q.val ≤ 32767 := by have := q.prop.2; simp [q0_16MaxRaw] at this; exact this
simp only [UInt16.ofInt]
have htbn : (UInt16.ofNat (q.val % (2 : Int) ^ 16).toNat).toNat =
(q.val % (2 : Int) ^ 16).toNat % 2 ^ 16 := by
simp only [UInt16.toNat_ofNat']
rcases Int.lt_or_le q.val 0 with hneg | hnn
· have htbn' : (UInt16.ofNat (q.val % (2 : Int) ^ 16).toNat).toNat =
(q.val + 65536).toNat := by rw [htbn]; omega
rw [htbn']
have hge : (q.val + 65536).toNat ≥ 32768 := by omega
simp only [if_pos hge]
have hval : ((q.val + 65536).toNat : Int) - 65536 = q.val := by omega
rw [hval]
simp only [Q0_16.ofRawInt, q0_16MaxRaw, q0_16MinRaw]
split_ifs with h1 h2
· exact absurd h1 (by omega)
· exact absurd h2 (by omega)
· exact Subtype.ext rfl
· have htbn' : (UInt16.ofNat (q.val % (2 : Int) ^ 16).toNat).toNat = q.val.toNat := by
rw [htbn]; omega
rw [htbn']
have hlt : ¬ q.val.toNat ≥ 32768 := by omega
simp only [if_neg hlt]
have hval : (q.val.toNat : Int) = q.val := by omega
rw [hval]
simp only [Q0_16.ofRawInt, q0_16MaxRaw, q0_16MinRaw]
split_ifs with h1 h2
· exact absurd h1 (by omega)
· exact absurd h2 (by omega)
· exact Subtype.ext rfl
-- ═══════════════════════════════════════════════════════════════════════════
-- Q16_16 wire format: 4-byte little-endian two's complement
-- ═══════════════════════════════════════════════════════════════════════════
def q16_16RowMajor : WireFormat Q16_16 rowMajor where
encode := fun q =>
let u := Q16_16.toBits q
ByteArray.mk #[
(u &&& 0xFF).toUInt8,
((u >>> 8) &&& 0xFF).toUInt8,
((u >>> 16) &&& 0xFF).toUInt8,
((u >>> 24) &&& 0xFF).toUInt8
]
decode := fun bs =>
if h : bs.size = 1 then some (bs.get! 0)
if h : bs.size = 4 then
let b0 := (bs[0]'(by omega)).toUInt32
let b1 := (bs[1]'(by omega)).toUInt32
let b2 := (bs[2]'(by omega)).toUInt32
let b3 := (bs[3]'(by omega)).toUInt32
some (Q16_16.ofBits (b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24)))
else none
encode_size := by intro a; simp [ByteArray.size]
encode_size := by intro q; rfl
roundTrip := by
intro a
simp only [ByteArray.size]
have h1 : (ByteArray.mk #[a]).size = 1 := by simp [ByteArray.size]
simp [h1]
rfl
intro q
simp only [dif_pos (show (ByteArray.mk #[_, _, _, _]).size = 4 from rfl)]
let u := Q16_16.toBits q
change some (Q16_16.ofBits (
((u &&& 0xFF).toUInt8).toUInt32 |||
((((u >>> 8) &&& 0xFF).toUInt8).toUInt32 <<< 8) |||
((((u >>> 16) &&& 0xFF).toUInt8).toUInt32 <<< 16) |||
((((u >>> 24) &&& 0xFF).toUInt8).toUInt32 <<< 24))) = some q
congr 1
rw [u32_byte_reassembly u]
exact q16_ofBits_toBits q
#eval uint8RowMajor.encode 42 -- expected: ByteArray with single byte 42
#eval uint8RowMajor.decode (uint8RowMajor.encode 42) -- expected: some 42
-- ═══════════════════════════════════════════════════════════════════════════
-- Q0_16 wire format: 2-byte little-endian
-- ═══════════════════════════════════════════════════════════════════════════
/-- Encode a Bool as a single byte (0=false, 1=true).
Uses revert + native_decide for the roundtrip proof since Bool is finite. -/
def boolRowMajor : WireFormat Bool Layout.rowMajor where
encode := fun b => ByteArray.mk #[if b then 1 else 0]
def q0_16RowMajor : WireFormat Q0_16 rowMajor where
encode := fun q =>
let u : UInt16 := UInt16.ofInt q.val
ByteArray.mk #[
(u &&& 0xFF).toUInt8,
((u >>> 8) &&& 0xFF).toUInt8
]
decode := fun bs =>
if h : bs.size = 1 then
let b := bs.get! 0
some (b != 0)
if h : bs.size = 2 then
let b0 := (bs[0]'(by omega)).toUInt16
let b1 := (bs[1]'(by omega)).toUInt16
let u := b0 ||| (b1 <<< 8)
let raw : Int :=
if u.toNat ≥ 32768 then (u.toNat : Int) - 65536 else u.toNat
some (Q0_16.ofRawInt raw)
else none
encode_size := by intro a; simp [ByteArray.size]
encode_size := by intro q; rfl
roundTrip := by
intro a
revert a
native_decide
intro q
simp only [dif_pos (show (ByteArray.mk #[_, _]).size = 2 from rfl)]
let u := UInt16.ofInt q.val
change some (Q0_16.ofRawInt (
let b0 := ((u &&& 0xFF).toUInt8).toUInt16
let b1 := (((u >>> 8) &&& 0xFF).toUInt8).toUInt16
let w := b0 ||| (b1 <<< 8)
if w.toNat ≥ 32768 then (w.toNat : Int) - 65536 else w.toNat)) = some q
simp only []
have hw : ((u &&& 0xFF).toUInt8).toUInt16 |||
((((u >>> 8) &&& 0xFF).toUInt8).toUInt16 <<< 8) = u :=
u16_byte_reassembly u
rw [hw]
congr 1
exact q0_ofRawInt_ofInt q
#eval boolRowMajor.encode true -- expected: ByteArray with single byte 1
#eval boolRowMajor.encode false -- expected: ByteArray with single byte 0
#eval boolRowMajor.decode (boolRowMajor.encode true) -- expected: some true
#eval boolRowMajor.decode (boolRowMajor.encode false) -- expected: some false
end SilverSight
end SilverSight.Semantics

View file

@ -23,7 +23,7 @@
The chirality lattice encodes at 45° increments on /360,
matching the phase-quantized structure from the chaos game
documentation.
-/}
-/
import Mathlib
import universal_encoding.UniversalMathEncoding
@ -125,7 +125,7 @@ theorem consistent_count_lt_full :
(Finset.filter (λ (p : Phase × Chirality × Direction × Regime) =>
match p with | (ph, ch, dir, reg) => isConsistent ph ch dir reg)
(Finset.univ : Finset (Phase × Chirality × Direction × Regime))).card < 144 := by
native_decide
decide
-- =================================================================
-- §6. CHIRALITY ASSIGNMENT PER TOKEN

View file

@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""
equation_dna_encoder.py SilverSight Φ Encoder CLI
Thin CLI wrapper around the phi package modules.
Usage:
echo 'd_F(p,q) = 2*arccos(sum(sqrt(p_i*q_i)))' | python equation_dna_encoder.py
python equation_dna_encoder.py 'E(x) = x^T Q x'
"""
from __future__ import annotations
import sys
from phi import encode_phi, to_fastq
def main():
if len(sys.argv) > 1:
equations = [" ".join(sys.argv[1:])]
else:
equations = [line.strip() for line in sys.stdin if line.strip()]
for eq in equations:
result = encode_phi(eq)
if result is None:
print(f"FAIL: could not parse: {eq!r}", file=sys.stderr)
continue
print(f"# Equation: {result['equation']}")
print(f"# DNA: {result['dna_sequence']} ({result['length']} bases)")
print(f"# PASS: {result['consistency_pass']}")
print(f"# Hash: {result['sha256_prefix']}")
print(f"# F: {result['F']}")
print(f"# τ: {result['tau']}")
print(f"# δ: {result['delta']}")
print(f"# FASTQ: {to_fastq(result).rstrip()}")
print()
if __name__ == "__main__":
main()

View file

@ -1,15 +1,16 @@
#!/usr/bin/env python3
"""
gemma4_mcp.py Local Gemma4-12B MCP server.
gemma4_mcp.py Local + cloud LLM MCP server.
Calls the local llama-server endpoint at http://127.0.0.1:8081/v1.
No API key required. Returns reasoning + content.
Two-tier routing:
1. Local Gemma4-12B (llama.cpp at http://127.0.0.1:8081/v1)
2. FreeLLMAPI proxy (http://127.0.0.1:3001/v1) 16 free providers, auto-failover
Usage:
python3 gemma4_mcp.py # starts MCP server on stdio
Set FREELLMAPI_KEY env var, or the proxy's auto-generated key is used.
"""
import json
import os
import sys
try:
@ -19,61 +20,48 @@ except ImportError:
GEMMA_URL = "http://127.0.0.1:8081/v1/chat/completions"
GEMMA_MODELS_URL = "http://127.0.0.1:8081/v1/models"
FREELLMAPI_URL = "http://127.0.0.1:3001/v1/chat/completions"
FREELLMAPI_KEY = os.environ.get("FREELLMAPI_KEY",
"freellmapi-69dbee85c7c088c9ea8751a338f85044598bed37e3fe33bf")
def get_model_id() -> str:
"""Auto-detect the model ID from the server."""
try:
import httpx
with httpx.Client(timeout=5) as client:
resp = client.get(GEMMA_MODELS_URL, headers={"Authorization": "Bearer none"})
data = resp.json()
return data["models"][0]["name"]
return resp.json()["models"][0]["name"]
except Exception:
return "gemma4-12b" # fallback
return "gemma4-12b"
def call_gemma(question: str, system: str = "", max_tokens: int = 2000,
temperature: float = 0.3, enable_thinking: bool = True) -> dict:
"""Call local Gemma4-12B model."""
def call_model(url: str, api_key: str, question: str, system: str = "",
max_tokens: int = 2000, temperature: float = 0.3,
model: str = "auto", timeout: int = 120) -> dict:
if httpx is None:
return {"error": "httpx not installed"}
model_id = get_model_id()
messages = []
if system:
messages.append({"role": "system", "content": system})
messages.append({"role": "user", "content": question})
payload = {
"model": model_id,
"model": model,
"messages": messages,
"max_tokens": max_tokens,
"temperature": temperature,
}
if not enable_thinking:
payload["chat_template_kwargs"] = {"enable_thinking": False}
try:
with httpx.Client(timeout=120) as client:
resp = client.post(
GEMMA_URL,
json=payload,
headers={
"Content-Type": "application/json",
"Authorization": "Bearer none",
},
)
with httpx.Client(timeout=timeout) as client:
resp = client.post(url, json=payload, headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}",
})
resp.raise_for_status()
data = resp.json()
msg = data["choices"][0]["message"]
content = msg.get("content", "")
reasoning = msg.get("reasoning_content", "")
usage = data.get("usage", {})
timings = data.get("timings", {})
return {
"content": content,
"reasoning": reasoning,
@ -86,13 +74,24 @@ def call_gemma(question: str, system: str = "", max_tokens: int = 2000,
return {"error": str(e)}
def call_gemma(question, system="", max_tokens=2000, temperature=0.3, enable_thinking=True):
model_id = get_model_id()
result = call_model(GEMMA_URL, "none", question, system, max_tokens, temperature, model_id)
if "error" not in result:
return result
result = call_model(FREELLMAPI_URL, FREELLMAPI_KEY, question, system,
max_tokens, temperature, "auto")
if "error" not in result:
return result
return {"error": "both local Gemma4 and FreeLLMAPI failed"}
def mcp_server():
for line in sys.stdin:
try:
req = json.loads(line.strip())
except json.JSONDecodeError:
continue
method = req.get("method", "")
req_id = req.get("id")
params = req.get("params", {})
@ -103,7 +102,7 @@ def mcp_server():
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "gemma4", "version": "0.1.0"},
"serverInfo": {"name": "gemma4", "version": "0.2.0"},
},
}
elif method == "tools/list":
@ -113,30 +112,17 @@ def mcp_server():
"tools": [{
"name": "gemma4",
"description": (
"Ask a question to the local Gemma4-12B model. "
"Free, fast (~40 tok/s), good at math and code. "
"Use this for quick questions, sanity checks, "
"and mathematical reasoning."
"Ask a question to the local Gemma4-12B model, "
"with automatic fallback to 16 free LLM providers "
"(Gemini, Groq, GPT-4o, etc.). Good at math and code."
),
"inputSchema": {
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "The question to ask",
},
"system": {
"type": "string",
"description": "System prompt (optional)",
},
"max_tokens": {
"type": "number",
"description": "Max response tokens (default: 2000)",
},
"enable_thinking": {
"type": "boolean",
"description": "Enable reasoning mode (default: true)",
},
"question": {"type": "string", "description": "The question to ask"},
"system": {"type": "string", "description": "System prompt (optional)"},
"max_tokens": {"type": "number", "description": "Max response tokens (default: 2000)"},
"enable_thinking": {"type": "boolean", "description": "Enable reasoning mode (default: true)"},
},
"required": ["question"],
},
@ -146,7 +132,6 @@ def mcp_server():
elif method == "tools/call":
tool_name = params.get("name", "")
arguments = params.get("arguments", {})
if tool_name == "gemma4":
result = call_gemma(
question=arguments.get("question", ""),
@ -156,7 +141,6 @@ def mcp_server():
)
else:
result = {"error": f"Unknown tool: {tool_name}"}
resp = {
"jsonrpc": "2.0", "id": req_id,
"result": {
@ -168,7 +152,6 @@ def mcp_server():
"jsonrpc": "2.0", "id": req_id,
"error": {"code": -32601, "message": f"Method not found: {method}"},
}
print(json.dumps(resp), flush=True)

View file

@ -0,0 +1,293 @@
#!/usr/bin/env python3
"""
nr_bracket_validation.py Real-data validation of d_CE μ = 0 (Gate C)
Tests the NijenhuisRichardson bracket breakglass on actual braid state data
from the RRC EntropyCandidates pipeline. Two test suites:
Suite A Basis vectors v_i = e_i e_7 (Fin 7 basis of V).
Expected: d_CE μ_ = 0 (exact) mirrors Lean Jacobiator_basis_all.
Suite B Real strand phase vectors from RRC entropy candidates.
Extracts phaseAcc.x (and .y) from each of the 8 strands,
projects into V = ker(Σ), and evaluates d_CE μ.
Should be near machine-zero if the formal proof matches reality.
Reference: SilverSight/formal/SilverSight/PIST/CartanConnection.lean
"""
from __future__ import annotations
import json
import math
import re
import sys
# ─── Crossing matrix C (exact rationals) ─────────────────────────────────────
SIGMA = 39 / 256 # diagonal weight
TAU = 1 / 7 # same-block off-diagonal weight
def crossing_matrix() -> list[list[float]]:
C = [[0.0] * 8 for _ in range(8)]
for i in range(8):
for j in range(8):
if i == j:
C[i][j] = SIGMA
elif i // 2 == j // 2:
C[i][j] = TAU
return C
C = crossing_matrix()
def mat_vec_mul(M: list[list[float]], v: list[float]) -> list[float]:
return [sum(M[i][j] * v[j] for j in range(8)) for i in range(8)]
def vec_add(v: list[float], w: list[float]) -> list[float]:
return [a + b for a, b in zip(v, w)]
def vec_sub(v: list[float], w: list[float]) -> list[float]:
return [a - b for a, b in zip(v, w)]
def inf_norm(v: list[float]) -> float:
return max(abs(x) for x in v)
def project_into_V(v: list[float]) -> list[float]:
mean = sum(v) / 8.0
return [x - mean for x in v]
def mu(X: list[float], Y: list[float]) -> list[float]:
CX = mat_vec_mul(C, X)
CY = mat_vec_mul(C, Y)
return [CX[k] * Y[k] - X[k] * CY[k] for k in range(8)]
def jacobiator(X: list[float], Y: list[float], Z: list[float]) -> list[float]:
return vec_add(
mu(mu(X, Y), Z),
vec_add(mu(mu(Y, Z), X), mu(mu(Z, X), Y))
)
# ─── Suite A: Basis vectors ──────────────────────────────────────────────────
def basis_vec(k: int) -> list[float]:
v = [0.0] * 8
v[k] = 1.0
v[7] = -1.0
return v
def run_suite_a() -> dict:
non_zero: list[tuple[int, int, int, float]] = []
worst = 0.0
for i in range(7):
vi = basis_vec(i)
for j in range(7):
vj = basis_vec(j)
for k in range(7):
vk = basis_vec(k)
J = jacobiator(vi, vj, vk)
nrm = inf_norm(J)
if nrm > worst:
worst = nrm
if nrm > 1e-12:
non_zero.append((i, j, k, nrm))
return {
"total_triples": 7 ** 3,
"non_zero_count": len(non_zero),
"worst_inf_norm": worst,
"all_zero": worst < 1e-12,
}
# ─── Suite B: Parse Candidates.lean (stateful line-based) ────────────────────
def parse_candidates(lines: list[str]) -> list[list[tuple[int, int, int, int]]]:
"""
Extract (x_raw, y_raw, slot, kappa_raw) per strand per candidate.
Each candidate has 8 strand blocks like:
| 0, _ => { phaseAcc := { x := Q16_16.ofRawInt 37813, y := Q16_16.ofRawInt 45787 }
, parity := false
, slot := 1
, residue := Q16_16.ofRawInt 0
, jitter := Q16_16.ofRawInt 0
, bracket := { lower := ...
, kappa := Q16_16.ofRawInt 44921
"""
x_pat = re.compile(r"x\s*:=\s*Q16_16\.ofRawInt\s+(-?\d+)")
y_pat = re.compile(r"y\s*:=\s*Q16_16\.ofRawInt\s+(-?\d+)")
slot_pat = re.compile(r"slot\s*:=\s*(\d+)")
kappa_pat = re.compile(r"kappa\s*:=\s*Q16_16\.ofRawInt\s+(-?\d+)")
candidates: list[list[tuple[int, int, int, int]]] = []
current: list[tuple[int, int, int, int]] = []
buf: dict[str, int | None] = {"x": None, "y": None, "slot": None, "kappa": None}
def flush():
nonlocal buf, current
if all(v is not None for v in buf.values()):
current.append((
buf["x"], buf["y"], buf["slot"], buf["kappa"]
))
buf = {"x": None, "y": None, "slot": None, "kappa": None}
for line in lines:
if "phaseAcc" in line:
flush() # commit previous strand if pending
x_m = x_pat.search(line)
y_m = y_pat.search(line)
slot_m = slot_pat.search(line)
kappa_m = kappa_pat.search(line)
if x_m:
buf["x"] = int(x_m.group(1))
if y_m:
buf["y"] = int(y_m.group(1))
if slot_m:
buf["slot"] = int(slot_m.group(1))
if kappa_m:
buf["kappa"] = int(kappa_m.group(1))
# When we have all 4 fields, make a strand entry
if all(v is not None for v in buf.values()):
flush()
if len(current) == 8:
candidates.append(current)
current = []
return candidates
def run_suite_b(candidates: list[list[tuple[int, int, int, int]]]) -> dict:
Q16 = 65536.0
results = []
for idx, cand in enumerate(candidates):
X = [s[0] / Q16 for s in cand]
Y = [s[1] / Q16 for s in cand]
Z = [s[3] / Q16 for s in cand]
Xv = project_into_V(X)
Yv = project_into_V(Y)
Zv = project_into_V(Z)
tests: list[tuple[str, list[float], list[float], list[float]]] = [
("X,X,X", Xv, Xv, Xv),
("Y,Y,Y", Yv, Yv, Yv),
("Z,Z,Z", Zv, Zv, Zv),
("X,Y,Z", Xv, Yv, Zv),
("X,X,Y", Xv, Xv, Yv),
("Y,Y,X", Yv, Yv, Xv),
("X,Y,Y", Xv, Yv, Yv),
("X,Z,Y", Xv, Zv, Yv),
]
worst = 0.0
details = []
for label, A, B, D in tests:
J = jacobiator(A, B, D)
nrm = inf_norm(J)
if nrm > worst:
worst = nrm
details.append({"triple": label, "inf_norm": round(nrm, 12)})
results.append({
"candidate_idx": idx,
"worst_inf_norm": round(worst, 12),
"all_near_zero": worst < 1e-6,
"details": details,
})
overall_worst = max((r["worst_inf_norm"] for r in results), default=0.0)
return {
"candidates_tested": len(candidates),
"results": results,
"overall_worst": overall_worst,
"overall_pass": all(r["all_near_zero"] for r in results),
}
# ─── Main ─────────────────────────────────────────────────────────────────────
def main():
print("=" * 60)
print("NR Bracket Validation — d_CE μ = 0 on real data")
print("=" * 60)
# Suite A
print("\n─── Suite A: Basis vectors (343 triples) ───")
sa = run_suite_a()
print(f" Total triples: {sa['total_triples']}")
print(f" Non-zero found: {sa['non_zero_count']}")
print(f" Worst ‖J‖_∞: {sa['worst_inf_norm']:.2e}")
print(f" All zero (exact): {sa['all_zero']}")
candidates_file = (
"/home/allaun/Research Stack/"
"0-Core-Formalism/lean/Semantics/"
"Semantics/RRC/EntropyCandidates/Candidates.lean"
)
print(f"\n─── Suite B: Real candidates ({candidates_file}) ───")
try:
with open(candidates_file) as f:
lines = f.readlines()
candidates = parse_candidates(lines)
print(f" Candidates parsed: {len(candidates)}")
if len(candidates) == 0:
print(" ✗ WARNING: No candidates parsed — check regex patterns")
# Debug: show first 30 lines containing relevant keywords
for i, ln in enumerate(lines[:200]):
if any(kw in ln for kw in ["phaseAcc", "slot", "kappa", "ofRawInt"]):
print(f" L{i+1}: {ln.rstrip()}")
else:
sb = run_suite_b(candidates)
print(f" Tested: {sb['candidates_tested']} candidates")
print(f" Overall worst ‖J‖_∞: {sb['overall_worst']:.6e}")
print(f" Overall pass: {sb['overall_pass']}")
for cr in sb["results"]:
status = "" if cr["all_near_zero"] else ""
print(f" {status} Candidate {cr['candidate_idx']}: "
f"worst ‖J‖_∞ = {cr['worst_inf_norm']:.6e}")
for d in cr["details"]:
if d["inf_norm"] > 1e-9:
print(f"{d['triple']}: {d['inf_norm']:.6e}")
except FileNotFoundError:
print(f" ✗ Candidates.lean not found at {candidates_file}")
print("\n" + "=" * 60)
verdict_a = "✓ PASS" if sa["all_zero"] else "✗ FAIL"
print(f" Suite A (basis): {verdict_a}")
if len(candidates) > 0:
verdict_b = "✓ PASS" if sb["overall_pass"] else "✗ FAIL"
print(f" Suite B (real): {verdict_b}")
print("=" * 60)
# Save JSON receipt
receipt = {
"schema": "nr_bracket_validation_v1",
"suite_a": sa,
"suite_b": sb if len(candidates) > 0 else None,
"verdict": {
"suite_a": "PASS" if sa["all_zero"] else "FAIL",
"suite_b": "PASS" if (len(candidates) > 0 and sb["overall_pass"]) else "FAIL" if len(candidates) > 0 else "SKIP",
},
}
receipt_path = "/home/allaun/SilverSight/python/nr_bracket_validation_receipt.json"
with open(receipt_path, "w") as f:
json.dump(receipt, f, indent=2)
print(f"\n Receipt saved: {receipt_path}")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,410 @@
{
"schema": "nr_bracket_validation_v1",
"suite_a": {
"total_triples": 343,
"non_zero_count": 0,
"worst_inf_norm": 0.0,
"all_zero": true
},
"suite_b": {
"candidates_tested": 10,
"results": [
{
"candidate_idx": 0,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 1,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 2,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 3,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 4,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 5,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 6,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 7,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 8,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
},
{
"candidate_idx": 9,
"worst_inf_norm": 0.0,
"all_near_zero": true,
"details": [
{
"triple": "X,X,X",
"inf_norm": 0.0
},
{
"triple": "Y,Y,Y",
"inf_norm": 0.0
},
{
"triple": "Z,Z,Z",
"inf_norm": 0.0
},
{
"triple": "X,Y,Z",
"inf_norm": 0.0
},
{
"triple": "X,X,Y",
"inf_norm": 0.0
},
{
"triple": "Y,Y,X",
"inf_norm": 0.0
},
{
"triple": "X,Y,Y",
"inf_norm": 0.0
},
{
"triple": "X,Z,Y",
"inf_norm": 0.0
}
]
}
],
"overall_worst": 0.0,
"overall_pass": true
},
"verdict": {
"suite_a": "PASS",
"suite_b": "PASS"
}
}

22
python/phi/__init__.py Normal file
View file

@ -0,0 +1,22 @@
"""
phi SilverSight Equation-to-DNA Φ Encoding Pipeline
Independent modules, each reusable without the others:
charclass Layer 1: 8-class byte histogram Δ₇
ast_parse Layer 3: AST parsing τ and δ distributions
consistency Layer 4: 6 consistency rules ADMIT/QUARANTINE
embed Core Φ: (F, τ, δ) 30-base hachimoji DNA sequence
output FASTQ, Adleman graph, PCR primer protocol
Usage:
from phi import encode_phi
result = encode_phi("d_F(p,q) = 2*arccos(sum(sqrt(p_i*q_i)))")
print(result["dna_sequence"])
"""
from .embed import encode_phi
from .output import to_fastq, to_adleman_graph, design_filtering_protocol, PRIMER_DESIGN
from .charclass import compute_F
from .ast_parse import compute_tau, compute_delta
from .consistency import check_consistency, CONSISTENCY_RULES

182
python/phi/ast_parse.py Normal file
View file

@ -0,0 +1,182 @@
"""
phi.ast_parse Layer 3: Parse tree analysis τ and δ distributions
Converts equation strings to Python ASTs (after preprocessing math
notation), then computes:
τ(E) node-type frequency histogram over Δ_{k-1}
δ(E) child-ordering frequency histogram over Δ_{2-1}
Dependencies: Python ast, re (stdlib). Independent of phi.charclass.
"""
from __future__ import annotations
import ast
import re
from typing import Dict, List, Optional, Tuple
# ── Node types recognized by the parser ──────────────────────────────────
NODE_TYPES = [
"bin_add", "bin_sub", "bin_mul", "bin_div",
"bin_pow", "bin_eq", "un_neg", "un_not",
"var", "const", "call", "subscript", "tuple",
"list", "dict", "set", "lambda", "if_exp",
]
# ── Math notation preprocessor ───────────────────────────────────────────
def preprocess_math(text: str) -> str:
"""Preprocess math notation into Python-parseable form.
Handles:
- Single = == (but preserves <=, >=, !=, ==)
- |x| abs(x)
- Parenthesized subscripts: p_(i+j) p[i+j]
- Implicit multiplication: (x)(y) (x)*(y)
- TeX markers: removed
"""
s = text.strip()
if s.endswith(":"):
return ""
s = re.sub(r'\$|\$\$|\\\[|\\\]|\\\(|\\\)', '', s)
s = re.sub(r'(?<![<>=!])=(?!=)', '==', s)
s = re.sub(r'\|([^|=]+)\|', r'abs(\1)', s)
s = re.sub(r'([a-zA-Z])_\(([^)]+)\)', r'\1[\2]', s)
s = re.sub(r'\)\(', r')*(', s)
return s
def parse_to_ast(equation: str) -> Optional[ast.AST]:
"""Parse an equation string into a Python AST.
Tries direct parse first, then wraps in parens for expressions
where math notation drops outer parentheses.
"""
text = preprocess_math(equation)
if not text:
return None
try:
return ast.parse(text, mode="eval")
except SyntaxError:
pass
try:
return ast.parse(f"({text})", mode="eval")
except SyntaxError:
return None
# ── AST node classification ──────────────────────────────────────────────
def _classify_node(node: ast.AST) -> str:
"""Map an AST node to one of the NODE_TYPES."""
if isinstance(node, ast.BinOp):
if isinstance(node.op, ast.Add):
return "bin_add"
if isinstance(node.op, ast.Sub):
return "bin_sub"
if isinstance(node.op, ast.Mult):
return "bin_mul"
if isinstance(node.op, ast.Div):
return "bin_div"
if isinstance(node.op, ast.Pow):
return "bin_pow"
return "bin_add"
if isinstance(node, ast.UnaryOp):
if isinstance(node.op, ast.USub):
return "un_neg"
if isinstance(node.op, ast.Not):
return "un_not"
return "un_neg"
if isinstance(node, ast.Name):
return "var"
if isinstance(node, ast.Constant):
return "const"
if isinstance(node, ast.Call):
return "call"
if isinstance(node, ast.Subscript):
return "subscript"
if isinstance(node, ast.Tuple):
return "tuple"
return "const"
# ── τ(E): node-type frequencies → Δ_{k-1} ───────────────────────────────
def compute_tau(equation: str) -> Optional[List[float]]:
"""Compute τ(E) — normalized node-type histogram.
Returns 18 floats (one per NODE_TYPE) summing to 1.0,
or None if the equation cannot be parsed.
"""
tree = parse_to_ast(equation)
if tree is None:
return None
counts = {t: 0 for t in NODE_TYPES}
for node in ast.walk(tree):
t = _classify_node(node)
counts[t] = counts.get(t, 0) + 1
total = sum(counts.values())
if total == 0:
return [1.0 / len(NODE_TYPES)] * len(NODE_TYPES)
return [counts[t] / total for t in NODE_TYPES]
# ── δ(E): child-ordering frequencies → Δ_{2k²-1} ────────────────────────
# Which (parent, child) type combinations are tracked in δ
DELTA_PARENT_TYPES = [
"bin_add", "bin_sub", "bin_mul", "bin_div", "bin_pow",
"un_neg", "un_not", "call", "subscript",
]
DELTA_CHILD_TYPES = [
"bin_add", "bin_sub", "bin_mul", "bin_div", "bin_pow",
"un_neg", "var", "const", "call",
]
MAX_CHILDREN = 3
def compute_delta(equation: str) -> Optional[List[float]]:
"""Compute δ(E) — child-ordering frequency histogram.
For each (parent_type, child_type, child_index) triple, returns
the fraction of all parent-child edges. Captures syntactic
topology beyond raw node counts.
Returns a flat list of length len(DELTA_PARENT_TYPES) ×
len(DELTA_CHILD_TYPES) × MAX_CHILDREN, or None if parse fails.
"""
tree = parse_to_ast(equation)
if tree is None:
return None
edges: Dict[Tuple[str, str, int], int] = {}
total_edges = 0
def walk(node: ast.AST, _child_idx: int = 0):
nonlocal total_edges
parent_t = _classify_node(node)
for i, child in enumerate(ast.iter_child_nodes(node)):
child_t = _classify_node(child)
key = (parent_t, child_t, i)
edges[key] = edges.get(key, 0) + 1
total_edges += 1
walk(child, i)
walk(tree)
if total_edges == 0:
return None
result = []
for pt in DELTA_PARENT_TYPES:
for ct in DELTA_CHILD_TYPES:
for i in range(MAX_CHILDREN):
result.append(edges.get((pt, ct, i), 0) / total_edges)
return result

65
python/phi/charclass.py Normal file
View file

@ -0,0 +1,65 @@
"""
phi.charclass Layer 1: Character classification Δ₇ byte histogram
Each ASCII character maps to 1 of 8 archetypal classes. The histogram
over these 8 classes is the F(E) feature vector the first component
of the Φ embedding.
Dependencies: none (stdlib only)
"""
from __future__ import annotations
from typing import List
# ── 8 character classes ──────────────────────────────────────────────────
# Each class corresponds to a dimension of Δ₇ (the 7-simplex).
# The classes partition the visible ASCII range into 8 bins.
CHAR_CLASSES = {
"digit": 0, # 0-9
"lower_alpha": 1, # a-z
"upper_alpha": 2, # A-Z
"operator": 3, # + - * / ^ % = < > ! & | ~
"bracket": 4, # ( ) [ ] { }
"punctuation": 5, # . , ; : ' " @ # $ _ \
"whitespace": 6, # space, tab, newline
"other": 7, # everything else (Greek, Unicode math, etc.)
}
OPERATOR_CHARS = set("+-*/^%=<>!&|~")
BRACKET_CHARS = set("()[]{}")
PUNCT_CHARS = set(".,;:'\"@#$ _\\")
def classify_char(c: str) -> int:
"""Classify a single character into 1 of 8 classes (0-7)."""
if c.isdigit():
return 0
if c.isalpha():
return 1 if c.islower() else 2
if c in OPERATOR_CHARS:
return 3
if c in BRACKET_CHARS:
return 4
if c in PUNCT_CHARS:
return 5
if c in (" ", "\t", "\n", "\r"):
return 6
return 7
def compute_F(equation: str) -> List[float]:
"""Compute F(E) — normalized byte-class histogram on Δ₇.
Returns 8 floats summing to 1.0. This is Layer 1 of the Φ embedding.
Pure function: no state, no side effects.
"""
counts = [0] * 8
for c in equation:
counts[classify_char(c)] += 1
total = sum(counts)
if total == 0:
return [1.0 / 8] * 8
return [c / total for c in counts]

104
python/phi/consistency.py Normal file
View file

@ -0,0 +1,104 @@
"""
phi.consistency Layer 4: 6 consistency rules ADMIT / QUARANTINE
Each equation is checked against 6 rules. All must pass for the
equation to be ADMITted. The results are embedded in the DNA as
G (pass) / T (fail) bases for allele-specific PCR filtering.
Dependencies: phi.ast_parse (for tree-based checks).
"""
from __future__ import annotations
import ast
import re
from typing import Dict, Optional
from .ast_parse import parse_to_ast
# ── Well-known math function names (considered "defined references") ─────
KNOWN_MATH_NAMES = frozenset({
"sin", "cos", "tan", "log", "ln", "exp", "sqrt", "abs", "sum",
"min", "max", "floor", "ceil", "round", "sign", "arg", "norm",
"det", "trace", "tr", "diag", "vec", "mat", "rank", "dim",
"arccos", "arcsin", "arctan", "sinh", "cosh", "tanh",
"Re", "Im", "conj", "adj", "trans", "id",
})
# ── The 6 rules ──────────────────────────────────────────────────────────
CONSISTENCY_RULES = [
"balanced_parens", # Rule 1: parentheses must be balanced
"valid_operator_order", # Rule 2: no illegal consecutive operators
"valid_variable_name", # Rule 3: identifiers start with letter/underscore
"no_empty_expression", # Rule 4: equation is non-empty
"single_expression", # Rule 5: parseable as single AST expression
"defined_reference", # Rule 6: all names are known or short vars
]
RULE_ORDER = list(CONSISTENCY_RULES)
def check_consistency(equation: str) -> Dict[str, bool]:
"""Check all 6 consistency rules.
Returns dict of rule_name True/False.
All True = ADMIT; any False = QUARANTINE.
"""
result: Dict[str, bool] = {}
# ── Rule 1: Balanced parentheses ──
depth = 0
for c in equation:
if c == "(":
depth += 1
elif c == ")":
depth -= 1
if depth < 0:
break
result["balanced_parens"] = depth == 0
# ── Rule 2: No illegal consecutive operators ──
ops = set("+-*/^=<>!")
valid_pairs = frozenset({"<=", ">=", "==", "!=", "**"})
bad = False
for i in range(len(equation) - 1):
pair = equation[i:i+2]
if equation[i] in ops and equation[i + 1] in ops:
if pair not in valid_pairs:
bad = True
break
result["valid_operator_order"] = not bad
# ── Rule 3: Identifiers start with letter or underscore ──
tokens = re.findall(r"[A-Za-z_]\w*|\d+|[^\w\s]", equation)
bad_vars = any(
re.match(r"^\d", t) and not re.match(r"^\d+$", t)
for t in tokens
)
result["valid_variable_name"] = not bad_vars
# ── Rule 4: Non-empty ──
result["no_empty_expression"] = len(equation.strip()) > 0
# ── Rule 5: Parseable as single expression ──
tree = parse_to_ast(equation)
result["single_expression"] = tree is not None
# ── Rule 6: All names are known or short ──
result["defined_reference"] = True
if tree is not None:
for node in ast.walk(tree):
if isinstance(node, ast.Name):
name = node.id
allowed = (
len(name) <= 2
or name.startswith("_")
or "_" in name
or name in KNOWN_MATH_NAMES
)
if not allowed:
result["defined_reference"] = False
return result

107
python/phi/embed.py Normal file
View file

@ -0,0 +1,107 @@
"""
phi.embed Core Φ embedding: (F, τ, δ) 30-base hachimoji DNA
Combines all four layers into a single encoding pass. This is the
only module that knows about the hachimoji alphabet and the DNA
sequence layout.
DNA layout (30 bases total):
bases 0-7: F(E) byte-class frequencies on Δ₇
bases 8-15: τ(E) parse tree node-type frequencies
bases 16-23: δ(E) child-ordering frequencies
bases 24-29: Layer 4 consistency (G=pass, T=fail)
Dependencies: phi.charclass, phi.ast_parse, phi.consistency
"""
from __future__ import annotations
import hashlib
from typing import Dict, List, Optional
from .charclass import compute_F
from .ast_parse import compute_tau, compute_delta, NODE_TYPES
from .consistency import check_consistency, RULE_ORDER
# ── Hachimoji alphabet ───────────────────────────────────────────────────
HACHIMOJI_BASES = list("ABCGPSTZ")
INDEX_TO_BASE = dict(enumerate(HACHIMOJI_BASES))
BASE_TO_INDEX = {b: i for i, b in enumerate(HACHIMOJI_BASES)}
# ── Float-to-base conversion ─────────────────────────────────────────────
def _float_to_3bit(x: float) -> int:
"""Quantize a float [0, 1] to a 3-bit integer (0-7)."""
return min(7, max(0, round(x * 7)))
def _vec_to_bases(values: List[float]) -> str:
"""Map floats in [0,1] to hachimoji bases (3 bits each, 8 bases)."""
return "".join(INDEX_TO_BASE[_float_to_3bit(v)] for v in values)
# ── Core encoding ────────────────────────────────────────────────────────
def encode_phi(equation: str) -> Optional[Dict]:
"""Apply Φ mapping: equation string → 30-base hachimoji DNA sequence.
The four layers are:
1. F(E) byte-class histogram (Δ₇)
2. (implicit derived from the phase-alphabet mapping)
3. τ(E) + δ(E) parse tree structure
4. 6 consistency rules primer-binding region
Returns a dict with the DNA sequence and all intermediate values,
or None if the equation is empty.
The returned dict is the standard Φ encoding record consumed by
phi.output (FASTQ, Adleman graph, PCR protocol).
"""
if not equation or not equation.strip():
return None
F = compute_F(equation)
consistency = check_consistency(equation)
tau = compute_tau(equation)
delta = compute_delta(equation)
# Fallback for unparseable equations: uniform distribution
# (encodes as all-A — "null structural signal")
if tau is None:
tau = [1.0 / len(NODE_TYPES)] * len(NODE_TYPES)
# Encode each layer as 8 hachimoji bases
F_dna = _vec_to_bases(F[:8])
tau_dna = _vec_to_bases(tau[:8])
delta_dna = _vec_to_bases(delta[:8]) if delta else "AAAAAAAA"
# Layer 4: encode consistency G=pass T=fail
consistency_dna = "".join("G" if consistency[r] else "T" for r in RULE_ORDER)
full_sequence = F_dna + tau_dna + delta_dna + consistency_dna
quality_scores = "".join("A" if v else "P" for v in consistency.values())
seq_hash = hashlib.sha256(full_sequence.encode()).hexdigest()[:16]
return {
"equation": equation,
"dna_sequence": full_sequence,
"length": len(full_sequence),
"bases": list(HACHIMOJI_BASES),
"schema": "phi_embedding_v2",
"F": [round(x, 4) for x in F],
"tau": [round(x, 4) for x in tau],
"delta": [round(x, 4) for x in delta] if delta else None,
"F_dna": F_dna,
"tau_dna": tau_dna,
"delta_dna": delta_dna,
"consistency": consistency,
"consistency_pass": all(consistency.values()),
"consistency_dna": consistency_dna,
"quality_scores": quality_scores,
"sha256_prefix": seq_hash,
"pas_primer": "CCCCCC",
"fail_primer": "AAAAAA",
}

137
python/phi/output.py Normal file
View file

@ -0,0 +1,137 @@
"""
phi.output FASTQ, Adleman graph, and PCR primer protocol
Transforms Φ encoding records (from phi.embed.encode_phi) into
standard bioinformatics formats consumable by external tools.
Formats:
FASTQ pipe through Jellyfish/KMC/BLAST
Adleman graph feed into BioComputing's connectNodes()
PCR protocol wet-lab filtering with allele-specific primers
Dependencies: phi.embed (for encode_phi output dict format).
"""
from __future__ import annotations
import math
from typing import Dict, List
# ── Primer sequences ─────────────────────────────────────────────────────
PRIMER_DESIGN = {
"pas_primer": {
"sequence": "CCCCCC",
"target": "consistency_dna = GGGGGG (all 6 rules pass)",
"tm": 36.0,
"purpose": "Capture PASS strands — amplify consistent equations only",
},
"fail_primer": {
"sequence": "AAAAAA",
"target": "consistency_dna = TTTTTT (all 6 rules fail)",
"tm": 12.0,
"purpose": "Capture FAIL strands — quarantine inconsistent equations",
},
"universal_primer": {
"sequence": "ABCABC",
"target": "F_dna region (first 8 bases)",
"tm": 15.0,
"purpose": "Amplify all encoded equations regardless of consistency",
},
}
# ── FASTQ ────────────────────────────────────────────────────────────────
def to_fastq(record: Dict) -> str:
"""Format a Φ encoding record as a 4-line FASTQ entry.
FASTQ is the standard DNA sequencing format. This lets us pipe
equation encodings through any existing bioinformatics pipeline
without tool modification.
"""
eq = record["equation"]
seq = record["dna_sequence"]
qual = record["quality_scores"]
n_cons = sum(1 for v in record["consistency"].values() if v)
eq_hash = record["sha256_prefix"]
pass_flag = "PASS" if record["consistency_pass"] else "FAIL"
header = f"@{eq_hash} n_consistency={n_cons}/6 pass={pass_flag} len={len(eq)}"
qual_line = qual * (len(seq) // len(qual)) if len(seq) > len(qual) else qual
return f"{header}\n{seq}\n+\n{qual_line}\n"
# ── Adleman integration ──────────────────────────────────────────────────
def to_adleman_graph(records: List[Dict]) -> Dict:
"""Build an Adleman/Lipton-compatible graph from Φ-encoded equations.
Each equation is a vertex. Edges represent Fisher-distance similarity
(d_F < 0.5) between their F(E) byte-class histograms.
Feed the output into BioComputing's `hampath.connectNodes()` or
`sattv.createNodes()` to generate wet-lab DNA sequences.
"""
vertices = {}
for i, rec in enumerate(records):
vid = f"E{i}"
vertices[vid] = {
"equation": rec["equation"],
"dna": rec["dna_sequence"],
"consistency": rec["consistency_pass"],
}
edges = []
vert_ids = list(vertices.keys())
for i in range(len(vert_ids)):
for j in range(i + 1, len(vert_ids)):
Fi = records[i]["F"]
Fj = records[j]["F"]
dist = _fisher_distance(Fi, Fj)
if dist < 0.5:
edges.append((vert_ids[i], vert_ids[j], round(dist, 4)))
return {
"vertices": vertices,
"edges": edges,
"format": "adleman_graph_v1",
"n_vertices": len(vertices),
"n_edges": len(edges),
}
# ── PCR protocol ─────────────────────────────────────────────────────────
def design_filtering_protocol(records: List[Dict]) -> Dict:
"""Design a PCR filtering protocol for a batch of encoded equations.
Uses allele-specific PCR (Newton et al. 1989) the 24°C Tm gap
between PASS and FAIL primers provides single-base discrimination.
"""
n_pass = sum(1 for r in records if r["consistency_pass"])
n_fail = len(records) - n_pass
return {
"protocol": "allele_specific_pcr_v1",
"reference": "Newton et al. (1989) Nucleic Acids Res 17:2503; "
"allele-specific PCR for single-base discrimination",
"pas_primer": PRIMER_DESIGN["pas_primer"]["sequence"],
"fail_primer": PRIMER_DESIGN["fail_primer"]["sequence"],
"universal_primer": PRIMER_DESIGN["universal_primer"]["sequence"],
"annealing_tm_pass": PRIMER_DESIGN["pas_primer"]["tm"],
"annealing_tm_fail": PRIMER_DESIGN["fail_primer"]["tm"],
"annealing_tm_universal": PRIMER_DESIGN["universal_primer"]["tm"],
"expected_amplification_pass": n_pass,
"expected_amplification_fail": n_fail,
}
# ── Fisher distance ↓ (internal; no circular dep) ────────────────────────
def _fisher_distance(p: List[float], q: List[float]) -> float:
"""Fisher-Rao distance between two points on Δ₇: d_F = 2·acos(Σ√(p_i·q_i))."""
dot = sum(math.sqrt(pi * qi) for pi, qi in zip(p, q))
dot = max(-1.0, min(1.0, dot))
return 2.0 * math.acos(dot)