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

Commit 225d1ce

Browse files
committed
refactor(combinatorics/hall/finite): small simplifications and readability improvements (#13091)
1 parent 9ff42fd commit 225d1ce

File tree

1 file changed

+55
-81
lines changed

1 file changed

+55
-81
lines changed

src/combinatorics/hall/finite.lean

Lines changed: 55 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,7 @@ universes u v
3838

3939
namespace hall_marriage_theorem
4040

41-
variables {ι : Type u} {α : Type v} [fintype ι]
42-
43-
theorem hall_hard_inductive_zero (t : ι → finset α) (hn : fintype.card ι = 0) :
44-
∃ (f : ι → α), function.injective f ∧ ∀ x, f x ∈ t x :=
45-
begin
46-
rw fintype.card_eq_zero_iff at hn,
47-
exactI ⟨is_empty_elim, is_empty_elim, is_empty_elim⟩,
48-
end
49-
50-
variables {t : ι → finset α} [decidable_eq α]
41+
variables {ι : Type u} {α : Type v} [fintype ι] {t : ι → finset α} [decidable_eq α]
5142

5243
lemma hall_cond_of_erase {x : ι} (a : α)
5344
(ha : ∀ (s : finset ι), s.nonempty → s ≠ univ → s.card < (s.bUnion t).card)
@@ -59,8 +50,7 @@ begin
5950
rw [nonempty.image_iff, finset.card_image_of_injective s' subtype.coe_injective] at ha,
6051
by_cases he : s'.nonempty,
6152
{ have ha' : s'.card < (s'.bUnion (λ x, t x)).card,
62-
{ specialize ha he (λ h, by { have h' := mem_univ x, rw ←h at h', simpa using h' }),
63-
convert ha using 2,
53+
{ convert ha he (λ h, by simpa [←h] using mem_univ x) using 2,
6454
ext x,
6555
simp only [mem_image, mem_bUnion, exists_prop, set_coe.exists,
6656
exists_and_distrib_right, exists_eq_right, subtype.coe_mk], },
@@ -96,25 +86,23 @@ begin
9686
let x := classical.arbitrary ι,
9787
have tx_ne : (t x).nonempty,
9888
{ rw ←finset.card_pos,
99-
apply nat.lt_of_lt_of_le nat.one_pos,
100-
convert ht {x},
101-
rw finset.singleton_bUnion, },
102-
rcases classical.indefinite_description _ tx_ne with ⟨y, hy,
89+
calc 0 < 1 : nat.one_pos
90+
... ≤ (finset.bUnion {x} t).card : ht {x}
91+
... = (t x).card : by rw finset.singleton_bUnion, },
92+
choose y hy using tx_ne,
10393
/- Restrict to everything except `x` and `y`. -/
10494
let ι' := {x' : ι | x' ≠ x},
10595
let t' : ι' → finset α := λ x', (t x').erase y,
106-
have card_ι' : fintype.card ι' = n,
107-
{ convert congr_arg (λ m, m - 1) hn,
108-
convert set.card_ne_eq _, },
96+
have card_ι' : fintype.card ι' = n :=
97+
calc fintype.card ι' = fintype.card ι - 1 : set.card_ne_eq _
98+
... = n : by { rw [hn, nat.add_succ_sub_one, add_zero], },
10999
rcases ih t' card_ι'.le (hall_cond_of_erase y ha) with ⟨f', hfinj, hfr⟩,
110100
/- Extend the resulting function. -/
111101
refine ⟨λ z, if h : z = x then y else f' ⟨z, h⟩, _, _⟩,
112102
{ rintro z₁ z₂,
113103
have key : ∀ {x}, y ≠ f' x,
114104
{ intros x h,
115-
specialize hfr x,
116-
rw ←h at hfr,
117-
simpa using hfr, },
105+
simpa [←h] using hfr x, },
118106
by_cases h₁ : z₁ = x; by_cases h₂ : z₂ = x; simp [h₁, h₂, hfinj.eq_iff, key, key.symm], },
119107
{ intro z,
120108
split_ifs with hz,
@@ -129,12 +117,12 @@ lemma hall_cond_of_restrict {ι : Type u} {t : ι → finset α} {s : finset ι}
129117
(s' : finset (s : set ι)) :
130118
s'.card ≤ (s'.bUnion (λ a', t a')).card :=
131119
begin
132-
haveI := classical.dec_eq ι,
120+
classical,
121+
rw ← card_image_of_injective s' subtype.coe_injective,
133122
convert ht (s'.image coe) using 1,
134-
{ rw card_image_of_injective _ subtype.coe_injective, },
135-
{ apply congr_arg,
136-
ext y,
137-
simp, },
123+
apply congr_arg,
124+
ext y,
125+
simp,
138126
end
139127

140128
lemma hall_cond_of_compl {ι : Type u} {t : ι → finset α} {s : finset ι}
@@ -144,32 +132,31 @@ lemma hall_cond_of_compl {ι : Type u} {t : ι → finset α} {s : finset ι}
144132
s'.card ≤ (s'.bUnion (λ x', t x' \ s.bUnion t)).card :=
145133
begin
146134
haveI := classical.dec_eq ι,
147-
have : s'.card = (s ∪ s'.image coe).card - s.card,
148-
{ rw [card_disjoint_union, add_tsub_cancel_left,
149-
card_image_of_injective _ subtype.coe_injective],
150-
simp only [disjoint_left, not_exists, mem_image, exists_prop, set_coe.exists,
135+
have disj : disjoint s (s'.image coe),
136+
{ simp only [disjoint_left, not_exists, mem_image, exists_prop, set_coe.exists,
151137
exists_and_distrib_right, exists_eq_right, subtype.coe_mk],
152138
intros x hx hc h,
153-
exact (hc hx).elim },
139+
exact absurd hx hc, },
140+
have : s'.card = (s ∪ s'.image coe).card - s.card,
141+
{ simp [disj, card_image_of_injective _ subtype.coe_injective], },
154142
rw [this, hus],
155-
apply (tsub_le_tsub_right (ht _) _).trans _,
143+
refine (tsub_le_tsub_right (ht _) _).trans _,
156144
rw ← card_sdiff,
157-
{ have : (s ∪ s'.image subtype.val).bUnion t \ s.bUnion t ⊆ s'.bUnion (λ x', t x' \ s.bUnion t),
158-
{ intros t,
159-
simp only [mem_bUnion, mem_sdiff, not_exists, mem_image, and_imp, mem_union,
160-
exists_and_distrib_right, exists_imp_distrib],
161-
rintro x (hx | ⟨x', hx', rfl⟩) rat hs,
162-
{ exact (hs x hx rat).elim },
163-
{ exact ⟨⟨x', hx', rat⟩, hs⟩, } },
164-
exact (card_le_of_subset this).trans le_rfl, },
145+
{ refine (card_le_of_subset _).trans le_rfl,
146+
intros t,
147+
simp only [mem_bUnion, mem_sdiff, not_exists, mem_image, and_imp, mem_union,
148+
exists_and_distrib_right, exists_imp_distrib],
149+
rintro x (hx | ⟨x', hx', rfl⟩) rat hs,
150+
{ exact (hs x hx rat).elim },
151+
{ exact ⟨⟨x', hx', rat⟩, hs⟩, } },
165152
{ apply bUnion_subset_bUnion_of_subset_left,
166153
apply subset_union_left }
167154
end
168155

169156
/--
170157
Second case of the inductive step: assuming that
171158
`∃ (s : finset ι), s ≠ univ → s.card = (s.bUnion t).card`
172-
and that the statement of Hall's Marriage Theorem is true for all
159+
and that the statement of **Hall's Marriage Theorem** is true for all
173160
`ι'` of cardinality ≤ `n`, then it is true for `ι` of cardinality `n + 1`.
174161
-/
175162
lemma hall_hard_inductive_step_B {n : ℕ} (hn : fintype.card ι = n + 1)
@@ -190,9 +177,9 @@ begin
190177
rw nat.add_one at hn,
191178
have card_ι'_le : fintype.card s ≤ n,
192179
{ apply nat.le_of_lt_succ,
193-
rw ←hn,
194-
convert (card_lt_iff_ne_univ _).mpr hns,
195-
rw fintype.card_coe },
180+
calc fintype.card s = s.card : fintype.card_coe _
181+
... < fintype.card ι : (card_lt_iff_ne_univ _).mpr hns
182+
... = n.succ : hn },
196183
rcases ih t' card_ι'_le (hall_cond_of_restrict ht) with ⟨f', hf', hsf'⟩,
197184
/- Restrict to `sᶜ` in the domain and `(s.bUnion t)ᶜ` in the codomain. -/
198185
set ι'' := (s : set ι)ᶜ with ι''_def,
@@ -211,56 +198,43 @@ begin
211198
have h := hsf'' ⟨x'', hx''⟩,
212199
rw mem_sdiff at h,
213200
exact h.2, },
214-
have im_disj : ∀ {x' x'' : ι} {hx' : x' ∈ s} {hx'' : ¬x'' ∈ s}, f' ⟨x', hx'⟩ ≠ f'' ⟨x'', hx''⟩,
201+
have im_disj : ∀ (x' x'' : ι) (hx' : x' ∈ s) (hx'' : ¬x'' ∈ s), f' ⟨x', hx'⟩ ≠ f'' ⟨x'', hx''⟩,
215202
{ intros _ _ hx' hx'' h,
216203
apply f''_not_mem_bUnion hx'',
217204
rw ←h,
218205
apply f'_mem_bUnion, },
219206
refine ⟨λ x, if h : x ∈ s then f' ⟨x, h⟩ else f'' ⟨x, h⟩, _, _⟩,
220-
{ exact hf'.dite _ hf'' @im_disj },
207+
{ exact hf'.dite _ hf'' im_disj },
221208
{ intro x,
222-
split_ifs,
209+
split_ifs with h,
223210
{ exact hsf' ⟨x, h⟩ },
224211
{ exact sdiff_subset _ _ (hsf'' ⟨x, h⟩) } }
225212
end
226213

227214
/--
228-
If `ι` has cardinality `n + 1` and the statement of Hall's Marriage Theorem
229-
is true for all `ι'` of cardinality ≤ `n`, then it is true for `ι`.
230-
-/
231-
theorem hall_hard_inductive_step {n : ℕ} (hn : fintype.card ι = n + 1)
232-
(ht : ∀ (s : finset ι), s.card ≤ (s.bUnion t).card)
233-
(ih : ∀ {ι' : Type u} [fintype ι'] (t' : ι' → finset α),
234-
by exactI fintype.card ι' ≤ n →
235-
(∀ (s' : finset ι'), s'.card ≤ (s'.bUnion t').card) →
236-
∃ (f : ι' → α), function.injective f ∧ ∀ x, f x ∈ t' x) :
237-
∃ (f : ι → α), function.injective f ∧ ∀ x, f x ∈ t x :=
238-
begin
239-
by_cases h : ∀ (s : finset ι), s.nonempty → s ≠ univ → s.card < (s.bUnion t).card,
240-
{ exact hall_hard_inductive_step_A hn ht @ih h, },
241-
{ push_neg at h,
242-
rcases h with ⟨s, sne, snu, sle⟩,
243-
have seq := nat.le_antisymm (ht _) sle,
244-
exact hall_hard_inductive_step_B hn ht @ih s sne snu seq, },
245-
end
246-
247-
/--
248-
Here we combine the base case and the inductive step into
249-
a full strong induction proof, thus completing the proof
250-
of the second direction.
215+
Here we combine the two inductive steps into a full strong induction proof,
216+
completing the proof the harder direction of **Hall's Marriage Theorem**.
251217
-/
252-
theorem hall_hard_inductive {n : ℕ} (hn : fintype.card ι = n)
218+
theorem hall_hard_inductive
253219
(ht : ∀ (s : finset ι), s.card ≤ (s.bUnion t).card) :
254220
∃ (f : ι → α), function.injective f ∧ ∀ x, f x ∈ t x :=
255221
begin
256-
unfreezingI { revert ι },
257-
refine nat.strong_induction_on n (λ n' ih, _),
258-
intros _ _ t hn ht,
259-
rcases n' with (_|_),
260-
{ exactI hall_hard_inductive_zero t hn },
261-
{ resetI, apply hall_hard_inductive_step hn ht,
262-
introsI ι' _ _ hι',
263-
exact ih (fintype.card ι') (nat.lt_succ_of_le hι') rfl, },
222+
unfreezingI
223+
{ induction hn : fintype.card ι using nat.strong_induction_on with n ih generalizing ι },
224+
rcases n with _|_,
225+
{ rw fintype.card_eq_zero_iff at hn,
226+
exactI ⟨is_empty_elim, is_empty_elim, is_empty_elim⟩, },
227+
{ have ih' : ∀ (ι' : Type u) [fintype ι'] (t' : ι' → finset α),
228+
by exactI fintype.card ι' ≤ n →
229+
(∀ (s' : finset ι'), s'.card ≤ (s'.bUnion t').card) →
230+
∃ (f : ι' → α), function.injective f ∧ ∀ x, f x ∈ t' x,
231+
{ introsI ι' _ _ hι' ht',
232+
exact ih _ (nat.lt_succ_of_le hι') ht' rfl, },
233+
by_cases h : ∀ (s : finset ι), s.nonempty → s ≠ univ → s.card < (s.bUnion t).card,
234+
{ exact hall_hard_inductive_step_A hn ht ih' h, },
235+
{ push_neg at h,
236+
rcases h with ⟨s, sne, snu, sle⟩,
237+
exact hall_hard_inductive_step_B hn ht ih' s sne snu (nat.le_antisymm (ht _) sle), } },
264238
end
265239

266240
end hall_marriage_theorem
@@ -280,7 +254,7 @@ theorem finset.all_card_le_bUnion_card_iff_exists_injective'
280254
(∃ (f : ι → α), function.injective f ∧ ∀ x, f x ∈ t x) :=
281255
begin
282256
split,
283-
{ exact hall_marriage_theorem.hall_hard_inductive rfl },
257+
{ exact hall_marriage_theorem.hall_hard_inductive },
284258
{ rintro ⟨f, hf₁, hf₂⟩ s,
285259
rw ←card_image_of_injective s hf₁,
286260
apply card_le_of_subset,

0 commit comments

Comments
 (0)