Skip to content

Commit 8fd5b31

Browse files
committed
Small tripling implies approximate subgroup
1 parent 24bb4c4 commit 8fd5b31

File tree

9 files changed

+363
-31
lines changed

9 files changed

+363
-31
lines changed

LeanCamCombi.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import LeanCamCombi.Mathlib.Analysis.Convex.Exposed
3131
import LeanCamCombi.Mathlib.Analysis.Convex.Extreme
3232
import LeanCamCombi.Mathlib.Analysis.Convex.Independence
3333
import LeanCamCombi.Mathlib.Analysis.Convex.SimplicialComplex.Basic
34+
import LeanCamCombi.Mathlib.Combinatorics.Additive.RuzsaCovering
35+
import LeanCamCombi.Mathlib.Combinatorics.Additive.SmallTripling
3436
import LeanCamCombi.Mathlib.Combinatorics.Schnirelmann
3537
import LeanCamCombi.Mathlib.Combinatorics.SimpleGraph.Basic
3638
import LeanCamCombi.Mathlib.Combinatorics.SimpleGraph.Containment

LeanCamCombi/GrowthInGroups/ApproximateSubgroup.lean

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import Mathlib.Algebra.BigOperators.Ring
2-
import Mathlib.Algebra.Group.Pointwise.Finset.Basic
31
import Mathlib.Algebra.Order.BigOperators.Ring.Finset
4-
import Mathlib.Combinatorics.Additive.RuzsaCovering
5-
import Mathlib.Data.Fintype.BigOperators
6-
import Mathlib.Data.Real.Basic
2+
import LeanCamCombi.Mathlib.Algebra.Group.Pointwise.Finset.Basic
73
import LeanCamCombi.Mathlib.Algebra.Group.Pointwise.Set.Basic
4+
import LeanCamCombi.Mathlib.Combinatorics.Additive.RuzsaCovering
5+
import LeanCamCombi.Mathlib.Combinatorics.Additive.SmallTripling
6+
import LeanCamCombi.Mathlib.Data.Finset.Basic
87

98
open scoped Finset Pointwise
109

11-
1210
variable {G : Type*} [Group G] {S : Set G} {K L : ℝ} {n : ℕ}
1311

