Skip to content

Commit da0f82e

Browse files
ctchouYaelDillies
andauthored
PlainCombi: LYM inequality using the Katona circle method (#42)
Co-authored-by: Yaël Dillies <[email protected]>
1 parent d140052 commit da0f82e

File tree

7 files changed

+254
-0
lines changed

7 files changed

+254
-0
lines changed

LeanCamCombi.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ import LeanCamCombi.GrowthInGroups.Lecture1
1010
import LeanCamCombi.GrowthInGroups.Lecture2
1111
import LeanCamCombi.GrowthInGroups.Lecture3
1212
import LeanCamCombi.GrowthInGroups.Lecture4
13+
import LeanCamCombi.Mathlib.Algebra.BigOperators.Field
1314
import LeanCamCombi.Mathlib.Combinatorics.Additive.ApproximateSubgroup
15+
import LeanCamCombi.Mathlib.Combinatorics.SetFamily.LYM
1416
import LeanCamCombi.Mathlib.Combinatorics.SimpleGraph.Density
1517
import LeanCamCombi.Mathlib.Combinatorics.SimpleGraph.Subgraph
18+
import LeanCamCombi.Mathlib.Data.Fintype.Card
19+
import LeanCamCombi.Mathlib.Data.Nat.Choose.Cast
1620
import LeanCamCombi.Mathlib.Probability.ProbabilityMassFunction.Constructions
21+
import LeanCamCombi.PlainCombi.KatonaCircle
1722
import LeanCamCombi.PlainCombi.LittlewoodOfford
1823
import LeanCamCombi.PlainCombi.OrderShatter
24+
import LeanCamCombi.PlainCombi.ProbLYM
1925
import LeanCamCombi.PlainCombi.VanDenBergKesten
2026
import LeanCamCombi.StableCombi.AddSet
2127
import LeanCamCombi.StableCombi.Formula
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Mathlib.Algebra.BigOperators.Field
2+
import Mathlib.Data.Finset.Density
3+
4+
namespace Finset
5+
variable {α β : Type*} [Fintype β]
6+
7+
@[simp]
8+
lemma dens_disjiUnion (s : Finset α) (t : α → Finset β) (h) :
9+
(s.disjiUnion t h).dens = ∑ a ∈ s, (t a).dens := by simp [dens, sum_div]
10+
11+
variable {s : Finset α} {t : α → Finset β}
12+
13+
lemma dens_biUnion [DecidableEq β] (h : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → Disjoint (t x) (t y)) :
14+
(s.biUnion t).dens = ∑ u ∈ s, (t u).dens := by
15+
simp [dens, card_biUnion h, sum_div]
16+
17+
lemma dens_biUnion_le [DecidableEq β] : (s.biUnion t).dens ≤ ∑ a ∈ s, (t a).dens := by
18+
simp [dens, ← sum_div]; gcongr; positivity; norm_cast; exact card_biUnion_le
19+
20+
lemma dens_eq_sum_dens_fiberwise [DecidableEq α] {f : β → α} {t : Finset β} (h : ∀ x ∈ t, f x ∈ s) :
21+
t.dens = ∑ a ∈ s, {b ∈ t | f b = a}.dens := by
22+
simp [dens, ← sum_div, card_eq_sum_card_fiberwise h]
23+
24+
lemma dens_eq_sum_dens_image [DecidableEq α] (f : β → α) (t : Finset β) :
25+
t.dens = ∑ a ∈ t.image f, {b ∈ t | f b = a}.dens :=
26+
dens_eq_sum_dens_fiberwise fun _ ↦ mem_image_of_mem _
27+
28+
end Finset
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Mathlib.Combinatorics.SetFamily.LYM
2+
3+
/-!
4+
# TODO
5+
6+
* Use semantic naming convention instead of symbol-reading
7+
* Add the `∑ s ∈ 𝒜, ((card α).choose #s)⁻¹ ≤ 1` variant
8+
-/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Mathlib.Data.Fintype.Card
2+
3+
namespace Fintype
4+
variable {α : Type*} {p : α → Prop}
5+
6+
-- TODO: Replace `card_subtype_le`
7+
lemma card_subtype_le' [Fintype α] [Fintype {a // p a}] : card {a // p a} ≤ card α := by
8+
classical convert card_subtype_le _; infer_instance
9+
10+
end Fintype
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/-
2+
Copyright (c) 2021 Yaël Dillies. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yaël Dillies
5+
-/
6+
import Mathlib.Data.Nat.Choose.Basic
7+
import Mathlib.Data.Nat.Factorial.Cast
8+
9+
/-!
10+
# TODO
11+
12+
Replace
13+
-/
14+
15+
16+
open Nat
17+
18+
variable (K : Type*) [DivisionSemiring K] [CharZero K]
19+
20+
namespace Nat
21+
22+
theorem cast_choose' {a b : ℕ} (h : a ≤ b) : (b.choose a : K) = b ! / (a ! * (b - a)!) := by
23+
have : ∀ {n : ℕ}, (n ! : K) ≠ 0 := Nat.cast_ne_zero.2 (factorial_ne_zero _)
24+
rw [eq_div_iff_mul_eq (mul_ne_zero this this)]
25+
rw_mod_cast [← mul_assoc, choose_mul_factorial_mul_factorial h]
26+
27+
theorem cast_add_choose' {a b : ℕ} : ((a + b).choose a : K) = (a + b)! / (a ! * b !) := by
28+
rw [cast_choose' K (_root_.le_add_right le_rfl), add_tsub_cancel_left]
29+
30+
theorem cast_choose_eq_ascPochhammer_div' (a b : ℕ) :
31+
(a.choose b : K) = (ascPochhammer K b).eval ↑(a - (b - 1)) / b ! := by
32+
rw [eq_div_iff_mul_eq (cast_ne_zero.2 b.factorial_ne_zero : (b ! : K) ≠ 0), ← cast_mul,
33+
mul_comm, ← descFactorial_eq_factorial_mul_choose, ← cast_descFactorial]
34+
35+
end Nat
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/-
2+
Copyright (c) 2024 Ching-Tsun Chou, Chris Wong. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Ching-Tsun Chou, Chris Wong
5+
-/
6+
import LeanCamCombi.Mathlib.Data.Fintype.Card
7+
import LeanCamCombi.Mathlib.Data.Nat.Choose.Cast
8+
import Mathlib.Data.Finset.Density
9+
import Mathlib.Data.Fintype.Prod
10+
import Mathlib.Data.Fintype.Perm
11+
12+
/-!
13+
# The Katona circle method
14+
15+
This file provides tooling to use the Katona circle method, which is double-counting ways to order
16+
`n` elements on a circle under some condition.
17+
-/
18+
19+
open Fintype Finset Nat
20+
21+
variable {α : Type*} [Fintype α]
22+
23+
variable (α) in
24+
/-- A numbering of a fintype `α` is a bijection between `α` and `Fin (card α)`. -/
25+
abbrev Numbering : Type _ := α ≃ Fin (card α)
26+
27+
@[simp] lemma Fintype.card_numbering [DecidableEq α] : card (Numbering α) = (card α)! :=
28+
card_equiv (equivFin _)
29+
30+
namespace Numbering
31+
variable {f : Numbering α} {s t : Finset α}
32+
33+
/-- `IsPrefix f s` means that the elements of `s` precede the elements of `sᶜ`
34+
in the numbering `f`. -/
35+
def IsPrefix (f : Numbering α) (s : Finset α) := ∀ x, x ∈ s ↔ f x < #s
36+
37+
lemma IsPrefix.subset_of_card_le_card (hs : IsPrefix f s) (ht : IsPrefix f t) (hst : #s ≤ #t) :
38+
s ⊆ t := fun a ha ↦ (ht a).mpr <| ((hs a).mp ha).trans_le hst
39+
40+
variable [DecidableEq α]
41+
42+
instance : Decidable (IsPrefix f s) := by unfold IsPrefix; infer_instance
43+
44+
/-- The set of numberings of which `s` is a prefix. -/
45+
def prefixed (s : Finset α) : Finset (Numbering α) := {f | IsPrefix f s}
46+
47+
@[simp] lemma mem_prefixed : f ∈ prefixed s ↔ IsPrefix f s := by simp [prefixed]
48+
49+
/-- Decompose a numbering of which `s` is a prefix into a numbering of `s` and a numbering on `sᶜ`.
50+
-/
51+
def prefixedEquiv (s : Finset α) : prefixed s ≃ Numbering s × Numbering ↑(sᶜ) where
52+
toFun f :=
53+
{ fst.toFun x := ⟨f.1 x, by simp [← mem_prefixed.1 f.2 x]⟩
54+
fst.invFun n :=
55+
⟨f.1.symm ⟨n, n.2.trans_le <| by simpa using s.card_le_univ⟩, by
56+
rw [mem_prefixed.1 f.2]; simpa using n.2
57+
fst.left_inv x := by simp
58+
fst.right_inv n := by simp
59+
snd.toFun x := ⟨f.1 x - #s, by
60+
have := (mem_prefixed.1 f.2 x).not.1 (Finset.mem_compl.1 x.2)
61+
simp at this ⊢
62+
omega⟩
63+
snd.invFun n :=
64+
⟨f.1.symm ⟨n + #s, Nat.add_lt_of_lt_sub <| by simpa using n.2⟩, by
65+
rw [s.mem_compl, mem_prefixed.1 f.2]; simp⟩
66+
snd.left_inv := by
67+
rintro ⟨x, hx⟩
68+
rw [s.mem_compl, mem_prefixed.1 f.2, not_lt] at hx
69+
simp [Nat.sub_add_cancel hx]
70+
snd.right_inv := by rintro ⟨n, hn⟩; simp }
71+
invFun := fun (g, g') ↦
72+
{ val.toFun x :=
73+
if hx : x ∈ s then
74+
g ⟨x, hx⟩ |>.castLE Fintype.card_subtype_le'
75+
else
76+
g' ⟨x, by simpa⟩ |>.addNat #s |>.cast (by simp [card_le_univ])
77+
val.invFun n :=
78+
if hn : n < #s then
79+
g.symm ⟨n, by simpa using hn⟩
80+
else
81+
g'.symm ⟨n - #s, by simp; omega⟩
82+
val.left_inv x := by
83+
by_cases hx : x ∈ s
84+
· have : g ⟨x, hx⟩ < #s := by simpa using (g ⟨x, hx⟩).2
85+
simp [hx, this]
86+
· simp [hx, Equiv.symm_apply_eq]
87+
val.right_inv n := by
88+
obtain hns | hsn := lt_or_le n.1 #s
89+
· simp [hns]
90+
· simp [hsn.not_lt, hsn, dif_neg (mem_compl.1 <| Subtype.prop _), Fin.ext_iff,
91+
Fintype.card_subtype_le']
92+
property := mem_prefixed.2 fun x ↦ by
93+
constructor
94+
· intro hx
95+
simpa [hx, -Fin.is_lt] using (g _).is_lt
96+
· by_cases hx : x ∈ s <;> simp [hx] }
97+
left_inv f := by
98+
ext x
99+
by_cases hx : x ∈ s
100+
· simp [hx]
101+
· rw [mem_prefixed.1 f.2, not_lt] at hx
102+
simp [hx]
103+
right_inv g := by simp +contextual [Prod.ext_iff, DFunLike.ext_iff]
104+
105+
lemma card_prefixed (s : Finset α) : #(prefixed s) = (#s)! * (card α - #s)! := by
106+
simpa [-mem_prefixed] using Fintype.card_congr (prefixedEquiv s)
107+
108+
@[simp]
109+
lemma dens_prefixed (s : Finset α) : (prefixed s).dens = ((card α).choose #s : ℚ≥0)⁻¹ := by
110+
simp [dens, card_prefixed, Nat.cast_choose' _ s.card_le_univ]
111+
112+
-- TODO: This can be strengthened to an iff
113+
lemma disjoint_prefixed_prefixed (hst : ¬ s ⊆ t) (hts : ¬ t ⊆ s) :
114+
Disjoint (prefixed s) (prefixed t) := by
115+
simp only [Finset.disjoint_left, mem_prefixed]
116+
intro f hs ht
117+
obtain hst' | hts' := Nat.le_total #s #t
118+
· exact hst <| hs.subset_of_card_le_card ht hst'
119+
· exact hts <| ht.subset_of_card_le_card hs hts'
120+
121+
end Numbering
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/-
2+
Copyright (c) 2024 Ching-Tsun Chou, Chris Wong. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Ching-Tsun Chou, Chris Wong
5+
-/
6+
import LeanCamCombi.Mathlib.Algebra.BigOperators.Field
7+
import LeanCamCombi.PlainCombi.KatonaCircle
8+
9+
/-!
10+
# The LYM inequality using probability theory
11+
12+
This file proves the LYM inequality using (very elementary) probability theory.
13+
14+
15+
16+
## References
17+
18+
This proof formalizes Section 1.2 of Prof. Yufei Zhao's lecture notes for MIT 18.226:
19+
20+
<https://yufeizhao.com/pm/probmethod_notes.pdf>
21+
22+
A video of Prof. Zhao's lecture is available on YouTube:
23+
24+
<https://youtu.be/exBXHYl4po8>
25+
26+
The proof of Theorem 1.10, Lecture 3 in the Cambridge lecture notes on combinatorics:
27+
28+
<https://github.com/YaelDillies/maths-notes/blob/master/combinatorics.pdf>
29+
30+
is basically the same proof, except without using probability theory.
31+
-/
32+
33+
open Finset Fintype Numbering
34+
35+
variable {α : Type*} [Fintype α] {𝒜 : Finset (Finset α)}
36+
37+
/-- The **Lubell-Yamamoto-Meshalkin inequality**, proved using the Katona circle method. -/
38+
theorem LYM_inequality (h𝒜 : IsAntichain (· ⊆ ·) 𝒜.toSet) :
39+
∑ s ∈ 𝒜, ((card α).choose #s : ℚ≥0)⁻¹ ≤ 1 := by
40+
classical
41+
calc
42+
_ = ∑ s ∈ 𝒜, (prefixed s).dens := by simp
43+
_ = (𝒜.biUnion prefixed).dens := by
44+
rw [dens_biUnion]
45+
exact fun s hs t ht hst ↦ disjoint_prefixed_prefixed (h𝒜 hs ht hst) (h𝒜 ht hs hst.symm)
46+
_ ≤ 1 := dens_le_one

0 commit comments

Comments
 (0)