Skip to content

Commit 72b9c8d

Browse files
feat(Combinatorics/SimpleGraph): more API for Turán density (leanprover-community#29449)
Refactors `tendsto_turanDensity` and implements `turanDensity_eq_sInf` and `isContained_of_card_edgeFinset` (theorems that are common in proofs involving Turán density).
1 parent e5686e7 commit 72b9c8d

1 file changed

Lines changed: 76 additions & 16 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ public import Mathlib.Combinatorics.Enumerative.DoubleCounting
1010
public import Mathlib.Combinatorics.SimpleGraph.DeleteEdges
1111
public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic
1212
public import Mathlib.Data.Nat.Choose.Cast
13+
1314
import Mathlib.Tactic.Bound
1415
import Mathlib.Topology.Algebra.InfiniteSum.Order
16+
import Mathlib.Topology.Instances.Real.Lemmas
1517

1618
/-!
1719
# Turán density
@@ -27,6 +29,9 @@ This file defines the **Turán density** of a simple graph.
2729
2830
* `SimpleGraph.isEquivalent_extremalNumber` is the proof that `extremalNumber n H` is
2931
asymptotically equivalent to `turanDensity H * n.choose 2` as `n` approaches `∞`.
32+
33+
* `SimpleGraph.isContained_of_card_edgeFinset`: simple graphs on `n` vertices with at least
34+
`(turanDensity H + o(1)) * n ^ 2` edges contain `H`, for all sufficently large `n`.
3035
-/
3136

3237
@[expose] public section
@@ -36,7 +41,7 @@ open Asymptotics Filter Finset Fintype Topology
3641

3742
namespace SimpleGraph
3843

39-
variable {V W : Type*} {G : SimpleGraph V} {H : SimpleGraph W}
44+
variable {W : Type*}
4045

4146
lemma antitoneOn_extremalNumber_div_choose_two (H : SimpleGraph W) :
4247
AntitoneOn (fun n ↦ (extremalNumber n H / n.choose 2 : ℝ)) (Set.Ici 2) := by
@@ -75,34 +80,89 @@ See `SimpleGraph.tendsto_turanDensity` for proof of existence. -/
7580
noncomputable def turanDensity (H : SimpleGraph W) :=
7681
limUnder atTop fun n ↦ (extremalNumber n H / n.choose 2 : ℝ)
7782

83+
theorem isGLB_turanDensity (H : SimpleGraph W) :
84+
IsGLB { (extremalNumber n H / n.choose 2 : ℝ) | n ∈ Set.Ici 2 } (turanDensity H) := by
85+
have h_bdd : BddBelow { (extremalNumber n H / n.choose 2 : ℝ) | n ∈ Set.Ici 2 } := by
86+
refine ⟨0, fun x ⟨_, _, hx⟩ ↦ ?_⟩
87+
rw [← hx]
88+
positivity
89+
refine Real.isGLB_of_tendsto_antitoneOn_bddBelow_nat_Ici ?_
90+
(antitoneOn_extremalNumber_div_choose_two H) h_bdd
91+
have h_tto := Real.tendsto_atTop_csInf_of_antitoneOn_bddBelow_nat_Ici
92+
(antitoneOn_extremalNumber_div_choose_two H) h_bdd
93+
rwa [← h_tto.limUnder_eq] at h_tto
94+
95+
theorem turanDensity_eq_csInf (H : SimpleGraph W) :
96+
turanDensity H = sInf { (extremalNumber n H / n.choose 2 : ℝ) | n ∈ Set.Ici 2 } :=
97+
have h := isGLB_turanDensity H
98+
(h.csInf_eq h.nonempty).symm
99+
78100
/-- The **Turán density** of a simple graph `H` is well-defined. -/
79101
theorem tendsto_turanDensity (H : SimpleGraph W) :
80102
Tendsto (fun n ↦ (extremalNumber n H / n.choose 2 : ℝ)) atTop (𝓝 (turanDensity H)) := by
81-
let f := fun n ↦ (extremalNumber n H / n.choose 2 : ℝ)
82-
suffices h : ∃ x, Tendsto (fun n ↦ f (n + 2)) atTop (𝓝 x) by
83-
obtain ⟨_, h⟩ := by simpa [tendsto_add_atTop_iff_nat 2] using h
84-
simpa [← Tendsto.limUnder_eq h] using h
85-
use ⨅ n, f (n + 2)
86-
apply tendsto_atTop_ciInf
87-
· rw [antitone_add_nat_iff_antitoneOn_nat_Ici]
88-
exact antitoneOn_extremalNumber_div_choose_two H
89-
· use 0
90-
intro n ⟨_, hn⟩
91-
rw [← hn]
92-
positivity
103+
have h_tendsto := Real.tendsto_atTop_csInf_of_antitoneOn_bddBelow_nat_Ici
104+
(antitoneOn_extremalNumber_div_choose_two H) (isGLB_turanDensity H).bddBelow
105+
rwa [turanDensity, h_tendsto.limUnder_eq]
93106

94107
/-- `extremalNumber n H` is asymptotically equivalent to `turanDensity H * n.choose 2` as `n`
95108
approaches `∞`. -/
96-
theorem isEquivalent_extremalNumber (h : turanDensity H ≠ 0) :
109+
theorem isEquivalent_extremalNumber {H : SimpleGraph W} (h : turanDensity H ≠ 0) :
97110
(fun n ↦ (extremalNumber n H : ℝ)) ~[atTop] (fun n ↦ (turanDensity H * n.choose 2 : ℝ)) := by
98111
have hπ := tendsto_turanDensity H
99112
apply Tendsto.const_mul (1 / turanDensity H : ℝ) at hπ
100113
simp_rw [one_div_mul_cancel h, div_mul_div_comm, one_mul] at hπ
101114
have hz : ∀ᶠ (x : ℕ) in atTop, turanDensity H * x.choose 20 := by
102115
rw [eventually_atTop]
103-
use 2
104-
intro n hn
116+
refine ⟨2, fun n hn ↦ ?_⟩
105117
simp [h, Nat.choose_eq_zero_iff, hn]
106118
simpa [isEquivalent_iff_tendsto_one hz] using
107119

120+
/-- Simple graphs on `n` vertices having at least `(turanDensity H + o(1)) * n ^ 2` edges contain
121+
`H`, for sufficiently large `n`. -/
122+
theorem eventually_isContained_of_card_edgeFinset (H : SimpleGraph W) {ε : ℝ} (hε_pos : 0 < ε) :
123+
∀ᶠ n in atTop, ∀ {G : SimpleGraph (Fin n)} [DecidableRel G.Adj],
124+
#G.edgeFinset ≥ (turanDensity H + ε) * n.choose 2 → H ⊑ G := by
125+
have hπ := (turanDensity_eq_csInf H).ge
126+
rw [eventually_atTop]
127+
contrapose! hπ with h
128+
apply lt_of_lt_of_le <| lt_add_of_pos_right (turanDensity H) hε_pos
129+
refine le_csInf ?_ (fun x ⟨m, hm, hx⟩ ↦ ?_)
130+
· rw [← Set.image, Set.image_nonempty]
131+
exact Set.nonempty_Ici
132+
rw [← hx]
133+
have ⟨n, hn, G, _, hcard_edges, h_free⟩ := h m
134+
replace h_free : H.Free G := not_nonempty_iff.mpr h_free
135+
trans (extremalNumber n H / n.choose 2)
136+
· rw [le_div_iff₀ <| mod_cast Nat.choose_pos (hm.trans hn)]
137+
conv =>
138+
enter [2, 1, 1]
139+
rw [← Fintype.card_fin n]
140+
exact hcard_edges.trans (mod_cast card_edgeFinset_le_extremalNumber h_free)
141+
· exact antitoneOn_extremalNumber_div_choose_two H hm (hm.trans hn) hn
142+
143+
open Classical in
144+
/-- The edge density of `H`-free simple graphs on `turanDensityConst H ε` vertices
145+
is at most `turanDensity H + ε`.
146+
147+
Contrapositively, `turanDensity H + ε` is the density at which `H` is always contained in simple
148+
graphs on `turanDensityConst H ε` vertices.
149+
150+
Note that this value is only defined for positive `ε` and `turanDensityConst H ε = 0` for non
151+
positive `ε`. -/
152+
noncomputable abbrev turanDensityConst (H : SimpleGraph W) (ε : ℝ) :=
153+
if h : ε > 0 then
154+
Nat.find <| eventually_atTop.mp <| eventually_isContained_of_card_edgeFinset H h
155+
else 0
156+
157+
open Classical in
158+
/-- Simple graphs on `card V` vertices having at least `(turanDensity H + o(1)) * (card V) ^ 2`
159+
edges contain `H`, for sufficiently large `card V`. -/
160+
theorem isContained_of_card_edgeFinset (H : SimpleGraph W) {ε : ℝ} (hε_pos : 0 < ε)
161+
{V : Type*} [Fintype V] (h_verts : card V ≥ turanDensityConst H ε)
162+
(G : SimpleGraph V) [DecidableRel G.Adj] :
163+
#G.edgeFinset ≥ (turanDensity H + ε) * (card V).choose 2 → H ⊑ G := by
164+
rw [(G.overFinIso rfl).card_edgeFinset_eq, isContained_congr Iso.refl (G.overFinIso rfl)]
165+
apply Nat.find_spec <| eventually_atTop.mp <| eventually_isContained_of_card_edgeFinset H hε_pos
166+
simpa only [turanDensityConst, hε_pos, ↓reduceDIte] using h_verts
167+
108168
end SimpleGraph

0 commit comments

Comments
 (0)