Pith. sign in

IndisputableMonolith.Cosmology.CosmogenesisSim

IndisputableMonolith/Cosmology/CosmogenesisSim.lean · 237 lines · 29 declarations

show as:
view math explainer →

open module explainer GitHub source

Explainer status: pending

   1import Mathlib
   2
   3/-!
   4# Cosmogenesis Simulation: a computable, kernel-checked mirror
   5
   6`Cosmology/PreBigBang` and `Cosmology/FirstTick` prove the dynamics over `ℝ`.
   7This module gives the same cosmogenesis a **computable** form over `ℚ`, so the
   8simulation is a Lean object you can `#eval`, with a conservation law proved in
   9the kernel rather than only checked at runtime.
  10
  11The recognition ledger is mirrored exactly:
  12
  13* `QEvent` is `Foundation.LedgerForcing.RecognitionEvent` over `ℚ`.
  14* `qreciprocal` swaps source/target and inverts the ratio.
  15* `addEvent` posts an event together with its reciprocal (double-entry).
  16* `qcost` is the summed J-cost; `qcost_addEvent` is the per-tick increment
  17  `+ 2·J(ratio)`, mirroring `FirstTick.ledger_cost_add_event`.
  18
  19The conserved quantity (σ) takes its multiplicative form here, which is rational
  20and therefore computable: the **flow product** at an agent, the product of the
  21ratios of all events touching it. Double-entry posting multiplies it by
  22`r · r⁻¹ = 1`, so it is invariant. `cosmogenesis_conserves` proves the flow
  23product is exactly `1` at every agent after the full 8-tick cosmogenesis, for any
  24positive seed, with no `decide` and no `sorry`.
  25
  26The self-similar recurrence `r ↦ 1 + 1/r` runs over `ℚ` and produces the exact
  27Fibonacci convergents `2, 3/2, 5/3, 8/5, 13/8, …`, which converge to `φ`. So the
  28emergence of `φ` is visible as an exact rational sequence, and `#eval` shows it.
  29-/
  30
  31set_option linter.unusedSimpArgs false
  32
  33namespace IndisputableMonolith
  34namespace Cosmology
  35namespace CosmogenesisSim
  36
  37/-- A recognition event over `ℚ`. Mirror of `LedgerForcing.RecognitionEvent`. -/
  38structure QEvent where
  39  source : ℕ
  40  target : ℕ
  41  ratio : ℚ
  42  deriving Repr
  43
  44/-- The reciprocal event: swap source/target, invert the ratio. -/
  45def qreciprocal (e : QEvent) : QEvent := ⟨e.target, e.source, e.ratio⁻¹⟩
  46
  47/-- The canonical recognition cost over `ℚ`: `J(x) = (x + x⁻¹)/2 - 1`. -/
  48def qJ (x : ℚ) : ℚ := (x + x⁻¹) / 2 - 1
  49
  50/-- Total ledger cost. Mirror of `LedgerForcing.ledger_cost`. -/
  51def qcost (es : List QEvent) : ℚ := (es.map (fun e => qJ e.ratio)).sum
  52
  53/-- An event's contribution to the flow at an agent: its ratio if it touches the
  54agent (as source or target), and `1` otherwise. -/
  55def flowContribution (agent : ℕ) (e : QEvent) : ℚ :=
  56  if e.source = agent ∨ e.target = agent then e.ratio else 1
  57
  58/-- The flow product at an agent: the product over all events of their
  59contribution. This is the multiplicative (computable) form of σ. Conserved
  60value is `1`. -/
  61def flowProduct (es : List QEvent) (agent : ℕ) : ℚ :=
  62  (es.map (flowContribution agent)).prod
  63
  64/-- Post one distinction. Double-entry forces the reciprocal in with it.
  65Mirror of `LedgerForcing.add_event`. -/
  66def addEvent (es : List QEvent) (e : QEvent) : List QEvent :=
  67  e :: qreciprocal e :: es
  68
  69/-! ## Cost increment per tick (mirror of `FirstTick.ledger_cost_add_event`) -/
  70
  71/-- `J` is reciprocal-symmetric over `ℚ`. -/
  72theorem qJ_recip (x : ℚ) : qJ x⁻¹ = qJ x := by
  73  unfold qJ; rw [inv_inv]; ring
  74
  75/-- Posting one paired event raises the cost by exactly `2·J(ratio)`. -/
  76theorem qcost_addEvent (L : List QEvent) (e : QEvent) :
  77    qcost (addEvent L e) = qcost L + 2 * qJ e.ratio := by
  78  unfold qcost addEvent
  79  simp only [List.map_cons, List.sum_cons, qreciprocal, qJ_recip]
  80  ring
  81
  82/-! ## σ as a conserved multiplicative invariant -/
  83
  84/-- The empty ledger has flow product `1` at every agent. -/
  85theorem flowProduct_nil (agent : ℕ) : flowProduct [] agent = 1 := by
  86  simp [flowProduct]
  87
  88/-- An event and its reciprocal contribute a factor of exactly `1` at every
  89agent: either both touch it (factor `r · r⁻¹ = 1`) or neither does (factor `1`). -/
  90theorem flowContribution_pair (e : QEvent) (he : e.ratio ≠ 0) (agent : ℕ) :
  91    flowContribution agent e * flowContribution agent (qreciprocal e) = 1 := by
  92  simp only [flowContribution, qreciprocal]
  93  by_cases h : e.source = agent ∨ e.target = agent
  94  · rw [if_pos h, if_pos h.symm]
  95    exact mul_inv_cancel₀ he
  96  · rw [if_neg h, if_neg (mt Or.symm h)]
  97    ring
  98
  99/-- **Conservation step.** Posting a paired event leaves the flow product
 100unchanged at every agent (the `r · r⁻¹ = 1` cancellation). -/
 101theorem flowProduct_addEvent (L : List QEvent) (e : QEvent) (he : e.ratio ≠ 0)
 102    (agent : ℕ) : flowProduct (addEvent L e) agent = flowProduct L agent := by
 103  unfold flowProduct addEvent
 104  simp only [List.map_cons, List.prod_cons]
 105  rw [← mul_assoc, flowContribution_pair e he agent, one_mul]
 106
 107/-- Flow product is `1` for any ledger built solely by `addEvent` from empty,
 108provided every posted ratio is nonzero. -/
 109theorem flowProduct_foldl (agent : ℕ) (f : ℕ → QEvent)
 110    (hf : ∀ t, (f t).ratio ≠ 0) (n : ℕ) :
 111    flowProduct ((List.range n).foldl (fun L t => addEvent L (f t)) []) agent = 1 := by
 112  induction n with
 113  | zero => simp [flowProduct]
 114  | succ k ih =>
 115      rw [List.range_succ, List.foldl_append]
 116      simp only [List.foldl_cons, List.foldl_nil]
 117      rw [flowProduct_addEvent _ _ (hf k) agent, ih]
 118
 119/-! ## The self-similar recurrence and the cosmogenesis ledger -/
 120
 121/-- The self-similar recognition recurrence `r ↦ 1 + 1/r` over `ℚ`.
 122Exact Fibonacci convergents to `φ`. -/
 123def recurSeq (seed : ℚ) : ℕ → ℚ
 124  | 0 => seed
 125  | (n + 1) => 1 + (recurSeq seed n)⁻¹
 126
 127/-- The recurrence stays positive for a positive seed. -/
 128theorem recurSeq_pos (seed : ℚ) (hs : 0 < seed) : ∀ t, 0 < recurSeq seed t
 129  | 0 => hs
 130  | (n + 1) => by
 131      have hp : 0 < recurSeq seed n := recurSeq_pos seed hs n
 132      have hinv : 0 < (recurSeq seed n)⁻¹ := inv_pos.mpr hp
 133      show (0 : ℚ) < 1 + (recurSeq seed n)⁻¹
 134      linarith
 135
 136/-- The Gray-code Hamiltonian cycle on the 3-cube, closing back to its start. -/
 137def cyc : List ℕ := [0, 1, 3, 2, 6, 7, 5, 4, 0]
 138
 139/-- The cadence walk has nine vertices (eight edges, closed loop). -/
 140theorem cyc_length : cyc.length = 9 := by native_decide
 141
 142/-- Exactly eight ticks are posted in `cosmogenesis`. -/
 143theorem cosmogenesis_tick_count (_seed : ℚ) :
 144    (List.range 8).length = 8 := rfl
 145
 146/-- Positive ratio distinct from unity incurs positive `qJ` cost. -/
 147theorem qJ_pos {x : ℚ} (hx : 0 < x) (hne : x ≠ 1) : 0 < qJ x := by
 148  have h : qJ x = (x - 1) ^ 2 / (2 * x) := by
 149    unfold qJ
 150    field_simp [hx.ne']
 151    ring
 152  have h01 : x - 1 ≠ 0 := sub_ne_zero.mpr hne
 153  have hsq : 0 < (x - 1) ^ 2 := by
 154    rw [pow_two]
 155    exact mul_self_pos.mpr h01
 156  rw [h]
 157  exact div_pos hsq (by linarith)
 158
 159/-- Default seed-2 run posts a genuine distinction at tick 0. -/
 160theorem seed2_distinction : (recurSeq 2 0) ≠ 1 := by native_decide
 161
 162/-- The recognition event posted at tick `t`: an edge of the 3-cube carrying the
 163`t`-th recurrence ratio. -/
 164def cosmoEvent (seed : ℚ) (t : ℕ) : QEvent :=
 165  ⟨cyc.getD t 0, cyc.getD (t + 1) 0, recurSeq seed t⟩
 166
 167/-- **The cosmogenesis ledger.** Eight ticks posted onto the empty ledger, one
 168per edge of the 3-cube cadence, each paired by double-entry. -/
 169def cosmogenesis (seed : ℚ) : List QEvent :=
 170  (List.range 8).foldl (fun L t => addEvent L (cosmoEvent seed t)) []
 171
 172/-- **σ conservation, proved.** After the full cosmogenesis, the flow product is
 173exactly `1` at every agent, for any positive seed. No `decide`, no `sorry`. -/
 174theorem cosmogenesis_conserves (seed : ℚ) (hs : 0 < seed) (agent : ℕ) :
 175    flowProduct (cosmogenesis seed) agent = 1 :=
 176  flowProduct_foldl agent (cosmoEvent seed)
 177    (fun t => (recurSeq_pos seed hs t).ne') 8
 178
 179/-- Each paired posting adds two events. -/
 180theorem addEvent_length (L : List QEvent) (e : QEvent) :
 181    (addEvent L e).length = L.length + 2 := by
 182  simp [addEvent]
 183
 184/-- A ledger built by `n` paired postings from empty has `2n` events. -/
 185theorem foldl_addEvent_length (f : ℕ → QEvent) (n : ℕ) :
 186    ((List.range n).foldl (fun L t => addEvent L (f t)) []).length = 2 * n := by
 187  induction n with
 188  | zero => simp
 189  | succ k ih =>
 190      rw [List.range_succ, List.foldl_append]
 191      simp only [List.foldl_cons, List.foldl_nil]
 192      rw [addEvent_length, ih]
 193      ring
 194
 195/-- The cosmogenesis posts sixteen events (eight ticks, each paired). -/
 196theorem cosmogenesis_length (seed : ℚ) : (cosmogenesis seed).length = 16 := by
 197  have h : (cosmogenesis seed).length = 2 * 8 := foldl_addEvent_length (cosmoEvent seed) 8
 198  omega
 199
 200/-- First-tick cost is positive for the canonical seed-2 cosmogenesis run. -/
 201theorem seed2_first_tick_cost_pos : 0 < qJ (recurSeq 2 0) :=
 202  qJ_pos (recurSeq_pos 2 (by norm_num) 0) seed2_distinction
 203
 204/-- Certificates mirrored by `cosmogenesis_golden_trace_v0` (Python microkernel). -/
 205structure TraceCertificates where
 206  event_count : (cosmogenesis 2).length = 16
 207  sigma_at_zero : flowProduct (cosmogenesis 2) 0 = 1
 208  cadence_eight_ticks : (List.range 8).length = 8
 209  cyc_closed_nine_vertices : cyc.length = 9
 210  first_tick_cost_pos : 0 < qJ (recurSeq 2 0)
 211
 212/-- Kernel-checked trace certificates for the canonical seed-2 run. -/
 213theorem trace_certificates_seed2 : TraceCertificates where
 214  event_count := cosmogenesis_length 2
 215  sigma_at_zero := cosmogenesis_conserves 2 (by norm_num) 0
 216  cadence_eight_ticks := cosmogenesis_tick_count 2
 217  cyc_closed_nine_vertices := cyc_length
 218  first_tick_cost_pos := seed2_first_tick_cost_pos
 219
 220/-! ## Runnable demonstrations
 221
 222These are evaluable. Uncomment locally to watch the universe emerge.
 223
 224`#eval (List.range 9).map (fun t => recurSeq 2 t)`  -- 2, 3/2, 5/3, 8/5, … → φ
 225`#eval qcost (cosmogenesis 2)`                       -- the climbing cost
 226`#eval (cosmogenesis 2).length`                      -- 16
 227`#eval flowProduct (cosmogenesis 2) 0`               -- 1  (σ conserved)
 228-/
 229
 230/-- Conservation holds for the seed-2 run as a direct corollary, kernel-proved. -/
 231example (agent : ℕ) : flowProduct (cosmogenesis 2) agent = 1 :=
 232  cosmogenesis_conserves 2 (by norm_num) agent
 233
 234end CosmogenesisSim
 235end Cosmology
 236end IndisputableMonolith
 237

source mirrored from github.com/jonwashburn/shape-of-logic