@@ -10,8 +10,10 @@ public import Mathlib.Combinatorics.Enumerative.DoubleCounting
1010public import Mathlib.Combinatorics.SimpleGraph.DeleteEdges
1111public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic
1212public import Mathlib.Data.Nat.Choose.Cast
13+
1314import Mathlib.Tactic.Bound
1415import 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
3742namespace SimpleGraph
3843
39- variable {V W : Type *} {G : SimpleGraph V} {H : SimpleGraph W }
44+ variable {W : Type *}
4045
4146lemma 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. -/
7580noncomputable 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. -/
79101theorem 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`
95108approaches `∞`. -/
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 2 ≠ 0 := 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 hπ
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+
108168end SimpleGraph
0 commit comments