@@ -208,4 +208,98 @@ by cases i; refl
208
208
209
209
end rec
210
210
211
+ section find
212
+
213
+ def find : Π {n : ℕ} (p : fin n → Prop ) [decidable_pred p], option (fin n)
214
+ | 0 p _ := none
215
+ | (n+1 ) p _ := by resetI; exact option.cases_on
216
+ (@find n (λ i, p (i.cast_lt (nat.lt_succ_of_lt i.2 ))) _)
217
+ (if h : p (fin.last n) then some (fin.last n) else none)
218
+ (λ i, some (i.cast_lt (nat.lt_succ_of_lt i.2 )))
219
+
220
+ lemma find_spec : Π {n : ℕ} (p : fin n → Prop ) [decidable_pred p] {i : fin n}
221
+ (hi : i ∈ by exactI fin.find p), p i
222
+ | 0 p I i hi := option.no_confusion hi
223
+ | (n+1 ) p I i hi := begin
224
+ dsimp [find] at hi,
225
+ resetI,
226
+ cases h : find (λ i : fin n, (p (i.cast_lt (nat.lt_succ_of_lt i.2 )))) with j,
227
+ { rw h at hi,
228
+ dsimp at hi,
229
+ split_ifs at hi with hl hl,
230
+ { exact option.some_inj.1 hi ▸ hl },
231
+ { exact option.no_confusion hi } },
232
+ { rw h at hi,
233
+ rw [← option.some_inj.1 hi],
234
+ exact find_spec _ h }
235
+ end
236
+
237
+ lemma is_some_find_iff : Π {n : ℕ} {p : fin n → Prop } [decidable_pred p],
238
+ by exactI (find p).is_some ↔ ∃ i, p i
239
+ | 0 p _ := iff_of_false (λ h, bool.no_confusion h) (λ ⟨i, _⟩, fin.elim0 i)
240
+ | (n+1 ) p _ := ⟨λ h, begin
241
+ resetI,
242
+ rw [option.is_some_iff_exists] at h,
243
+ cases h with i hi,
244
+ exact ⟨i, find_spec _ hi⟩
245
+ end , λ ⟨⟨i, hin⟩, hi⟩,
246
+ begin
247
+ resetI,
248
+ dsimp [find],
249
+ cases h : find (λ i : fin n, (p (i.cast_lt (nat.lt_succ_of_lt i.2 )))) with j,
250
+ { split_ifs with hl hl,
251
+ { exact option.is_some_some },
252
+ { have := (@is_some_find_iff n (λ x, p (x.cast_lt (nat.lt_succ_of_lt x.2 ))) _).2
253
+ ⟨⟨i, lt_of_le_of_ne (nat.le_of_lt_succ hin)
254
+ (λ h, by clear_aux_decl; subst h; exact hl hi)⟩, hi⟩,
255
+ rw h at this ,
256
+ exact this } },
257
+ { simp }
258
+ end ⟩
259
+
260
+ lemma find_eq_none_iff {n : ℕ} {p : fin n → Prop } [decidable_pred p] :
261
+ find p = none ↔ ∀ i, ¬ p i :=
262
+ by rw [← not_exists, ← is_some_find_iff]; cases (find p); simp
263
+
264
+ lemma find_min : Π {n : ℕ} {p : fin n → Prop } [decidable_pred p] {i : fin n}
265
+ (hi : i ∈ by exactI fin.find p) {j : fin n} (hj : j < i), ¬ p j
266
+ | 0 p _ i hi j hj hpj := option.no_confusion hi
267
+ | (n+1 ) p _ i hi ⟨j, hjn⟩ hj hpj := begin
268
+ resetI,
269
+ dsimp [find] at hi,
270
+ cases h : find (λ i : fin n, (p (i.cast_lt (nat.lt_succ_of_lt i.2 )))) with k,
271
+ { rw [h] at hi,
272
+ split_ifs at hi with hl hl,
273
+ { have := option.some_inj.1 hi,
274
+ subst this ,
275
+ rw [find_eq_none_iff] at h,
276
+ exact h ⟨j, hj⟩ hpj },
277
+ { exact option.no_confusion hi } },
278
+ { rw h at hi,
279
+ dsimp at hi,
280
+ have := option.some_inj.1 hi,
281
+ subst this ,
282
+ exact find_min h (show (⟨j, lt_trans hj k.2 ⟩ : fin n) < k, from hj) hpj }
283
+ end
284
+
285
+ lemma find_min' {p : fin n → Prop } [decidable_pred p] {i : fin n}
286
+ (h : i ∈ fin.find p) {j : fin n} (hj : p j) : i ≤ j :=
287
+ le_of_not_gt (λ hij, find_min h hij hj)
288
+
289
+ lemma nat_find_mem_find {p : fin n → Prop } [decidable_pred p]
290
+ (h : ∃ i, ∃ hin : i < n, p ⟨i, hin⟩) :
291
+ (⟨nat.find h, (nat.find_spec h).fst⟩ : fin n) ∈ find p :=
292
+ let ⟨i, hin, hi⟩ := h in
293
+ begin
294
+ cases hf : find p with f,
295
+ { rw [find_eq_none_iff] at hf,
296
+ exact (hf ⟨i, hin⟩ hi).elim },
297
+ { refine option.some_inj.2 (le_antisymm _ _),
298
+ { exact find_min' hf (nat.find_spec h).snd },
299
+ { exact nat.find_min' _ ⟨f.2 , by convert find_spec p hf;
300
+ exact fin.eta _ _⟩ } }
301
+ end
302
+
303
+ end find
304
+
211
305
end fin
0 commit comments