|
1 | 1 | import Mathlib.Data.List.Basic
|
2 | 2 | import Mathlib.Tactic.HaveI
|
| 3 | +import Mathlib.Tactic.Simpa |
3 | 4 |
|
4 | 5 | macro_rules | `($x[$i]'$h) => `(getElem $x $i $h)
|
5 | 6 |
|
@@ -94,4 +95,117 @@ lemma get_set (a : Array α) (i j : Nat) (hi : i < a.size) (hj : j < a.size) (v
|
94 | 95 | (a.set ⟨i, hi⟩ v)[j]'(by simp_all) = if i = j then v else a[j] := by
|
95 | 96 | by_cases i = j <;> simp [*]
|
96 | 97 |
|
| 98 | +@[simp] |
| 99 | +theorem size_mkEmpty : (mkEmpty n : Array α).size = 0 := rfl |
| 100 | + |
| 101 | +@[simp] |
| 102 | +theorem size_mapIdxM_map (as : Array α) (bs : Array β) (f : Fin as.size → α → Id β) (i j h) (hj : j = bs.size) : |
| 103 | + (Array.mapIdxM.map as f i j h bs).size = as.size := by |
| 104 | + induction i generalizing j bs |
| 105 | + case zero => subst hj; simp [mapIdxM.map, ← h] |
| 106 | + case succ i ih => |
| 107 | + simp only [mapIdxM.map, Id.bind_eq] |
| 108 | + rw [ih] |
| 109 | + simp [hj] |
| 110 | + |
| 111 | +@[simp] |
| 112 | +theorem size_mapIdxM_Id (a : Array α) (f : Fin a.size → α → Id β) : |
| 113 | + (a.mapIdxM f).size = a.size := by |
| 114 | + simp [mapIdxM, size_mapIdxM_map] |
| 115 | + |
| 116 | +@[simp] |
| 117 | +theorem size_mapIdx (a : Array α) (f : Fin a.size → α → β) : (a.mapIdx f).size = a.size := by |
| 118 | + simp [mapIdx, Id.run] |
| 119 | + |
| 120 | +theorem getElem_mapIdxM_map (as : Array α) (bs : Array β) (f : Fin as.size → α → Id β) (i j h) |
| 121 | + (hj : j = bs.size) (k) (hk : k < as.size) |
| 122 | + (hbs : ∀ k' (hk' : k' < bs.size), |
| 123 | + haveI : k' < as.size := by rw [← h, hj, Nat.add_comm]; exact Nat.lt_add_right _ _ _ hk' |
| 124 | + bs[k'] = f ⟨k', this⟩ as[k']) : |
| 125 | + (Id.run (Array.mapIdxM.map as f i j h bs))[k]'(by simp_all [Id.run]) = f ⟨k, hk⟩ as[k] := by |
| 126 | + induction i generalizing j bs |
| 127 | + case zero => erw [hbs] |
| 128 | + case succ i ih => |
| 129 | + simp only [mapIdxM.map, Id.bind_eq] |
| 130 | + rw [ih] |
| 131 | + · simp [hj] |
| 132 | + · intro k' hk' |
| 133 | + rw [get_push] |
| 134 | + cases (lt_or_eq_of_le <| Nat.le_of_lt_succ (by simpa using hk')) |
| 135 | + case inl hk' => simp [hk', hbs] |
| 136 | + case inr hk' => simp_all |
| 137 | + |
| 138 | +@[simp] |
| 139 | +theorem getElem_mapIdx (a : Array α) (f : Fin a.size → α → β) (i : Nat) (h) : |
| 140 | + haveI : i < a.size := by simp_all |
| 141 | + (a.mapIdx f)[i]'(h) = f ⟨i, this⟩ a[i] := by |
| 142 | + simp only [mapIdx, mapIdxM] |
| 143 | + rw [getElem_mapIdxM_map] |
| 144 | + · simp |
| 145 | + · intro k hk; simp at hk; contradiction |
| 146 | + |
| 147 | +@[simp] |
| 148 | +theorem size_swap! (a : Array α) (i j) (hi : i < a.size) (hj : j < a.size) : (a.swap! i j).size = a.size := by |
| 149 | + simp [swap!, hi, hj] |
| 150 | + |
| 151 | +theorem size_reverse_rev (mid i) (a : Array α) (h : mid ≤ a.size) : (Array.reverse.rev a.size mid a i).size = a.size := |
| 152 | + if hi : i < mid then by |
| 153 | + unfold Array.reverse.rev |
| 154 | + have : i < a.size := lt_of_lt_of_le hi h |
| 155 | + have : a.size - i - 1 < a.size := Nat.sub_lt_self i.zero_lt_succ this |
| 156 | + have := Array.size_reverse_rev mid (i+1) (a.swap! i (a.size - i - 1)) |
| 157 | + simp_all |
| 158 | + else by |
| 159 | + unfold Array.reverse.rev |
| 160 | + simp [dif_neg hi] |
| 161 | +termination_by _ => mid - i |
| 162 | + |
| 163 | +@[simp] |
| 164 | +theorem size_reverse (a : Array α) : a.reverse.size = a.size := by |
| 165 | + have := size_reverse_rev (a.size / 2) 0 a (Nat.div_le_self ..) |
| 166 | + simp only [reverse, this] |
| 167 | + |
| 168 | +@[simp] |
| 169 | +theorem size_ofFn_loop (n) (f : Fin n → α) (i acc) : (ofFn.loop n f i acc).size = acc.size + (n - i) := |
| 170 | + if hin : i < n then by |
| 171 | + unfold ofFn.loop |
| 172 | + have : 1 + (n - (i + 1)) = n - i := |
| 173 | + Nat.sub_sub .. ▸ Nat.add_sub_cancel' (Nat.le_sub_of_add_le (Nat.add_comm .. ▸ hin)) |
| 174 | + rw [dif_pos hin, size_ofFn_loop n f (i+1), size_push, Nat.add_assoc, this] |
| 175 | + else by |
| 176 | + have : n - i = 0 := Nat.sub_eq_zero_of_le (le_of_not_lt hin) |
| 177 | + unfold ofFn.loop |
| 178 | + simp [hin, this] |
| 179 | +termination_by size_ofFn_loop n f i acc => n - i |
| 180 | + |
| 181 | +@[simp] |
| 182 | +theorem size_ofFn (f : Fin n → α) : (ofFn n f).size = n := by |
| 183 | + simp [ofFn] |
| 184 | + |
| 185 | +@[simp] |
| 186 | +theorem getElem_ofFn_loop (n) (f : Fin n → α) (i acc) (k : Nat) (hki : k < n) (hin : i ≤ n) (hi : i = acc.size) |
| 187 | + (hacc : ∀ j, ∀ hj : j < acc.size, acc[j] = f ⟨j, lt_of_lt_of_le hj (by simp_all)⟩) : |
| 188 | + haveI : acc.size + (n - acc.size) = n := Nat.add_sub_cancel' (hi ▸ hin) |
| 189 | + (ofFn.loop n f i acc)[k]'(by simp_all) = f ⟨k, hki⟩ := |
| 190 | + if hin : i < n then by |
| 191 | + unfold ofFn.loop |
| 192 | + have : 1 + (n - (i + 1)) = n - i := |
| 193 | + Nat.sub_sub .. ▸ Nat.add_sub_cancel' (Nat.le_sub_of_add_le (Nat.add_comm .. ▸ hin)) |
| 194 | + simp only [dif_pos hin] |
| 195 | + rw [getElem_ofFn_loop n f (i+1) _ k _ hin (by simp_all) (fun j hj => ?hacc)] |
| 196 | + cases (lt_or_eq_of_le <| Nat.le_of_lt_succ (by simpa using hj)) |
| 197 | + case inl hj => simp [get_push, hj, hacc j hj] |
| 198 | + case inr hj => simp_all [get_push] |
| 199 | + else by |
| 200 | + unfold ofFn.loop |
| 201 | + simp [hin, hacc k (lt_of_lt_of_le hki (le_of_not_gt (hi ▸ hin)))] |
| 202 | +termination_by |
| 203 | + getElem_ofFn_loop n f i acc k hki hin hi hacc => n - i |
| 204 | + |
| 205 | +@[simp] |
| 206 | +theorem getElem_ofFn (f : Fin n → α) (i : Nat) (h) : (ofFn n f)[i] = f ⟨i, by simp_all⟩ := by |
| 207 | + unfold ofFn |
| 208 | + rw [getElem_ofFn_loop] <;> try {simp} |
| 209 | + · intro j hj; simp at hj; contradiction |
| 210 | + |
97 | 211 | end Array
|
0 commit comments