-
Notifications
You must be signed in to change notification settings - Fork 251
/
Finite.lean
269 lines (240 loc) · 11.5 KB
/
Finite.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/-
Copyright (c) 2021 Alena Gusakov, Bhavik Mehta, Kyle Miller. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alena Gusakov, Bhavik Mehta, Kyle Miller
-/
import Mathlib.Data.Fintype.Basic
import Mathlib.Data.Set.Finite
#align_import combinatorics.hall.finite from "leanprover-community/mathlib"@"d6fad0e5bf2d6f48da9175d25c3dc5706b3834ce"
/-!
# Hall's Marriage Theorem for finite index types
This module proves the basic form of Hall's theorem.
In contrast to the theorem described in `Combinatorics.Hall.Basic`, this
version requires that the indexed family `t : ι → Finset α` have `ι` be finite.
The `Combinatorics.Hall.Basic` module applies a compactness argument to this version
to remove the `Finite` constraint on `ι`.
The modules are split like this since the generalized statement
depends on the topology and category theory libraries, but the finite
case in this module has few dependencies.
A description of this formalization is in [Gusakov2021].
## Main statements
* `Finset.all_card_le_biUnion_card_iff_existsInjective'` is Hall's theorem with
a finite index set. This is elsewhere generalized to
`Finset.all_card_le_biUnion_card_iff_existsInjective`.
## Tags
Hall's Marriage Theorem, indexed families
-/
open Finset
universe u v
namespace HallMarriageTheorem
variable {ι : Type u} {α : Type v} [DecidableEq α] {t : ι → Finset α}
section Fintype
variable [Fintype ι]
theorem hall_cond_of_erase {x : ι} (a : α)
(ha : ∀ s : Finset ι, s.Nonempty → s ≠ univ → s.card < (s.biUnion t).card)
(s' : Finset { x' : ι | x' ≠ x }) : s'.card ≤ (s'.biUnion fun x' => (t x').erase a).card := by
haveI := Classical.decEq ι
specialize ha (s'.image fun z => z.1)
rw [image_nonempty, Finset.card_image_of_injective s' Subtype.coe_injective] at ha
by_cases he : s'.Nonempty
· have ha' : s'.card < (s'.biUnion fun x => t x).card := by
convert ha he fun h => by simpa [← h] using mem_univ x using 2
ext x
simp only [mem_image, mem_biUnion, exists_prop, SetCoe.exists, exists_and_right,
exists_eq_right, Subtype.coe_mk]
rw [← erase_biUnion]
by_cases hb : a ∈ s'.biUnion fun x => t x
· rw [card_erase_of_mem hb]
exact Nat.le_sub_one_of_lt ha'
· rw [erase_eq_of_not_mem hb]
exact Nat.le_of_lt ha'
· rw [nonempty_iff_ne_empty, not_not] at he
subst s'
simp
#align hall_marriage_theorem.hall_cond_of_erase HallMarriageTheorem.hall_cond_of_erase
/-- First case of the inductive step: assuming that
`∀ (s : Finset ι), s.Nonempty → s ≠ univ → s.card < (s.biUnion t).card`
and that the statement of **Hall's Marriage Theorem** is true for all
`ι'` of cardinality ≤ `n`, then it is true for `ι` of cardinality `n + 1`.
-/
theorem hall_hard_inductive_step_A {n : ℕ} (hn : Fintype.card ι = n + 1)
(ht : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card)
(ih :
∀ {ι' : Type u} [Fintype ι'] (t' : ι' → Finset α),
Fintype.card ι' ≤ n →
(∀ s' : Finset ι', s'.card ≤ (s'.biUnion t').card) →
∃ f : ι' → α, Function.Injective f ∧ ∀ x, f x ∈ t' x)
(ha : ∀ s : Finset ι, s.Nonempty → s ≠ univ → s.card < (s.biUnion t).card) :
∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by
haveI : Nonempty ι := Fintype.card_pos_iff.mp (hn.symm ▸ Nat.succ_pos _)
haveI := Classical.decEq ι
-- Choose an arbitrary element `x : ι` and `y : t x`.
let x := Classical.arbitrary ι
have tx_ne : (t x).Nonempty := by
rw [← Finset.card_pos]
calc
0 < 1 := Nat.one_pos
_ ≤ (Finset.biUnion {x} t).card := ht {x}
_ = (t x).card := by rw [Finset.singleton_biUnion]
choose y hy using tx_ne
-- Restrict to everything except `x` and `y`.
let ι' := { x' : ι | x' ≠ x }
let t' : ι' → Finset α := fun x' => (t x').erase y
have card_ι' : Fintype.card ι' = n :=
calc
Fintype.card ι' = Fintype.card ι - 1 := Set.card_ne_eq _
_ = n := by rw [hn, Nat.add_succ_sub_one, add_zero]
rcases ih t' card_ι'.le (hall_cond_of_erase y ha) with ⟨f', hfinj, hfr⟩
-- Extend the resulting function.
refine ⟨fun z => if h : z = x then y else f' ⟨z, h⟩, ?_, ?_⟩
· rintro z₁ z₂
have key : ∀ {x}, y ≠ f' x := by
intro x h
simpa [t', ← h] using hfr x
by_cases h₁ : z₁ = x <;> by_cases h₂ : z₂ = x <;> simp [h₁, h₂, hfinj.eq_iff, key, key.symm]
· intro z
simp only [ne_eq, Set.mem_setOf_eq]
split_ifs with hz
· rwa [hz]
· specialize hfr ⟨z, hz⟩
rw [mem_erase] at hfr
exact hfr.2
set_option linter.uppercaseLean3 false in
#align hall_marriage_theorem.hall_hard_inductive_step_A HallMarriageTheorem.hall_hard_inductive_step_A
theorem hall_cond_of_restrict {ι : Type u} {t : ι → Finset α} {s : Finset ι}
(ht : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) (s' : Finset (s : Set ι)) :
s'.card ≤ (s'.biUnion fun a' => t a').card := by
classical
rw [← card_image_of_injective s' Subtype.coe_injective]
convert ht (s'.image fun z => z.1) using 1
apply congr_arg
ext y
simp
#align hall_marriage_theorem.hall_cond_of_restrict HallMarriageTheorem.hall_cond_of_restrict
theorem hall_cond_of_compl {ι : Type u} {t : ι → Finset α} {s : Finset ι}
(hus : s.card = (s.biUnion t).card) (ht : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card)
(s' : Finset (sᶜ : Set ι)) : s'.card ≤ (s'.biUnion fun x' => t x' \ s.biUnion t).card := by
haveI := Classical.decEq ι
have disj : Disjoint s (s'.image fun z => z.1) := by
simp only [disjoint_left, not_exists, mem_image, exists_prop, SetCoe.exists, exists_and_right,
exists_eq_right, Subtype.coe_mk]
intro x hx hc _
exact absurd hx hc
have : s'.card = (s ∪ s'.image fun z => z.1).card - s.card := by
simp [disj, card_image_of_injective _ Subtype.coe_injective, Nat.add_sub_cancel_left]
rw [this, hus]
refine (Nat.sub_le_sub_right (ht _) _).trans ?_
rw [← card_sdiff]
· refine (card_le_card ?_).trans le_rfl
intro t
simp only [mem_biUnion, mem_sdiff, not_exists, mem_image, and_imp, mem_union, exists_and_right,
exists_imp]
rintro x (hx | ⟨x', hx', rfl⟩) rat hs
· exact False.elim <| (hs x) <| And.intro hx rat
· use x', hx', rat, hs
· apply biUnion_subset_biUnion_of_subset_left
apply subset_union_left
#align hall_marriage_theorem.hall_cond_of_compl HallMarriageTheorem.hall_cond_of_compl
/-- Second case of the inductive step: assuming that
`∃ (s : Finset ι), s ≠ univ → s.card = (s.biUnion t).card`
and that the statement of **Hall's Marriage Theorem** is true for all
`ι'` of cardinality ≤ `n`, then it is true for `ι` of cardinality `n + 1`.
-/
theorem hall_hard_inductive_step_B {n : ℕ} (hn : Fintype.card ι = n + 1)
(ht : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card)
(ih :
∀ {ι' : Type u} [Fintype ι'] (t' : ι' → Finset α),
Fintype.card ι' ≤ n →
(∀ s' : Finset ι', s'.card ≤ (s'.biUnion t').card) →
∃ f : ι' → α, Function.Injective f ∧ ∀ x, f x ∈ t' x)
(s : Finset ι) (hs : s.Nonempty) (hns : s ≠ univ) (hus : s.card = (s.biUnion t).card) :
∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by
haveI := Classical.decEq ι
-- Restrict to `s`
rw [Nat.add_one] at hn
have card_ι'_le : Fintype.card s ≤ n := by
apply Nat.le_of_lt_succ
calc
Fintype.card s = s.card := Fintype.card_coe _
_ < Fintype.card ι := (card_lt_iff_ne_univ _).mpr hns
_ = n.succ := hn
let t' : s → Finset α := fun x' => t x'
rcases ih t' card_ι'_le (hall_cond_of_restrict ht) with ⟨f', hf', hsf'⟩
-- Restrict to `sᶜ` in the domain and `(s.biUnion t)ᶜ` in the codomain.
set ι'' := (s : Set ι)ᶜ
let t'' : ι'' → Finset α := fun a'' => t a'' \ s.biUnion t
have card_ι''_le : Fintype.card ι'' ≤ n := by
simp_rw [ι'', ← Nat.lt_succ_iff, ← hn, ← Finset.coe_compl, coe_sort_coe]
rwa [Fintype.card_coe, card_compl_lt_iff_nonempty]
rcases ih t'' card_ι''_le (hall_cond_of_compl hus ht) with ⟨f'', hf'', hsf''⟩
-- Put them together
have f'_mem_biUnion : ∀ (x') (hx' : x' ∈ s), f' ⟨x', hx'⟩ ∈ s.biUnion t := by
intro x' hx'
rw [mem_biUnion]
exact ⟨x', hx', hsf' _⟩
have f''_not_mem_biUnion : ∀ (x'') (hx'' : ¬x'' ∈ s), ¬f'' ⟨x'', hx''⟩ ∈ s.biUnion t := by
intro x'' hx''
have h := hsf'' ⟨x'', hx''⟩
rw [mem_sdiff] at h
exact h.2
have im_disj :
∀ (x' x'' : ι) (hx' : x' ∈ s) (hx'' : ¬x'' ∈ s), f' ⟨x', hx'⟩ ≠ f'' ⟨x'', hx''⟩ := by
intro x x' hx' hx'' h
apply f''_not_mem_biUnion x' hx''
rw [← h]
apply f'_mem_biUnion x
refine ⟨fun x => if h : x ∈ s then f' ⟨x, h⟩ else f'' ⟨x, h⟩, ?_, ?_⟩
· refine hf'.dite _ hf'' (@fun x x' => im_disj x x' _ _)
· intro x
simp only [of_eq_true]
split_ifs with h
· exact hsf' ⟨x, h⟩
· exact sdiff_subset (hsf'' ⟨x, h⟩)
set_option linter.uppercaseLean3 false in
#align hall_marriage_theorem.hall_hard_inductive_step_B HallMarriageTheorem.hall_hard_inductive_step_B
end Fintype
variable [Finite ι]
/-- Here we combine the two inductive steps into a full strong induction proof,
completing the proof the harder direction of **Hall's Marriage Theorem**.
-/
theorem hall_hard_inductive (ht : ∀ s : Finset ι, s.card ≤ (s.biUnion t).card) :
∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by
cases nonempty_fintype ι
induction' hn : Fintype.card ι using Nat.strong_induction_on with n ih generalizing ι
rcases n with (_ | n)
· rw [Fintype.card_eq_zero_iff] at hn
exact ⟨isEmptyElim, isEmptyElim, isEmptyElim⟩
· have ih' : ∀ (ι' : Type u) [Fintype ι'] (t' : ι' → Finset α), Fintype.card ι' ≤ n →
(∀ s' : Finset ι', s'.card ≤ (s'.biUnion t').card) →
∃ f : ι' → α, Function.Injective f ∧ ∀ x, f x ∈ t' x := by
intro ι' _ _ hι' ht'
exact ih _ (Nat.lt_succ_of_le hι') ht' _ rfl
by_cases h : ∀ s : Finset ι, s.Nonempty → s ≠ univ → s.card < (s.biUnion t).card
· refine hall_hard_inductive_step_A hn ht (@fun ι' => ih' ι') h
· push_neg at h
rcases h with ⟨s, sne, snu, sle⟩
exact hall_hard_inductive_step_B hn ht (@fun ι' => ih' ι')
s sne snu (Nat.le_antisymm (ht _) sle)
#align hall_marriage_theorem.hall_hard_inductive HallMarriageTheorem.hall_hard_inductive
end HallMarriageTheorem
/-- This is the version of **Hall's Marriage Theorem** in terms of indexed
families of finite sets `t : ι → Finset α` with `ι` finite.
It states that there is a set of distinct representatives if and only
if every union of `k` of the sets has at least `k` elements.
See `Finset.all_card_le_biUnion_card_iff_exists_injective` for a version
where the `Finite ι` constraint is removed.
-/
theorem Finset.all_card_le_biUnion_card_iff_existsInjective' {ι α : Type*} [Finite ι]
[DecidableEq α] (t : ι → Finset α) :
(∀ s : Finset ι, s.card ≤ (s.biUnion t).card) ↔
∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by
constructor
· exact HallMarriageTheorem.hall_hard_inductive
· rintro ⟨f, hf₁, hf₂⟩ s
rw [← card_image_of_injective s hf₁]
apply card_le_card
intro
rw [mem_image, mem_biUnion]
rintro ⟨x, hx, rfl⟩
exact ⟨x, hx, hf₂ x⟩
#align finset.all_card_le_bUnion_card_iff_exists_injective' Finset.all_card_le_biUnion_card_iff_existsInjective'