7.9 KiB
Lean Migration Migraine Reducer
Purpose
This note converts the current Sidon / AMREF / Mass-Number / Inverse-Ascent stack into a Lean-first implementation plan with minimal manual theorem pain.
I could not directly pull live pages from lean-lang.org in this environment, so this note is based on stable Lean 4 / Lake / Mathlib workflow practice and should be refreshed against the official Lean docs before use as a V-scope implementation receipt.
Core Rule
Do not hand-prove the whole ontology.
First formalize finite counters, gates, and monotonicity lemmas.
Then use computation/reflection for examples.
Only promote theorem statements after counters and witnesses exist.
Lean Stack Shape
Recommended module layout:
OTOM/
Sidon/
FinsetCounters.lean
SidonGate.lean
GolombGate.lean
CompressionGate.lean
MetaProbeGate.lean
InverseAscentGate.lean
Examples.lean
AMREF/
FixedPoint.lean
Score.lean
MassNumber/
Core.lean
Receipts.lean
FAM/
Route.lean
Gate.lean
Minimal Lake Setup
Expected files:
lean-toolchain
lakefile.lean
lean-toolchain should pin a toolchain, for example:
leanprover/lean4:stable
For Mathlib-backed work, use the Mathlib project template and then pin exact versions.
First Formal Target: Finite Counters
Everything starts with finite lists/finsets.
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Multiset.Basic
import Mathlib.Data.Nat.Basic
namespace OTOM.Sidon
abbrev Candidate := Finset Nat
/-- Unordered pair sums with repetitions represented as a multiset. -/
def pairSums (A : Candidate) : Multiset Nat :=
((A.product A).filter (fun p => p.1 <= p.2)).val.map (fun p => p.1 + p.2)
/-- A finite Sidon candidate: no duplicate unordered pair sums. -/
def IsSidon (A : Candidate) : Prop :=
(pairSums A).Nodup
/-- Ordered positive differences. -/
def diffs (A : Candidate) : Multiset Nat :=
((A.product A).filter (fun p => p.2 < p.1)).val.map (fun p => p.1 - p.2)
/-- Golomb-style no repeated positive differences. -/
def IsGolomb (A : Candidate) : Prop :=
(diffs A).Nodup
end OTOM.Sidon
This is the low-migraine route because Nodup gives you a proof object without building full collision-energy arithmetic first.
Second Target: Collision Energy as Computable Diagnostics
After Nodup, add computable collision debt.
namespace OTOM.Sidon
/-- Count how often `x` occurs in a multiset. -/
def countOf (x : Nat) (xs : Multiset Nat) : Nat :=
xs.count x
/-- Collision debt of a multiset: sum over unique support of max(0, count-1). -/
def collisionDebt (xs : Multiset Nat) : Nat :=
(xs.toFinset).sum (fun x => (xs.count x) - 1)
def cB2 (A : Candidate) : Nat :=
collisionDebt (pairSums A)
def cD (A : Candidate) : Nat :=
collisionDebt (diffs A)
end OTOM.Sidon
Target lemmas:
theorem sidon_iff_cB2_zero (A : Candidate) :
IsSidon A <-> cB2 A = 0 := by
-- prove after checking exact Multiset lemmas in Mathlib
sorry
theorem golomb_iff_cD_zero (A : Candidate) :
IsGolomb A <-> cD A = 0 := by
sorry
Use sorry only in draft branches; block promotion until removed.
Third Target: Gate Records
Use records for proof-carrying gates instead of loose booleans.
structure SidonProbeState where
A : Candidate
cB2 : Nat
cD : Nat
compressionGainQ16 : UInt32
gclStabilityQ16 : UInt32
metaProbeQ16 : UInt32
randomnessPenaltyQ16 : UInt32
receiptsComplete : Bool
inductive SidonGate where
| classicalSidon
| virtualSidon
| hold
| scar
| quarantine
deriving Repr, DecidableEq
Then define readiness as an executable Boolean:
def ClassicalSidonReady (s : SidonProbeState) : Bool :=
s.cB2 == 0 &&
s.metaProbeQ16 >= 0x00008000 &&
s.randomnessPenaltyQ16 <= 0x00004000 &&
s.receiptsComplete
And later prove Boolean/Prop correspondence:
def ClassicalSidonReadyProp (s : SidonProbeState) : Prop :=
s.cB2 = 0 ∧
s.metaProbeQ16 >= 0x00008000 ∧
s.randomnessPenaltyQ16 <= 0x00004000 ∧
s.receiptsComplete = true
Target theorem:
theorem classicalReady_sound (s : SidonProbeState) :
ClassicalSidonReady s = true -> ClassicalSidonReadyProp s := by
-- mostly simp / decide / Bool.and_eq_true decomposition
sorry
Fourth Target: Inverse Ascent Gate
Keep this integer/fixed-point first.
structure Route where
rankDelta : Int
energyAvailableQ16 : UInt32
ascentCostQ16 : UInt32
receiptsComplete : Bool
deriving Repr, DecidableEq
def CanAscend (r : Route) : Bool :=
r.rankDelta > 0 &&
r.energyAvailableQ16 >= r.ascentCostQ16 &&
r.receiptsComplete
Soundness target:
def CanAscendProp (r : Route) : Prop :=
r.rankDelta > 0 ∧
r.energyAvailableQ16 >= r.ascentCostQ16 ∧
r.receiptsComplete = true
theorem canAscend_sound (r : Route) :
CanAscend r = true -> CanAscendProp r := by
sorry
Fifth Target: Avoid Real Analysis Until Necessary
Do not start with FFT, AMREF, real-valued scores, or complex exponentials.
Start with finite approximations:
Q16.16 fixed-point scores
UInt32 thresholds
Nat collision counters
Bool gates
Prop soundness lemmas
Only after the finite gate is stable should you add:
Rational scores
Real-valued AMREF
Complex spectral fingerprints
FFT proofs
analytic limits
Tactics That Usually Shorten Pain
Useful tactics/patterns:
simp
simp_all
omega
linarith
norm_num
decide
by_cases h : condition
constructor
intro h
rcases h with ⟨h1, h2, h3⟩
For Nat arithmetic, try:
omega
For simple numerals:
norm_num
For boolean gates:
simp [CanAscend, CanAscendProp] at *
Migraine Avoidance Rules
1. Avoid proving optimized formulas first.
2. Define executable counters first.
3. Prove soundness of gates, not completeness of ontology.
4. Use UInt32/Q16 only at boundaries; use Nat for proofs where possible.
5. Keep spectral/complex analysis out of the first Lean pass.
6. Make every external claim a Receipt record.
7. Keep user-facing metaphor out of Lean names.
8. Never let visualization become theorem input.
Mapping Current Stack to Lean
| Concept | Lean-first representation |
|---|---|
| Sidon field | Finset Nat |
| Pair-sum collision | Multiset Nat + Nodup / debt counter |
| Golomb echoes | difference multiset + Nodup |
| AMREF score | Q16.16 score field first, real functional later |
| Mass-number | fixed-point diagnostic record |
| Inverse ascent | Route with energy/cost/receipts |
| GCL diff | Q16.16 stability score first |
| Metaprobe | Q16.16 trust score + Prop soundness |
| Receipts | structures / typeclasses |
Suggested First File
Create:
OTOM/Sidon/FinsetCounters.lean
with:
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Multiset.Basic
import Mathlib.Data.Nat.Basic
import Mathlib.Tactic
namespace OTOM.Sidon
abbrev Candidate := Finset Nat
def pairSums (A : Candidate) : Multiset Nat :=
((A.product A).filter (fun p => p.1 <= p.2)).val.map (fun p => p.1 + p.2)
def IsSidon (A : Candidate) : Prop :=
(pairSums A).Nodup
def diffs (A : Candidate) : Multiset Nat :=
((A.product A).filter (fun p => p.2 < p.1)).val.map (fun p => p.1 - p.2)
def IsGolomb (A : Candidate) : Prop :=
(diffs A).Nodup
def collisionDebt (xs : Multiset Nat) : Nat :=
(xs.toFinset).sum (fun x => (xs.count x) - 1)
def cB2 (A : Candidate) : Nat :=
collisionDebt (pairSums A)
def cD (A : Candidate) : Nat :=
collisionDebt (diffs A)
end OTOM.Sidon
Required Receipts
LeanDocsRefreshReceipt
LakeBuildReceipt
MathlibVersionReceipt
FiniteCounterReceipt
GateSoundnessReceipt
NoSorryReceipt
ExampleWitnessReceipt
Audit Classification
Receipt: LeanMigrationMigraineReducer
Status: IMPLEMENTATION_SCAFFOLD
Gate: U_scope
Reason: suitable migration plan and first-module sketch; must be refreshed against official Lean docs and checked by `lake build` before V_scope.