1412
structure IsApproximateAddSubgroup {G : Type*} [AddGroup G] (S : Set G) (K : ℝ) : Prop where
@@ -65,14 +63,18 @@ lemma pi {ι : Type*} {G : ι → Type*} [Fintype ι] [∀ i, Group (G i)] {S :
6563
_ ≤ ∏ i, K i := by gcongr; exact hF _
6664
· sorry
6765

66+
open Finset in
6867
@[to_additive]
69-
lemma of_small_tripling [DecidableEq G] {s : Finset G} (hs₀ : s.Nonempty) (hsymm : s⁻¹ = s)
70-
(hs : #(s ^ 3) ≤ K * #s) : IsApproximateSubgroup (s ^ 2 : Set G) (K ^ 2) where
71-
nonempty := hs₀.to_set.pow
72-
inv_eq_self := by simp [← inv_pow, hsymm, ← Finset.coe_inv]
68+
lemma of_small_tripling [DecidableEq G] {A : Finset G} (hA₀ : A.Nonempty) (hAsymm : A⁻¹ = A)
69+
(hA : #(A ^ 3) ≤ K * #A) : IsApproximateSubgroup (A ^ 2 : Set G) (K ^ 3) where
70+
nonempty := hA₀.to_set.pow
71+
inv_eq_self := by simp [← inv_pow, hAsymm, ← coe_inv]
7372
exists_sq_subset_mul := by
74-
sorry
75-
76-
73+
replace hA := calc (#(A ^ 4 * A) : ℝ)
74+
_ = #(A ^ 5) := by rw [← pow_succ]
75+
_ ≤ K ^ 3 * #A := small_pow_of_small_tripling' (by omega) hA hAsymm
76+
obtain ⟨F, -, hF, hAF⟩ := ruzsa_covering_mul hA₀ hA
77+
have hF₀ : F.Nonempty := nonempty_iff_ne_empty.2 <| by rintro rfl; simp [hA₀.ne_empty] at hAF
78+
exact ⟨F, hF, by norm_cast; simpa [div_eq_mul_inv, pow_succ, mul_assoc, hAsymm] using hAF⟩
7779

7880
end IsApproximateSubgroup

LeanCamCombi/GrowthInGroups/Lecture2.lean

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Mathlib.Combinatorics.Additive.SmallTripling
21
import LeanCamCombi.Mathlib.Data.Set.Pointwise.Interval
32
import LeanCamCombi.GrowthInGroups.ApproximateSubgroup
43

@@ -34,10 +33,10 @@ lemma lemma_4_3_1 (hA : #(A ^ 2) ≤ K * #A) : #(A * A⁻¹) ≤ K ^ 2 * #A := b
3433

3534
lemma lemma_4_4_1 (hm : 3 ≤ m) (hA : #(A ^ 3) ≤ K * #A) (ε : Fin m → ℤ) (hε : ∀ i, |ε i| = 1) :
3635
#((finRange m).map fun i ↦ A ^ ε i).prod ≤ K ^ (3 * (m - 2)) * #A :=
37-
small_alternating_pow_of_small_tripling hm hA ε hε
36+
small_alternating_pow_of_small_tripling' hm hA ε hε
3837

3938
lemma lemma_4_4_2 (hm : 3 ≤ m) (hA : #(A ^ 3) ≤ K * #A) (hAsymm : A⁻¹ = A) :
40-
#(A ^ m) ≤ K ^ (m - 2) * #A := small_pow_of_small_tripling hm hA hAsymm
39+
#(A ^ m) ≤ K ^ (m - 2) * #A := small_pow_of_small_tripling' hm hA hAsymm
4140

4241
def def_4_5 (S : Set G) (K : ℝ) : Prop := IsApproximateSubgroup S K
4342

@@ -63,11 +62,9 @@ lemma remark_4_6_3 : IsApproximateAddSubgroup (.Icc (-1) 1 : Set ℝ) 2 where
6362
exists_two_nsmul_subset_add := ⟨{-1, 1}, mod_cast card_le_two, by simp [two_nsmul_Icc_real]⟩
6463

6564
lemma lemma_4_7 {A : Finset G} (hA₀ : A.Nonempty) (hsymm : A⁻¹ = A) (hA : #(A ^ 3) ≤ K * #A) :
66-
IsApproximateSubgroup (A ^ 2 : Set G) (K ^ 2) := .of_small_tripling hA₀ hsymm hA
65+
IsApproximateSubgroup (A ^ 2 : Set G) (K ^ 3) := .of_small_tripling hA₀ hsymm hA
6766

68-
-- TODO: Generalise Ruzsa covering to non-abelian groups
69-
lemma lemma_4_8 {A B : Finset G} (hK : #(A * B) ≤ K * #B) : ∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * (B / B) := by
70-
sorry
71-
-- obtain ⟨F, hF⟩ := Finset.exists_subset_mul_div A _
67+
lemma lemma_4_8 {A B : Finset G} (hB : B.Nonempty) (hK : #(A * B) ≤ K * #B) :
68+
∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * B / B := ruzsa_covering_mul hB hK
7269

7370
end GrowthInGroups.Lecture2

LeanCamCombi/GrowthInGroups/Lecture3.lean

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ open scoped Pointwise
77
namespace GrowthInGroups.Lecture3
88
variable {G : Type*} [DecidableEq G] [Group G] {A : Finset G} {k K : ℝ} {m : ℕ}
99

10-
lemma lemma_5_1 {A : Finset G} (hA₀ : A.Nonempty) (hsymm : A⁻¹ = A) (hA : #(A ^ 3) ≤ K * #A) :
11-
IsApproximateSubgroup (A ^ 2 : Set G) (K ^ 2) := .of_small_tripling hA₀ hsymm hA
10+
lemma lemma_5_1 {A : Finset G} (hA₀ : A.Nonempty) (hAsymm : A⁻¹ = A) (hA : #(A ^ 3) ≤ K * #A) :
11+
IsApproximateSubgroup (A ^ 2 : Set G) (K ^ 3) := .of_small_tripling hA₀ hAsymm hA
1212

13-
-- TODO: Generalise Ruzsa covering to non-abelian groups
14-
lemma lemma_5_2 {A B : Finset G} (hK : #(A * B) ≤ K * #B) : ∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * (B / B) := by
15-
sorry
16-
-- obtain ⟨F, hF⟩ := Finset.exists_subset_mul_div A _
13+
lemma lemma_5_2 {A B : Finset G} (hB : B.Nonempty) (hK : #(A * B) ≤ K * #B) :
14+
∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * B / B := ruzsa_covering_mul hB hK
1715

1816
end GrowthInGroups.Lecture3

LeanCamCombi/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ attribute [gcongr] mul_subset_mul_left mul_subset_mul_right div_subset_div_left
1212
end Finset
1313

1414
namespace Finset
15-
variable {α : Type*} [DecidableEq α] [Monoid α] {s t : Finset α}
15+
variable {α : Type*} [DecidableEq α]
16+
17+
section Monoid
18+
variable [Monoid α] {s t : Finset α} {n : ℕ}
1619

1720
attribute [simp] one_nonempty
1821

@@ -21,6 +24,20 @@ lemma Nonempty.pow (hs : s.Nonempty) : ∀ {n}, (s ^ n).Nonempty
2124
| 0 => by simp
2225
| n + 1 => by rw [pow_succ]; exact hs.pow.mul hs
2326

27+
set_option push_neg.use_distrib true in
28+
@[to_additive (attr := simp)] lemma pow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
29+
constructor
30+
· contrapose!
31+
rintro (hs | rfl)
32+
-- TODO: The `nonempty_iff_ne_empty` would be unnecessary if `push_neg` knew how to simplify
33+
-- `s ≠ ∅` to `s.Nonempty` when `s : Finset α`.
34+
-- See https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/push_neg.20extensibility
35+
· exact nonempty_iff_ne_empty.1 (nonempty_iff_ne_empty.2 hs).pow
36+
· rw [← nonempty_iff_ne_empty]
37+
simp
38+
· rintro ⟨rfl, hn⟩
39+
exact empty_pow hn
40+
2441
@[to_additive]
2542
lemma pow_subset_pow_mul_of_sq_subset_mul (hst : s ^ 2 ⊆ t * s) :
2643
∀ {n}, 1 < n → s ^ n ⊆ t ^ (n - 1) * s
@@ -33,4 +50,26 @@ lemma pow_subset_pow_mul_of_sq_subset_mul (hst : s ^ 2 ⊆ t * s) :
3350
_ ⊆ t ^ (n + 1) * (t * s) := by gcongr
3451
_ = t ^ (n + 2) * s := by rw [← mul_assoc, ← pow_succ]
3552

53+
end Monoid
54+
55+
section DivisionMonoid
56+
variable [DivisionMonoid α] {s t : Finset α} {n : ℤ}
57+
58+
@[to_additive]
59+
lemma Nonempty.zpow (hs : s.Nonempty) : ∀ {n : ℤ}, (s ^ n).Nonempty
60+
| (n : ℕ) => hs.pow
61+
| .negSucc n => by simpa using hs.pow
62+
63+
set_option push_neg.use_distrib true in
64+
@[to_additive (attr := simp)] lemma zpow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
65+
constructor
66+
· contrapose!
67+
rintro (hs | rfl)
68+
· exact nonempty_iff_ne_empty.1 (nonempty_iff_ne_empty.2 hs).zpow
69+
· rw [← nonempty_iff_ne_empty]
70+
simp
71+
· rintro ⟨rfl, hn⟩
72+
exact empty_zpow hn
73+
74+
end DivisionMonoid
3675
end Finset

LeanCamCombi/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import Mathlib.Algebra.Group.Pointwise.Set.Basic
33
open scoped Pointwise
44

55
namespace Set
6-
variable {α : Type*} [Monoid α] {s t : Set α}
6+
variable {α : Type*}
7+
8+
section Monoid
9+
variable [Monoid α] {s t : Set α} {n : ℕ}
710

811
attribute [simp] one_nonempty
912

@@ -12,6 +15,16 @@ lemma Nonempty.pow (hs : s.Nonempty) : ∀ {n}, (s ^ n).Nonempty
1215
| 0 => by simp
1316
| n + 1 => by rw [pow_succ]; exact hs.pow.mul hs
1417

18+
set_option push_neg.use_distrib true in
19+
@[to_additive (attr := simp)] lemma pow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
20+
constructor
21+
· contrapose!
22+
rintro (hs | rfl)
23+
· exact hs.pow
24+
· simp
25+
· rintro ⟨rfl, hn⟩
26+
exact empty_pow hn
27+
1528
@[to_additive]
1629
lemma pow_subset_pow_mul_of_sq_subset_mul (hst : s ^ 2 ⊆ t * s) :
1730
∀ {n}, 1 < n → s ^ n ⊆ t ^ (n - 1) * s
@@ -24,6 +37,27 @@ lemma pow_subset_pow_mul_of_sq_subset_mul (hst : s ^ 2 ⊆ t * s) :
2437
_ ⊆ t ^ (n + 1) * (t * s) := by gcongr
2538
_ = t ^ (n + 2) * s := by rw [← mul_assoc, ← pow_succ]
2639

40+
end Monoid
41+
42+
section DivisionMonoid
43+
variable [DivisionMonoid α] {s t : Set α} {n : ℤ}
44+
45+
@[to_additive]
46+
lemma Nonempty.zpow (hs : s.Nonempty) : ∀ {n : ℤ}, (s ^ n).Nonempty
47+
| (n : ℕ) => hs.pow
48+
| .negSucc n => by simpa using hs.pow
49+
50+
set_option push_neg.use_distrib true in
51+
@[to_additive (attr := simp)] lemma zpow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
52+
constructor
53+
· contrapose!
54+
rintro (hs | rfl)
55+
· exact hs.zpow
56+
· simp
57+
· rintro ⟨rfl, hn⟩
58+
exact empty_zpow hn
59+
60+
end DivisionMonoid
2761
end Set
2862

2963
namespace Set
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/-
2+
Copyright (c) 2022 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.Real.Basic
7+
import Mathlib.SetTheory.Cardinal.Finite
8+
import Mathlib.Tactic.Positivity.Finset
9+
import LeanCamCombi.Mathlib.Algebra.Group.Pointwise.Finset.Basic
10+
11+
/-!
12+
# Ruzsa's covering lemma
13+
14+
This file proves the Ruzsa covering lemma. This says that, for `A`, `B` finsets, we can cover `A`
15+
with at most `#(A + B) / #B` copies of `B - B`.
16+
-/
17+
18+
open scoped Pointwise
19+
20+
variable {G : Type*} [Group G] {K : ℝ}
21+
22+
namespace Finset
23+
variable [DecidableEq G] {A B : Finset G}
24+
25+
/-- **Ruzsa's covering lemma**. -/
26+
@[to_additive "**Ruzsa's covering lemma**"]
27+
theorem ruzsa_covering_mul (hB : B.Nonempty) (hK : #(A * B) ≤ K * #B) :
28+
∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * B / B := by
29+
haveI : ∀ F, Decidable ((F : Set G).PairwiseDisjoint (· • B)) := fun F ↦ Classical.dec _
30+
set C := {F ∈ A.powerset | F.toSet.PairwiseDisjoint (· • B)}
31+
obtain ⟨F, hF, hFmax⟩ := C.exists_maximal <| filter_nonempty_iff.2
32+
⟨∅, empty_mem_powerset _, by rw [coe_empty]; exact Set.pairwiseDisjoint_empty⟩
33+
rw [mem_filter, mem_powerset] at hF
34+
obtain ⟨hFA, hF⟩ := hF
35+
refine ⟨F, hFA, le_of_mul_le_mul_right ?_ (by positivity : (0 : ℝ) < #B), fun a ha ↦ ?_⟩
36+
· calc
37+
(#F * #B : ℝ) = #(F * B) := by
38+
rw [card_mul_iff.2 <| pairwiseDisjoint_smul_iff.1 hF, Nat.cast_mul]
39+
_ ≤ #(A * B) := by gcongr
40+
_ ≤ K * #B := hK
41+
rw [mul_div_assoc]
42+
by_cases hau : a ∈ F
43+
· exact subset_mul_left _ hB.one_mem_div hau
44+
by_cases H : ∀ b ∈ F, Disjoint (a • B) (b • B)
45+
· refine (hFmax _ ?_ <| ssubset_insert hau).elim
46+
rw [mem_filter, mem_powerset, insert_subset_iff, coe_insert]
47+
exact ⟨⟨ha, hFA⟩, hF.insert fun _ hb _ ↦ H _ hb⟩
48+
push_neg at H
49+
simp_rw [not_disjoint_iff, ← inv_smul_mem_iff] at H
50+
obtain ⟨b, hb, c, hc₁, hc₂⟩ := H
51+
exact mem_mul.2 ⟨b, hb, b⁻¹ * a, mem_div.2 ⟨_, hc₂, _, hc₁, by simp⟩, by simp⟩
52+
53+
end Finset
54+
55+
namespace Set
56+
variable {A B : Set G}
57+
58+
/-- **Ruzsa's covering lemma** for sets. See also `Finset.exists_subset_mul_div`. -/
59+
@[to_additive "**Ruzsa's covering lemma** for sets. See also `Finset.exists_subset_add_sub`"]
60+
lemma ruzsa_covering_mul (hA : A.Finite) (hB : B.Finite) (hB₀ : B.Nonempty)
61+
(hK : Nat.card (A * B) ≤ K * Nat.card B) :
62+
∃ F ⊆ A, Nat.card F ≤ K ∧ A ⊆ F * B / B ∧ F.Finite := by
63+
lift A to Finset G using hA
64+
lift B to Finset G using hB
65+
classical
66+
obtain ⟨F, hFA, hF, hAF⟩ := Finset.ruzsa_covering_mul hB₀ (by simpa [← Finset.coe_mul] using hK)
67+
exact ⟨F, by norm_cast; simp [*]⟩
68+
69+
end Set

0 commit comments

Comments
 (0)