Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 080362d

Browse files
committed
feat(data/finset/pi_induction): induction on Π i, finset (α i) (#8794)
1 parent 83490fc commit 080362d

File tree

2 files changed

+110
-6
lines changed

2 files changed

+110
-6
lines changed

src/data/finset/basic.lean

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ lemma eq_empty_iff_forall_not_mem {s : finset α} : s = ∅ ↔ ∀ x, x ∉ s :
356356

357357
theorem subset_empty {s : finset α} : s ⊆ ∅ ↔ s = ∅ := subset_zero.trans val_eq_zero
358358

359+
@[simp] lemma not_ssubset_empty (s : finset α) : ¬s ⊂ ∅ :=
360+
λ h, let ⟨x, he, hs⟩ := exists_of_ssubset h in he
361+
359362
theorem nonempty_of_ne_empty {s : finset α} (h : s ≠ ∅) : s.nonempty :=
360363
exists_mem_of_ne_zero (mt val_eq_zero.1 h)
361364

@@ -1628,11 +1631,9 @@ def not_mem_range_equiv (k : ℕ) : {n // n ∉ range k} ≃ ℕ :=
16281631
namespace option
16291632

16301633
/-- Construct an empty or singleton finset from an `option` -/
1631-
def to_finset (o : option α) : finset α :=
1632-
match o with
1633-
| none := ∅
1634-
| some a := {a}
1635-
end
1634+
def to_finset : option α → finset α
1635+
| none := ∅
1636+
| (some a) := {a}
16361637

16371638
@[simp] theorem to_finset_none : none.to_finset = (∅ : finset α) := rfl
16381639

@@ -2705,7 +2706,13 @@ protected def sigma (s : finset α) (t : Πa, finset (σ a)) : finset (Σa, σ a
27052706

27062707
@[simp] theorem mem_sigma {p : sigma σ} : p ∈ s.sigma t ↔ p.1 ∈ s ∧ p.2 ∈ t (p.1) := mem_sigma
27072708

2708-
theorem sigma_mono {s₁ s₂ : finset α} {t₁ t₂ : Πa, finset (σ a)}
2709+
@[simp] theorem sigma_nonempty : (s.sigma t).nonempty ↔ ∃ x ∈ s, (t x).nonempty :=
2710+
by simp [finset.nonempty]
2711+
2712+
@[simp] theorem sigma_eq_empty : s.sigma t = ∅ ↔ ∀ x ∈ s, t x = ∅ :=
2713+
by simp only [← not_nonempty_iff_eq_empty, sigma_nonempty, not_exists]
2714+
2715+
@[mono] theorem sigma_mono {s₁ s₂ : finset α} {t₁ t₂ : Πa, finset (σ a)}
27092716
(H1 : s₁ ⊆ s₂) (H2 : ∀a, t₁ a ⊆ t₂ a) : s₁.sigma t₁ ⊆ s₂.sigma t₂ :=
27102717
λ ⟨x, sx⟩ H, let ⟨H3, H4⟩ := mem_sigma.1 H in mem_sigma.2 ⟨H1 H3, H2 x H4⟩
27112718

src/data/finset/pi_induction.lean

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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

Comments
 (0)