|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Yury Kudryashov. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yury Kudryashov |
| 5 | +-/ |
| 6 | +import data.fintype.basic |
| 7 | + |
| 8 | +/-! |
| 9 | +# Induction principles for `Π i, finset (α i)` |
| 10 | +
|
| 11 | +In this file we prove a few induction principles for functions `Π i : ι, finset (α i)` defined on a |
| 12 | +finite type. |
| 13 | +
|
| 14 | +* `finset.induction_on_pi` is a generic lemma that requires only `[fintype ι]`, `[decidable_eq ι]`, |
| 15 | + and `[Π i, decidable_eq (α i)]`; this version can be seen as a direct generalization of |
| 16 | + `finset.induction_on`. |
| 17 | +
|
| 18 | +* `finset.induction_on_pi_max` and `finset.induction_on_pi_min`: generalizations of |
| 19 | + `finset.induction_on_max`; these versions require `Π i, linear_order (α i)` but assume |
| 20 | + `∀ y ∈ g i, y < x` and `∀ y ∈ g i, x < y` respectively in the induction step. |
| 21 | +
|
| 22 | +## Tags |
| 23 | +finite set, finite type, induction, function |
| 24 | +-/ |
| 25 | + |
| 26 | +open function |
| 27 | + |
| 28 | +variables {ι : Type*} {α : ι → Type*} [fintype ι] [decidable_eq ι] [Π i, decidable_eq (α i)] |
| 29 | + |
| 30 | +namespace finset |
| 31 | + |
| 32 | +/-- General theorem for `finset.induction_on_pi`-style induction principles. -/ |
| 33 | +lemma induction_on_pi_of_choice (r : Π i, α i → finset (α i) → Prop) |
| 34 | + (H_ex : ∀ i (s : finset (α i)) (hs : s.nonempty), ∃ x ∈ s, r i x (s.erase x)) |
| 35 | + {p : (Π i, finset (α i)) → Prop} (f : Π i, finset (α i)) (h0 : p (λ _, ∅)) |
| 36 | + (step : ∀ (g : Π i, finset (α i)) (i : ι) (x : α i), |
| 37 | + r i x (g i) → p g → p (update g i (insert x (g i)))) : |
| 38 | + p f := |
| 39 | +begin |
| 40 | + induction hs : univ.sigma f using finset.strong_induction_on with s ihs generalizing f, subst s, |
| 41 | + cases eq_empty_or_nonempty (univ.sigma f) with he hne, |
| 42 | + { convert h0, simpa [funext_iff] using he }, |
| 43 | + { rcases sigma_nonempty.1 hne with ⟨i, -, hi⟩, |
| 44 | + rcases H_ex i (f i) hi with ⟨x, x_mem, hr⟩, |
| 45 | + set g := update f i ((f i).erase x) with hg, clear_value g, |
| 46 | + have hx' : x ∉ g i, by { rw [hg, update_same], apply not_mem_erase }, |
| 47 | + obtain rfl : f = update g i (insert x (g i)), |
| 48 | + by rw [hg, update_idem, update_same, insert_erase x_mem, update_eq_self], |
| 49 | + clear hg, rw [update_same, erase_insert hx'] at hr, |
| 50 | + refine step _ _ _ hr (ihs (univ.sigma g) _ _ rfl), |
| 51 | + rw ssubset_iff_of_subset (sigma_mono (subset.refl _) _), |
| 52 | + exacts [⟨⟨i, x⟩, mem_sigma.2 ⟨mem_univ _, by simp⟩, by simp [hx']⟩, |
| 53 | + (@le_update_iff _ _ _ _ g g i _).2 ⟨subset_insert _ _, λ _ _, le_rfl⟩] } |
| 54 | +end |
| 55 | + |
| 56 | +/-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all |
| 57 | +maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index |
| 58 | +`i : ι`, and `x ∉ g i`, `p g` implies `p (update g i (insert x (g i)))`. |
| 59 | +
|
| 60 | +See also `finset.induction_on_pi_max` and `finset.induction_on_pi_min` for specialized versions |
| 61 | +that require `Π i, linear_order (α i)`. -/ |
| 62 | +lemma induction_on_pi {p : (Π i, finset (α i)) → Prop} (f : Π i, finset (α i)) (h0 : p (λ _, ∅)) |
| 63 | + (step : ∀ (g : Π i, finset (α i)) (i : ι) (x : α i) (hx : x ∉ g i), |
| 64 | + p g → p (update g i (insert x (g i)))) : |
| 65 | + p f := |
| 66 | +induction_on_pi_of_choice (λ i x s, x ∉ s) (λ i s ⟨x, hx⟩, ⟨x, hx, not_mem_erase x s⟩) f h0 step |
| 67 | + |
| 68 | +/-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all |
| 69 | +maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index |
| 70 | +`i : ι`, and an element`x : α i` that is strictly greater than all elements of `g i`, `p g` implies |
| 71 | +`p (update g i (insert x (g i)))`. |
| 72 | +
|
| 73 | +This lemma requires `linear_order` instances on all `α i`. See also `finset.induction_on_pi` for a |
| 74 | +version that `x ∉ g i` instead of ` does not need `Π i, linear_order (α i)`. -/ |
| 75 | +lemma induction_on_pi_max [Π i, linear_order (α i)] {p : (Π i, finset (α i)) → Prop} |
| 76 | + (f : Π i, finset (α i)) (h0 : p (λ _, ∅)) |
| 77 | + (step : ∀ (g : Π i, finset (α i)) (i : ι) (x : α i), |
| 78 | + (∀ y ∈ g i, y < x) → p g → p (update g i (insert x (g i)))) : |
| 79 | + p f := |
| 80 | +induction_on_pi_of_choice (λ i x s, ∀ y ∈ s, y < x) |
| 81 | + (λ i s hs, ⟨s.max' hs, s.max'_mem hs, λ y, s.lt_max'_of_mem_erase_max' _⟩) f h0 step |
| 82 | + |
| 83 | +/-- Given a predicate on functions `Π i, finset (α i)` defined on a finite type, it is true on all |
| 84 | +maps provided that it is true on `λ _, ∅` and for any function `g : Π i, finset (α i)`, an index |
| 85 | +`i : ι`, and an element`x : α i` that is strictly less than all elements of `g i`, `p g` implies |
| 86 | +`p (update g i (insert x (g i)))`. |
| 87 | +
|
| 88 | +This lemma requires `linear_order` instances on all `α i`. See also `finset.induction_on_pi` for a |
| 89 | +version that `x ∉ g i` instead of ` does not need `Π i, linear_order (α i)`. -/ |
| 90 | +lemma induction_on_pi_min [Π i, linear_order (α i)] {p : (Π i, finset (α i)) → Prop} |
| 91 | + (f : Π i, finset (α i)) (h0 : p (λ _, ∅)) |
| 92 | + (step : ∀ (g : Π i, finset (α i)) (i : ι) (x : α i), |
| 93 | + (∀ y ∈ g i, x < y) → p g → p (update g i (insert x (g i)))) : |
| 94 | + p f := |
| 95 | +@induction_on_pi_max ι (λ i, order_dual (α i)) _ _ _ _ _ _ h0 step |
| 96 | + |
| 97 | +end finset |
0 commit comments