Catalog/Sparsity/Densification/Full.lean
| 1 | import Catalog.Sparsity.ShallowMinor.Full |
| 2 | import Catalog.Sparsity.ChernoffBound.Full |
| 3 | import Mathlib.Combinatorics.SimpleGraph.Finite |
| 4 | import Mathlib.Analysis.SpecialFunctions.Log.Basic |
| 5 | import Mathlib.Analysis.SpecialFunctions.Pow.Real |
| 6 | import Mathlib.Analysis.SpecialFunctions.Pow.Asymptotics |
| 7 | import Mathlib.MeasureTheory.Constructions.Pi |
| 8 | import Mathlib.MeasureTheory.Integral.Bochner.Set |
| 9 | import Mathlib.Probability.Independence.Basic |
| 10 | import Mathlib.Probability.ProbabilityMassFunction.Integrals |
| 11 | |
| 12 | open Catalog.Sparsity.ShallowMinor Real Filter Finset MeasureTheory ProbabilityTheory PMF NNReal |
| 13 | |
| 14 | namespace Catalog.Sparsity.Densification |
| 15 | |
| 16 | /-! |
| 17 | ## Proof structure |
| 18 | |
| 19 | The proof of `densification` follows Lemma 3.4 of the source, broken into: |
| 20 | |
| 21 | 1. `exists_good_pair` (probabilistic core): For large n, any graph with |
| 22 | min degree ≥ n^ε has disjoint A, B ⊆ V with |A| ∈ [n^{1-ε}, 3n^{1-ε} log n], |
| 23 | |B| ≥ n/2, and every b ∈ B having ≥ log n neighbors in A. |
| 24 | Proof uses Chernoff bounds on Bernoulli sums (not yet in Mathlib). |
| 25 | |
| 26 | 2. `greedy_densify` (graph construction): Given (A, B) as above, the |
| 27 | greedy process either finds K_{t+1} ≼₁ G for t ≥ log n, or builds a |
| 28 | depth-1 minor G' on vertex set A with ≥ |B| edges. |
| 29 | Each step: if N(b) ∩ A is a clique, use b to extend to a clique of size |
| 30 | |N(b) ∩ A| + 1 ≥ log n + 1; else contract b onto some a ∈ N(b) ∩ A, |
| 31 | adding an edge to G'[A]. Branch sets: {a} ∪ {contracted b's}, depth 1. |
| 32 | |
| 33 | 3. `edge_density_bound` (arithmetic): From n' = |A| ≤ 3n^{1-ε} log n |
| 34 | and n/2 ≤ edges, deduce (n')^{1+ε+ε²} ≤ edges for large n. |
| 35 | Proof: (n')^{1+ε+ε²} ≤ C · n^{1-ε³} · (log n)^{1+ε+ε²} ≤ n/2, |
| 36 | where the last step uses n^{ε³} dominates (log n)^{1+ε+ε²} |
| 37 | (from `isLittleO_log_rpow_rpow_atTop` with exponent ε³ > 0). |
| 38 | -/ |
| 39 | |
| 40 | /-- Under the product Bernoulli(p) measure on V → Bool, |
| 41 | the indicator 𝟙[ω v = true] has mean p. -/ |
| 42 | private lemma pi_bernoulli_indicator_mean {V : Type} [DecidableEq V] [Fintype V] |
| 43 | {p : ℝ≥0} (hp : p ≤ 1) (v : V) : |
| 44 | ∫ (ω : V → Bool), (if ω v then (1 : ℝ) else 0) |
| 45 | ∂(Measure.pi (fun _ : V => (bernoulli p hp).toMeasure)) = p.toReal := by |
| 46 | -- Reduce to the single-factor Bernoulli integral via measure pushforward. |
| 47 | have step1 : ∫ (ω : V → Bool), (if ω v then (1 : ℝ) else 0) |
| 48 | ∂(Measure.pi (fun _ : V => (bernoulli p hp).toMeasure)) = |
| 49 | ∫ (b : Bool), (if b then (1 : ℝ) else 0) ∂(bernoulli p hp).toMeasure := by |
| 50 | conv_rhs => rw [← (measurePreserving_eval (μ := fun _ : V => (bernoulli p hp).toMeasure) v).map_eq] |
| 51 | exact (integral_map_of_stronglyMeasurable |
| 52 | (measurable_pi_apply (X := fun _ : V => Bool) v) |
| 53 | (measurable_of_countable (fun b : Bool => if b then (1:ℝ) else 0)).stronglyMeasurable).symm |
| 54 | rw [step1] |
| 55 | simp_rw [show (fun b : Bool => if b then (1 : ℝ) else 0) = fun b => cond b 1 0 from |
| 56 | funext fun b => by cases b <;> rfl] |
| 57 | exact bernoulli_expectation hp |
| 58 | |
| 59 | /-- Under the product Bernoulli(p) measure on V → Bool, the indicators 𝟙[ω v = true] |
| 60 | for v : V are independent random variables (V → Bool) → ℝ. -/ |
| 61 | private lemma pi_bernoulli_iIndepFun {V : Type} [DecidableEq V] [Fintype V] |
| 62 | {p : ℝ≥0} (hp : p ≤ 1) : |
| 63 | iIndepFun (fun (v : V) (ω : V → Bool) => if ω v then (1 : ℝ) else 0) |
| 64 | (Measure.pi (fun _ : V => (bernoulli p hp).toMeasure)) := |
| 65 | iIndepFun_pi (fun _ => (measurable_of_countable |
| 66 | (fun b : Bool => if b then (1 : ℝ) else 0)).aemeasurable) |
| 67 | |
| 68 | /-- **Step 1 (probabilistic core)**: For large n, a min-degree-n^ε graph has |
| 69 | a "good pair" (A, B): disjoint vertex subsets with |A| in [n^{1-ε}, 3n^{1-ε} log n], |
| 70 | |B| ≥ n/2, and every b ∈ B having ≥ log n neighbors in A. |
| 71 | |
| 72 | Source proof: sample each vertex with probability p = 2 log n / n^ε independently. |
| 73 | For large n, p ∈ (0,1). Let A = sampled set, B = {v ∉ A | |N(v) ∩ A| ≥ log n}. |
| 74 | - Chernoff (upper + lower tail) on |A| = ∑_v Bernoulli(p): since μ = np = 2n^{1-ε} log n, |
| 75 | P(|A| ∉ [n^{1-ε} log n, 3n^{1-ε} log n]) ≤ 2 exp(-n^{1-ε} log n / 6) → 0. |
| 76 | - For each v with deg v ≥ n^ε: μ_v = deg(v) · p ≥ 2 log n, so by Chernoff lower tail, |
| 77 | P(|N(v) ∩ A| < log n) ≤ exp(-log n / 6) = n^{-1/6}. |
| 78 | - Since p = 2 log n / n^ε → 0, P(v ∈ A) = p → 0 too. |
| 79 | So P(v ∉ B) ≤ p + n^{-1/6} → 0. For large n, P(v ∉ B) ≤ 1/6. |
| 80 | - By linearity of expectation: E[|V \ B|] ≤ n/6. |
| 81 | - By Markov: P(|B| ≥ n/2) ≥ 1 - P(|V \ B| ≥ n/2) ≥ 1 - 1/3 = 2/3. |
| 82 | - Both events (good A size, |B| ≥ n/2) hold simultaneously with probability ≥ 2/3 + 3/4 - 1 > 0. |
| 83 | - By the probabilistic method, a good (A, B) pair exists. |
| 84 | |
| 85 | Uses `Catalog.Sparsity.ChernoffBound.chernoffBound` applied twice (once for |A|, once per vertex |
| 86 | for the neighbor count). The indicator variables X_v = 𝟙[ω v = true] are i.i.d. Bernoulli(p) |
| 87 | under `Measure.pi (fun _ : V => (PMF.bernoulli p_nnr hp_nnr).toMeasure)`, with independence |
| 88 | from `iIndepFun_pi` and mean from `bernoulli_expectation` + `measurePreserving_eval`. -/ |
| 89 | private lemma exists_good_pair (ε : ℝ) (hε_pos : 0 < ε) (hε_le : ε ≤ 2 / 3) : |
| 90 | ∃ M : ℕ, ∀ {V : Type} [DecidableEq V] [Fintype V] |
| 91 | (G : SimpleGraph V) [DecidableRel G.Adj], |
| 92 | M ≤ Fintype.card V → |
| 93 | (∀ v : V, (Fintype.card V : ℝ) ^ ε ≤ ↑(G.degree v)) → |
| 94 | ∃ (A B : Finset V), Disjoint A B ∧ |
| 95 | (Fintype.card V : ℝ) ^ (1 - ε) ≤ ↑A.card ∧ |
| 96 | (↑A.card : ℝ) ≤ 3 * (Fintype.card V : ℝ) ^ (1 - ε) * log ↑(Fintype.card V) ∧ |
| 97 | (Fintype.card V : ℝ) / 2 ≤ ↑B.card ∧ |
| 98 | ∀ b ∈ B, log ↑(Fintype.card V) ≤ ↑(G.neighborFinset b ∩ A).card := by |
| 99 | -- ======================== THRESHOLD SELECTION ======================== |
| 100 | -- We need n large enough that: |
| 101 | -- (A) p_n := 2 * log n / n^ε is a valid probability in (0,1) |
| 102 | -- (B) The Chernoff bound gives < 1/4 error for |A| |
| 103 | -- (C) Bad-vertex probability p_n + n^{-1/6} ≤ 1/6 |
| 104 | -- |
| 105 | -- Asymptotic: log x = o(x^ε) from isLittleO_log_rpow_atTop |
| 106 | -- ------- |
| 107 | -- (A) p_n ∈ (0,1) eventually: |
| 108 | have hp_pos_ev : ∀ᶠ n : ℕ in Filter.atTop, |
| 109 | 0 < 2 * Real.log n / (n : ℝ) ^ ε := by |
| 110 | rw [Filter.eventually_atTop] |
| 111 | -- log n > 0 for n ≥ 3, and n^ε > 0 for n ≥ 1 |
| 112 | exact ⟨3, fun n hn => div_pos (by |
| 113 | apply mul_pos two_pos |
| 114 | apply Real.log_pos |
| 115 | exact_mod_cast show 1 < n by omega) (Real.rpow_pos_of_pos (by exact_mod_cast show 0 < n by omega) ε)⟩ |
| 116 | have hp_lt1_ev : ∀ᶠ n : ℕ in Filter.atTop, |
| 117 | 2 * Real.log (n : ℝ) / (n : ℝ) ^ ε < 1 := by |
| 118 | have h := (isLittleO_log_rpow_atTop hε_pos).tendsto_div_nhds_zero |
| 119 | have h2 : Filter.Tendsto (fun n : ℕ => 2 * Real.log (n : ℝ) / (n : ℝ) ^ ε) |
| 120 | Filter.atTop (nhds 0) := by |
| 121 | have := h.comp (tendsto_natCast_atTop_atTop (R := ℝ)) |
| 122 | simp only [] at this |
| 123 | have hcov : Filter.Tendsto (fun n : ℕ => 2 * (Real.log (n : ℝ) / (n : ℝ) ^ ε)) |
| 124 | Filter.atTop (nhds 0) := by |
| 125 | simpa [mul_comm] using this.const_mul 2 |
| 126 | simpa [mul_div_assoc] using hcov |
| 127 | exact h2.eventually (gt_mem_nhds (by norm_num : (0 : ℝ) < 1)) |
| 128 | -- (B) Chernoff error < 1/4 eventually: 2·exp(−n^{1−ε}·log n/6) < 1/4 |
| 129 | have hchernoff_ev : ∀ᶠ n : ℕ in Filter.atTop, |
| 130 | 2 * Real.exp (-(((n : ℝ) ^ (1 - ε) * Real.log (n : ℝ)) / 6)) < 1 / 4 := by |
| 131 | have h1e : 0 < 1 - ε := by linarith |
| 132 | have h_rpow : Filter.Tendsto (fun n : ℕ => (n : ℝ) ^ (1 - ε)) Filter.atTop Filter.atTop := |
| 133 | (_root_.tendsto_rpow_atTop h1e).comp (tendsto_natCast_atTop_atTop (R := ℝ)) |
| 134 | have h_logn_ev : ∀ᶠ n : ℕ in Filter.atTop, 1 ≤ Real.log (n : ℝ) := |
| 135 | (Real.tendsto_log_atTop.comp (tendsto_natCast_atTop_atTop (R := ℝ))).eventually_ge_atTop 1 |
| 136 | filter_upwards [h_rpow.eventually_ge_atTop (18 * Real.log 2 + 1), h_logn_ev] |
| 137 | with n h_large h_logn |
| 138 | have h_nn : (0 : ℝ) ≤ (n : ℝ) ^ (1 - ε) := Real.rpow_nonneg (Nat.cast_nonneg _) _ |
| 139 | have h_log8 : Real.log 8 = 3 * Real.log 2 := by |
| 140 | rw [show (8 : ℝ) = 2 ^ (3 : ℕ) by norm_num, Real.log_pow]; push_cast; ring |
| 141 | have h_lb : Real.log 8 < (n : ℝ) ^ (1 - ε) * Real.log n / 6 := by |
| 142 | have h1 : (n : ℝ) ^ (1 - ε) ≤ (n : ℝ) ^ (1 - ε) * Real.log n := |
| 143 | le_mul_of_one_le_right h_nn h_logn |
| 144 | linarith |
| 145 | calc 2 * Real.exp (-((n : ℝ) ^ (1 - ε) * Real.log n / 6)) |
| 146 | < 2 * Real.exp (-Real.log 8) := by |
| 147 | apply mul_lt_mul_of_pos_left _ two_pos |
| 148 | exact Real.exp_lt_exp.mpr (by linarith) |
| 149 | _ = 1 / 4 := by |
| 150 | rw [Real.exp_neg, Real.exp_log (by norm_num : (0 : ℝ) < 8)]; norm_num |
| 151 | -- (C) Bad vertex probability p + 2·n^{-1/6} < 1/6 eventually |
| 152 | -- (Factor 2 accounts for the two-sided Chernoff bound applied per vertex) |
| 153 | have hbad_ev : ∀ᶠ n : ℕ in Filter.atTop, |
| 154 | 2 * Real.log (n : ℝ) / (n : ℝ) ^ ε + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)) < 1 / 6 := by |
| 155 | have h_log_zero : Filter.Tendsto (fun n : ℕ => 2 * Real.log (n : ℝ) / (n : ℝ) ^ ε) |
| 156 | Filter.atTop (nhds 0) := by |
| 157 | have h := (isLittleO_log_rpow_atTop hε_pos).tendsto_div_nhds_zero |
| 158 | have h2 := (h.comp (tendsto_natCast_atTop_atTop (R := ℝ))).const_mul 2 |
| 159 | simp only [mul_zero] at h2; simpa [mul_div_assoc] using h2 |
| 160 | have h_pow_zero : Filter.Tendsto (fun n : ℕ => 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) |
| 161 | Filter.atTop (nhds 0) := by |
| 162 | have := (tendsto_rpow_neg_atTop (by norm_num : (0 : ℝ) < 1 / 6)).comp |
| 163 | (tendsto_natCast_atTop_atTop (R := ℝ)) |
| 164 | simpa using this.const_mul 2 |
| 165 | have h_sum : Filter.Tendsto |
| 166 | (fun n : ℕ => 2 * Real.log (n : ℝ) / (n : ℝ) ^ ε + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) |
| 167 | Filter.atTop (nhds 0) := by simpa using h_log_zero.add h_pow_zero |
| 168 | filter_upwards [h_sum.eventually (Iio_mem_nhds (by norm_num : (0 : ℝ) < 1 / 6))] |
| 169 | with n hn; exact hn |
| 170 | -- (D) log n ≥ 1 eventually (needed to relate n^{1-ε} lower bound to n·p/2) |
| 171 | have h_logn_ev : ∀ᶠ n : ℕ in Filter.atTop, 1 ≤ Real.log (n : ℝ) := |
| 172 | (Real.tendsto_log_atTop.comp (tendsto_natCast_atTop_atTop (R := ℝ))).eventually_ge_atTop 1 |
| 173 | -- Extract concrete M |
| 174 | obtain ⟨M, hM⟩ := Filter.eventually_atTop.mp |
| 175 | (hp_pos_ev.and (hp_lt1_ev.and (hchernoff_ev.and (hbad_ev.and h_logn_ev)))) |
| 176 | refine ⟨M, ?_⟩ |
| 177 | -- ======================== MAIN ARGUMENT ======================== |
| 178 | intro V inst_deq inst_fin G inst_adj hn hG_deg |
| 179 | -- Set up notation |
| 180 | set n := Fintype.card V with hn_def |
| 181 | -- Unpack threshold conditions for this n |
| 182 | obtain ⟨hp_pos, hp_lt1, hchernoff, hbad, h_logn⟩ := hM n hn |
| 183 | -- Lift p to NNReal |
| 184 | have hp_nn_pos : (0 : ℝ) ≤ 2 * Real.log n / (n : ℝ) ^ ε := hp_pos.le |
| 185 | let p_nnr : ℝ≥0 := ⟨2 * Real.log n / (n : ℝ) ^ ε, hp_nn_pos⟩ |
| 186 | have hp_nnr : p_nnr ≤ 1 := by |
| 187 | have : (p_nnr : ℝ) ≤ 1 := hp_lt1.le |
| 188 | exact_mod_cast this |
| 189 | -- ======================== PROBABILITY SPACE ======================== |
| 190 | -- Product Bernoulli(p) measure on V → Bool |
| 191 | let μ := Measure.pi (fun _ : V => (bernoulli p_nnr hp_nnr).toMeasure) |
| 192 | haveI : IsProbabilityMeasure μ := inferInstance |
| 193 | -- Indicator variables: X_v ω = 𝟙[ω v = true] |
| 194 | let X : V → (V → Bool) → ℝ := fun v ω => if ω v then 1 else 0 |
| 195 | -- Properties of X needed for Chernoff: |
| 196 | have hX_meas : ∀ v : V, Measurable (X v) := |
| 197 | fun v => measurable_of_countable (X v) |
| 198 | have hX_bern : ∀ v : V, ∀ᵐ ω ∂μ, X v ω = 0 ∨ X v ω = 1 := |
| 199 | fun v => Filter.Eventually.of_forall (fun ω => by simp [X]) |
| 200 | have hX_mean : ∀ v : V, ∫ ω, X v ω ∂μ = p_nnr.toReal := |
| 201 | fun v => pi_bernoulli_indicator_mean hp_nnr v |
| 202 | have hX_indep : iIndepFun X μ := pi_bernoulli_iIndepFun hp_nnr |
| 203 | -- ======================== CHERNOFF BOUND FOR |A| ======================== |
| 204 | -- Use Fintype.equivFin to reindex V as Fin n |
| 205 | let e : V ≃ Fin n := Fintype.equivFin V |
| 206 | -- Reindexed variables: Y_i ω = X_{e.symm i} ω |
| 207 | let Y : Fin n → (V → Bool) → ℝ := fun i => X (e.symm i) |
| 208 | have hY_meas : ∀ i : Fin n, Measurable (Y i) := fun i => hX_meas (e.symm i) |
| 209 | have hY_bern : ∀ i : Fin n, ∀ᵐ ω ∂μ, Y i ω = 0 ∨ Y i ω = 1 := |
| 210 | fun i => hX_bern (e.symm i) |
| 211 | have hY_mean : ∀ i : Fin n, ∫ ω, Y i ω ∂μ = p_nnr.toReal := fun i => hX_mean (e.symm i) |
| 212 | have hY_indep : iIndepFun Y μ := |
| 213 | hX_indep.precomp e.symm.injective |
| 214 | -- p_nnr.toReal ∈ [0,1] |
| 215 | have hp_icc : p_nnr.toReal ∈ Set.Icc (0 : ℝ) 1 := |
| 216 | ⟨NNReal.coe_nonneg _, NNReal.coe_le_one.mpr hp_nnr⟩ |
| 217 | -- Chernoff bound: δ = 1/2 |
| 218 | have hδ : (1/2 : ℝ) ∈ Set.Ioo 0 1 := by norm_num |
| 219 | have h_chernoff_A := |
| 220 | Catalog.Sparsity.ChernoffBound.chernoffBound hp_icc hY_meas hY_indep hY_bern hY_mean hδ |
| 221 | -- h_chernoff_A : μ.real {ω | 1/2 * (n * p) ≤ |∑_i Y i ω - n * p|} ≤ 2*exp(−(1/4*n*p/3)) |
| 222 | -- Note: ∑_i Y_i ω = ∑_v X_v ω = |{v | ω v}| |
| 223 | -- Good event for |A|: |∑_i Y_i ω - n*p| < n*p/2, i.e., ∑_i Y_i ∈ [n*p/2, 3*n*p/2] |
| 224 | -- ======================== GOOD PAIR HAS POSITIVE MEASURE ======================== |
| 225 | -- A good ω: A = {v | ω v}, B = {v | !ω v ∧ |N(v) ∩ A| ≥ log n}, with A and B in right range. |
| 226 | let good_event : Set (V → Bool) := {ω | |
| 227 | -- A is in the right size range |
| 228 | (n : ℝ) ^ (1 - ε) ≤ (Finset.univ.filter (fun v => ω v)).card ∧ |
| 229 | ((Finset.univ.filter (fun v => ω v)).card : ℝ) ≤ |
| 230 | 3 * (n : ℝ) ^ (1 - ε) * Real.log n ∧ |
| 231 | -- B (vertices not in A with enough neighbors in A) has size ≥ n/2 |
| 232 | (n : ℝ) / 2 ≤ (Finset.univ.filter (fun v => |
| 233 | !ω v ∧ Real.log n ≤ |
| 234 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card} |
| 235 | -- The good event has positive measure (the hard probabilistic argument) |
| 236 | have h_good_pos : 0 < μ.real good_event := by |
| 237 | -- ∑_i Y_i ω = |(Finset.univ.filter (fun v => ω v))| as reals |
| 238 | have h_sum_card : ∀ ω : V → Bool, |
| 239 | (∑ i : Fin n, Y i ω : ℝ) = |
| 240 | (Finset.univ.filter (fun v : V => ω v)).card := fun ω => by |
| 241 | simp only [Y, X] |
| 242 | rw [show (∑ i : Fin n, if ω (e.symm i) = true then (1:ℝ) else 0) = |
| 243 | ∑ v : V, if ω v = true then (1:ℝ) else 0 from |
| 244 | Equiv.sum_comp e.symm (fun v => if ω v = true then (1:ℝ) else 0)] |
| 245 | simp |
| 246 | -- P(|∑_i Y_i - n*p| ≥ n*p/2) ≤ 2*exp(-n*p/12) < 1/4 (from h_chernoff_A + hchernoff) |
| 247 | -- n*p = 2 * n^{1-ε} * log n, n*p/12 = n^{1-ε} * log n / 6 |
| 248 | -- h_chernoff_A gives: μ.real {ω | 1/2*(n*p) ≤ |∑_i Y_i ω - n*p|} ≤ 2*exp(-1/4*n*p/3) |
| 249 | -- and 1/4 * n*p / 3 = n*p/12 = n^{1-ε}*log n/6 |
| 250 | -- Relate: {ω | good A size} ⊇ {ω | |∑_i Y_i ω - n*p| < n*p/2} |
| 251 | -- So P(bad A) ≤ P(|∑_i Y_i - n*p| ≥ n*p/2) ≤ 2*exp(-n*p/12) < 1/4 |
| 252 | have h_bad_A : μ.real {ω | ¬( |
| 253 | (n : ℝ) ^ (1 - ε) ≤ (Finset.univ.filter (fun v => ω v)).card ∧ |
| 254 | ((Finset.univ.filter (fun v => ω v)).card : ℝ) ≤ |
| 255 | 3 * (n : ℝ) ^ (1 - ε) * Real.log n)} < 1 / 4 := by |
| 256 | -- n > 0 (otherwise hp_pos : 0 < 0, contradiction) |
| 257 | have hn_pos : (0 : ℝ) < n := by |
| 258 | rcases Nat.eq_zero_or_pos n with h | h |
| 259 | · simp only [h, Nat.cast_zero, Real.log_zero, mul_zero, zero_div] at hp_pos |
| 260 | exact absurd hp_pos (lt_irrefl _) |
| 261 | · exact Nat.cast_pos.mpr h |
| 262 | have h_npe : 0 < (n : ℝ)^(1 - ε) := Real.rpow_pos_of_pos hn_pos _ |
| 263 | -- n * p = 2 * n^{1-ε} * log n (since p = 2*log n / n^ε and n/n^ε = n^{1-ε}) |
| 264 | have hn_p : (n : ℝ) * (p_nnr : ℝ) = 2 * (n : ℝ)^(1-ε) * Real.log n := by |
| 265 | show (n : ℝ) * (2 * Real.log n / (n : ℝ)^ε) = 2 * (n : ℝ)^(1-ε) * Real.log n |
| 266 | have hdiv : (n : ℝ) / (n : ℝ)^ε = (n : ℝ)^(1-ε) := by |
| 267 | rw [Real.rpow_sub hn_pos, Real.rpow_one] |
| 268 | rw [show (n : ℝ) * (2 * Real.log n / (n : ℝ)^ε) = |
| 269 | 2 * ((n : ℝ) / (n : ℝ)^ε) * Real.log n from by ring, hdiv] |
| 270 | -- {bad_A} ⊆ {Chernoff set}: if |A| ∉ [n^{1-ε}, 3n^{1-ε}logn] then |∑Yi - np| ≥ np/2 |
| 271 | have h_sub_A : {ω | ¬((n : ℝ)^(1-ε) ≤ ↑(Finset.univ.filter (fun v => ω v)).card ∧ |
| 272 | ↑(Finset.univ.filter (fun v => ω v)).card ≤ 3*(n:ℝ)^(1-ε)*Real.log n)} ⊆ |
| 273 | {ω | 1/2 * ((n:ℝ) * ↑p_nnr) ≤ |∑ i, Y i ω - (n:ℝ) * ↑p_nnr|} := by |
| 274 | intro ω hω |
| 275 | simp only [Set.mem_setOf_eq, not_and_or, not_le] at hω |
| 276 | rw [← h_sum_card ω] at hω |
| 277 | simp only [Set.mem_setOf_eq, hn_p] |
| 278 | rcases hω with hlo | hhi |
| 279 | · -- lower tail: ∑Yi < n^{1-ε} ≤ n^{1-ε}·logn = np/2 |
| 280 | have h_lt : ∑ i, Y i ω < (n:ℝ)^(1-ε) * Real.log n := |
| 281 | hlo.trans_le (le_mul_of_one_le_right h_npe.le h_logn) |
| 282 | rw [abs_of_nonpos (by |
| 283 | have := mul_nonneg h_npe.le (by linarith : (0:ℝ) ≤ Real.log n) |
| 284 | linarith)] |
| 285 | linarith |
| 286 | · -- upper tail: ∑Yi > 3n^{1-ε}·logn = np/2 + np |
| 287 | have h_prod : 0 < (n:ℝ)^(1-ε) * Real.log n := mul_pos h_npe (by linarith) |
| 288 | rw [abs_of_pos (by linarith)] |
| 289 | linarith |
| 290 | -- Chain: μ(bad_A) ≤ μ(Chernoff) ≤ 2·exp(−np/12) = 2·exp(−n^{1-ε}·logn/6) < 1/4 |
| 291 | have h_exp_simp : (1/2:ℝ)^2 * ((n:ℝ) * ↑p_nnr) / 3 = (n:ℝ)^(1-ε) * Real.log n / 6 := by |
| 292 | rw [hn_p]; ring |
| 293 | calc μ.real {ω | ¬((n:ℝ)^(1-ε) ≤ ↑(Finset.univ.filter (fun v => ω v)).card ∧ |
| 294 | ↑(Finset.univ.filter (fun v => ω v)).card ≤ 3*(n:ℝ)^(1-ε)*Real.log n)} |
| 295 | ≤ μ.real {ω | 1/2 * ((n:ℝ) * ↑p_nnr) ≤ |∑ i, Y i ω - (n:ℝ) * ↑p_nnr|} := |
| 296 | measureReal_mono h_sub_A |
| 297 | _ ≤ 2 * Real.exp (-((1/2:ℝ)^2 * ((n:ℝ) * ↑p_nnr) / 3)) := h_chernoff_A |
| 298 | _ = 2 * Real.exp (-((n:ℝ)^(1-ε) * Real.log n / 6)) := by |
| 299 | rw [show (1/2:ℝ)^2 * ((n:ℝ) * ↑p_nnr) / 3 = (n:ℝ)^(1-ε) * Real.log n / 6 from |
| 300 | h_exp_simp] |
| 301 | _ < 1/4 := hchernoff |
| 302 | -- P(|B| < n/2) < 1/3 (Markov on |V\B| with E[|V\B|] ≤ n*(p + 2*n^{-1/6}) and hbad) |
| 303 | have h_bad_B : μ.real {ω | ¬ ((n : ℝ) / 2 ≤ |
| 304 | (Finset.univ.filter (fun v => |
| 305 | !ω v ∧ Real.log n ≤ |
| 306 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card)} < 1 / 3 := by |
| 307 | -- n > 0 (from hp_pos) |
| 308 | have hn_pos : (0 : ℝ) < n := by |
| 309 | rcases Nat.eq_zero_or_pos n with h | h |
| 310 | · simp only [h, Nat.cast_zero, Real.log_zero, mul_zero, zero_div] at hp_pos |
| 311 | exact absurd hp_pos (lt_irrefl _) |
| 312 | · exact Nat.cast_pos.mpr h |
| 313 | have h_npe : 0 < (n : ℝ) ^ ε := Real.rpow_pos_of_pos hn_pos _ |
| 314 | have h_npi : 0 < (n : ℝ) ^ (-(1 / 6 : ℝ)) := Real.rpow_pos_of_pos hn_pos _ |
| 315 | -- deg(v) * p ≥ 2 * log n for each v (from hG_deg and p = 2*log n/n^ε) |
| 316 | have h_dp_lower : ∀ v : V, 2 * Real.log n ≤ (G.degree v : ℝ) * (p_nnr : ℝ) := fun v => by |
| 317 | have hdeg := hG_deg v |
| 318 | calc 2 * Real.log n |
| 319 | = (n : ℝ) ^ ε * (p_nnr : ℝ) := by |
| 320 | show 2 * Real.log n = (n : ℝ) ^ ε * (2 * Real.log n / (n : ℝ) ^ ε) |
| 321 | field_simp |
| 322 | _ ≤ (G.degree v : ℝ) * (p_nnr : ℝ) := |
| 323 | mul_le_mul_of_nonneg_right hdeg hp_pos.le |
| 324 | -- Per-vertex Chernoff: P(|N(v) ∩ A| < log n) ≤ 2 * n^{-1/6} |
| 325 | have h_chernoff_vtx : ∀ v : V, |
| 326 | μ.real {ω | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card < |
| 327 | Real.log n} ≤ 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)) := fun v => by |
| 328 | -- Sum identity: ∑_j X(nbr_j(v)) ω = |N(v) ∩ A(ω)| |
| 329 | have h_sum_v : ∀ ω : V → Bool, |
| 330 | (∑ j : Fin (G.degree v), |
| 331 | X ((Finset.equivFin (G.neighborFinset v)).symm j).val ω : ℝ) = |
| 332 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card := fun ω => by |
| 333 | simp only [X] |
| 334 | rw [show G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u) = |
| 335 | (G.neighborFinset v).filter (fun u => ω u) by ext; simp] |
| 336 | rw [show (((G.neighborFinset v).filter (fun u => ω u)).card : ℝ) = |
| 337 | ∑ u ∈ G.neighborFinset v, if ω u then (1 : ℝ) else 0 by |
| 338 | push_cast [Finset.card_filter] |
| 339 | apply Finset.sum_congr rfl; intro x _; simp] |
| 340 | rw [← Finset.sum_coe_sort (G.neighborFinset v)] |
| 341 | apply Fintype.sum_equiv (Finset.equivFin (G.neighborFinset v)).symm |
| 342 | intro j; simp |
| 343 | -- Independence of neighbor indicators via precomp |
| 344 | have hg_inj : Function.Injective |
| 345 | (fun j : Fin (G.degree v) => |
| 346 | ((Finset.equivFin (G.neighborFinset v)).symm j).val) := fun a b hab => by |
| 347 | have h1 := Subtype.val_injective hab |
| 348 | exact (Finset.equivFin (G.neighborFinset v)).symm.injective h1 |
| 349 | -- Apply Chernoff with δ = 1/2 |
| 350 | have h_chernoff_Z := |
| 351 | Catalog.Sparsity.ChernoffBound.chernoffBound hp_icc |
| 352 | (fun j => hX_meas ((Finset.equivFin (G.neighborFinset v)).symm j).val) |
| 353 | (hX_indep.precomp hg_inj) |
| 354 | (fun j => hX_bern ((Finset.equivFin (G.neighborFinset v)).symm j).val) |
| 355 | (fun j => hX_mean ((Finset.equivFin (G.neighborFinset v)).symm j).val) |
| 356 | hδ |
| 357 | -- Subset: {|N(v)∩A| < log n} ⊆ {Chernoff condition} |
| 358 | have h_dp := h_dp_lower v |
| 359 | have h_sub_v : {ω | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card < |
| 360 | Real.log n} ⊆ |
| 361 | {ω | 1 / 2 * ((G.degree v : ℝ) * ↑p_nnr) ≤ |
| 362 | |∑ j : Fin (G.degree v), |
| 363 | X ((Finset.equivFin (G.neighborFinset v)).symm j).val ω - |
| 364 | (G.degree v : ℝ) * ↑p_nnr|} := fun ω hω => by |
| 365 | simp only [Set.mem_setOf_eq] at hω ⊢ |
| 366 | rw [h_sum_v] |
| 367 | have h_neg : ((G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card : ℝ) - |
| 368 | (G.degree v : ℝ) * ↑p_nnr < 0 := by linarith |
| 369 | rw [abs_of_nonpos (le_of_lt h_neg)] |
| 370 | linarith |
| 371 | -- Bound: 2*exp(−deg*p/12) ≤ 2*n^{−1/6} (since deg*p ≥ 2*log n) |
| 372 | have h_exp_bound : 2 * Real.exp (-((1 / 2 : ℝ) ^ 2 * ((G.degree v : ℝ) * ↑p_nnr) / 3)) ≤ |
| 373 | 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)) := by |
| 374 | apply mul_le_mul_of_nonneg_left _ (by norm_num) |
| 375 | have h1 : (n : ℝ) ^ (-(1 / 6 : ℝ)) = Real.exp (-(Real.log n / 6)) := by |
| 376 | rw [Real.rpow_neg (le_of_lt hn_pos), Real.rpow_def_of_pos hn_pos, ← Real.exp_neg] |
| 377 | congr 1; ring |
| 378 | rw [h1] |
| 379 | apply Real.exp_le_exp_of_le |
| 380 | linarith |
| 381 | calc μ.real {ω | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card < |
| 382 | Real.log n} |
| 383 | ≤ μ.real {ω | 1 / 2 * ((G.degree v : ℝ) * ↑p_nnr) ≤ |
| 384 | |∑ j : Fin (G.degree v), |
| 385 | X ((Finset.equivFin (G.neighborFinset v)).symm j).val ω - |
| 386 | (G.degree v : ℝ) * ↑p_nnr|} := measureReal_mono h_sub_v |
| 387 | _ ≤ 2 * Real.exp (-((1 / 2 : ℝ) ^ 2 * ((G.degree v : ℝ) * ↑p_nnr) / 3)) := |
| 388 | h_chernoff_Z |
| 389 | _ ≤ 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)) := h_exp_bound |
| 390 | -- P(v ∉ B) ≤ p + 2*n^{-1/6} via union bound |
| 391 | have h_bad_v : ∀ v : V, |
| 392 | μ.real {ω | ¬(!ω v ∧ Real.log n ≤ |
| 393 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)} ≤ |
| 394 | (p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)) := fun v => by |
| 395 | -- {v ∉ B} ⊆ {ω v = true} ∪ {|N(v)∩A| < log n} |
| 396 | have h_sub : {ω | ¬(!ω v ∧ Real.log n ≤ |
| 397 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)} ⊆ |
| 398 | {ω : V → Bool | ω v = true} ∪ |
| 399 | {ω | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card < |
| 400 | Real.log n} := fun ω hω => by |
| 401 | simp only [Set.mem_setOf_eq, not_and_or, Bool.not_eq_true, not_le, |
| 402 | Set.mem_union] at * |
| 403 | rcases hω with h | h |
| 404 | · left; cases hv : ω v |
| 405 | · simp [hv] at h |
| 406 | · rfl |
| 407 | · right; exact h |
| 408 | -- P(ω v = true) = p |
| 409 | have h_p_v : μ.real {ω : V → Bool | ω v = true} = (p_nnr : ℝ) := by |
| 410 | rw [← hX_mean v, ← integral_indicator_one MeasurableSet.of_discrete] |
| 411 | congr 1; ext ω; simp [X, Set.indicator] |
| 412 | linarith [(measureReal_mono h_sub (measure_ne_top μ _)).trans (measureReal_union_le _ _), |
| 413 | h_chernoff_vtx v, h_p_v.symm.le] |
| 414 | -- Markov on f = |V\B| (count of bad vertices) |
| 415 | let notB_pred : V → (V → Bool) → Prop := fun v ω => |
| 416 | ¬(!ω v ∧ Real.log n ≤ |
| 417 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card) |
| 418 | let f : (V → Bool) → ℝ := |
| 419 | fun ω => (Finset.univ.filter (fun v => notB_pred v ω)).card |
| 420 | -- {bad_B} ⊆ {f ≥ n/2} |
| 421 | have h_sub_f : {ω | ¬ ((n : ℝ) / 2 ≤ |
| 422 | (Finset.univ.filter (fun v => |
| 423 | !ω v ∧ Real.log n ≤ |
| 424 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card)} ⊆ |
| 425 | {ω | (n : ℝ) / 2 ≤ f ω} := fun ω hω => by |
| 426 | simp only [Set.mem_setOf_eq, f, notB_pred] at * |
| 427 | have h_sum : ((Finset.univ.filter (fun v => !ω v ∧ Real.log n ≤ |
| 428 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card : ℝ) + |
| 429 | ((Finset.univ.filter (fun v => ¬(!ω v ∧ Real.log n ≤ |
| 430 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card))).card : ℝ) = |
| 431 | n := by |
| 432 | have key := @Finset.card_filter_add_card_filter_not V Finset.univ |
| 433 | (fun v => !ω v ∧ Real.log n ≤ |
| 434 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card) _ _ |
| 435 | rw [Finset.card_univ] at key |
| 436 | exact_mod_cast key.trans hn_def.symm |
| 437 | linarith |
| 438 | -- Markov inequality |
| 439 | have hf_nonneg : 0 ≤ᵐ[μ] f := |
| 440 | Filter.Eventually.of_forall (fun ω => by positivity) |
| 441 | have h_markov := |
| 442 | mul_meas_ge_le_integral_of_nonneg hf_nonneg Integrable.of_finite ((n : ℝ) / 2) |
| 443 | -- ∫ f ∂μ = ∑_v P(v ∉ B) |
| 444 | have h_int : ∫ ω, f ω ∂μ = ∑ v : V, μ.real {ω | notB_pred v ω} := by |
| 445 | conv_lhs => |
| 446 | arg 2; ext ω |
| 447 | rw [show (f ω : ℝ) = ∑ v : V, |
| 448 | ({ω | notB_pred v ω} : Set _).indicator (fun _ => (1 : ℝ)) ω from by |
| 449 | simp [f, notB_pred, Set.indicator]] |
| 450 | rw [integral_finset_sum Finset.univ (fun v _ => Integrable.of_finite)] |
| 451 | congr 1; ext v |
| 452 | exact MeasureTheory.integral_indicator_one MeasurableSet.of_discrete |
| 453 | -- ∫ f ∂μ ≤ n * (p + 2*n^{-1/6}) |
| 454 | have h_int_bound : ∫ ω, f ω ∂μ ≤ n * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) := by |
| 455 | rw [h_int] |
| 456 | calc ∑ v : V, μ.real {ω | notB_pred v ω} |
| 457 | ≤ ∑ v : V, ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) := |
| 458 | Finset.sum_le_sum (fun v _ => h_bad_v v) |
| 459 | _ = n * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) := by |
| 460 | simp [Finset.sum_const, Finset.card_univ, hn_def]; ring |
| 461 | -- Chain: P(bad_B) ≤ P(f ≥ n/2) ≤ E[f]/(n/2) ≤ 2*(p+2*n^{-1/6}) < 1/3 |
| 462 | have hn_half : 0 < (n : ℝ) / 2 := by linarith |
| 463 | have h_Pf : μ.real {ω | (n : ℝ) / 2 ≤ f ω} ≤ |
| 464 | 2 * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) := by |
| 465 | have h_final : (n : ℝ) / 2 * μ.real {ω | (n : ℝ) / 2 ≤ f ω} ≤ |
| 466 | n * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) := |
| 467 | h_markov.trans h_int_bound |
| 468 | rw [show (n : ℝ) * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) = |
| 469 | (n : ℝ) / 2 * (2 * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ)))) from by ring] |
| 470 | at h_final |
| 471 | exact le_of_mul_le_mul_left h_final hn_half |
| 472 | have h_p_val : (p_nnr : ℝ) = 2 * Real.log n / (n : ℝ) ^ ε := rfl |
| 473 | have h_bound : 2 * ((p_nnr : ℝ) + 2 * (n : ℝ) ^ (-(1 / 6 : ℝ))) < 1 / 3 := by |
| 474 | linarith |
| 475 | linarith [measureReal_mono h_sub_f (measure_ne_top μ _)] |
| 476 | -- Combine: P(good_event^c) ≤ P(bad_A) + P(bad_B) < 1/4 + 1/3 = 7/12 < 1 |
| 477 | -- So P(good_event) ≥ 5/12 > 0 |
| 478 | have h_bad_total : μ.real good_eventᶜ < 1 := by |
| 479 | have h_sub : good_eventᶜ ⊆ |
| 480 | {ω | ¬((n : ℝ) ^ (1 - ε) ≤ (Finset.univ.filter (fun v => ω v)).card ∧ |
| 481 | (Finset.univ.filter (fun v => ω v)).card ≤ |
| 482 | 3 * (n : ℝ) ^ (1 - ε) * Real.log n)} ∪ |
| 483 | {ω | ¬((n : ℝ) / 2 ≤ (Finset.univ.filter (fun v => |
| 484 | !ω v ∧ Real.log n ≤ |
| 485 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card)} := by |
| 486 | intro ω hω |
| 487 | simp only [good_event, Set.mem_compl_iff, Set.mem_setOf_eq, not_and] at hω |
| 488 | simp only [Set.mem_union, Set.mem_setOf_eq] |
| 489 | by_cases hA : (n : ℝ) ^ (1 - ε) ≤ (Finset.univ.filter (fun v => ω v)).card ∧ |
| 490 | ((Finset.univ.filter (fun v => ω v)).card : ℝ) ≤ 3 * (n : ℝ) ^ (1 - ε) * Real.log n |
| 491 | · exact Or.inr (hω hA.1 hA.2) |
| 492 | · exact Or.inl hA |
| 493 | have h_union : μ.real (good_eventᶜ) ≤ |
| 494 | μ.real {ω | ¬((n : ℝ) ^ (1 - ε) ≤ (Finset.univ.filter (fun v => ω v)).card ∧ |
| 495 | ((Finset.univ.filter (fun v => ω v)).card : ℝ) ≤ |
| 496 | 3 * (n : ℝ) ^ (1 - ε) * Real.log n)} + |
| 497 | μ.real {ω | ¬((n : ℝ) / 2 ≤ (Finset.univ.filter (fun v => |
| 498 | !ω v ∧ Real.log n ≤ |
| 499 | (G.neighborFinset v ∩ Finset.univ.filter (fun u => ω u)).card)).card)} := |
| 500 | (measureReal_mono h_sub).trans (measureReal_union_le _ _) |
| 501 | linarith |
| 502 | have h_meas : MeasurableSet good_event := MeasurableSet.of_discrete |
| 503 | rw [probReal_compl_eq_one_sub h_meas] at h_bad_total |
| 504 | linarith |
| 505 | -- ======================== EXTRACT WITNESS ======================== |
| 506 | obtain ⟨ω, hω⟩ := nonempty_of_measureReal_ne_zero (ne_of_gt h_good_pos) |
| 507 | obtain ⟨hA_lo, hA_hi, hB_lo⟩ := hω |
| 508 | -- Define A = sampled vertices, B = non-sampled vertices with enough sampled neighbors |
| 509 | let A : Finset V := Finset.univ.filter (fun v => ω v) |
| 510 | let B : Finset V := Finset.univ.filter |
| 511 | (fun v => !ω v ∧ Real.log n ≤ (G.neighborFinset v ∩ A).card) |
| 512 | refine ⟨A, B, ?_, ?_, ?_, ?_, ?_⟩ |
| 513 | · -- Disjoint A B: A ⊆ {ω v = true}, B ⊆ {ω v = false} |
| 514 | simp only [A, B, Finset.disjoint_filter] |
| 515 | intro v _ hv_A hv_B |
| 516 | simp [hv_A] at hv_B |
| 517 | · -- |A| ≥ n^{1-ε} |
| 518 | exact_mod_cast hA_lo |
| 519 | · -- |A| ≤ 3 n^{1-ε} log n |
| 520 | exact_mod_cast hA_hi |
| 521 | · -- |B| ≥ n/2 |
| 522 | exact_mod_cast hB_lo |
| 523 | · -- Every b ∈ B has ≥ log n neighbors in A (by definition of B) |
| 524 | intro b hb |
| 525 | exact_mod_cast ((Finset.mem_filter.mp hb).2).2 |
| 526 | |
| 527 | /-- **Auxiliary (minor model from assignment)**: Given an edge set `E` on `A` and an |
| 528 | assignment `f` from the processed subset `B'` of `B` to `A` — with each `b` adjacent to |
| 529 | `f b` in `G` — and a witness for every edge in `E` (some processed `b` whose assignment is |
| 530 | one endpoint and is adjacent to the other), this constructs a depth-1 `ShallowMinorModel` |
| 531 | of `fromEdgeSet E` in `G`. |
| 532 | |
| 533 | Branch set of `a ∈ A`: `{a.val} ∪ {b.val | b ∈ B', f b = a}`. |
| 534 | Depth 1: each `b` is adjacent to its assigned vertex `f b = a` in `G`. -/ |
| 535 | private noncomputable def minorModelFromAssignment |
| 536 | {V : Type} [DecidableEq V] [Fintype V] |
| 537 | (G : SimpleGraph V) [DecidableRel G.Adj] |
| 538 | (A B' : Finset V) (hAB' : Disjoint A B') |
| 539 | (E : Finset (Sym2 {a : V // a ∈ A})) |
| 540 | (f : {b : V // b ∈ B'} → {a : V // a ∈ A}) |
| 541 | (hf_adj : ∀ b : {b : V // b ∈ B'}, G.Adj (f b).val b.val) |
| 542 | (hE_witness : ∀ (a a' : {a : V // a ∈ A}), |
| 543 | (SimpleGraph.fromEdgeSet (↑E : Set (Sym2 {a : V // a ∈ A}))).Adj a a' → |
| 544 | ∃ b : {b : V // b ∈ B'}, |
| 545 | (f b = a ∧ G.Adj b.val a'.val) ∨ (f b = a' ∧ G.Adj b.val a.val)) : |
| 546 | ShallowMinorModel |
| 547 | (SimpleGraph.fromEdgeSet (↑E : Set (Sym2 {a : V // a ∈ A}))) G 1 where |
| 548 | branchSet a := {v : V | v = a.val ∨ ∃ b : {b : V // b ∈ B'}, f b = a ∧ v = b.val} |
| 549 | center a := a.val |
| 550 | center_mem a := Set.mem_setOf.mpr (Or.inl rfl) |
| 551 | branchDisjoint := by |
| 552 | intro a₁ a₂ ha |
| 553 | apply Set.disjoint_left.mpr |
| 554 | intro v hv₁ hv₂ |
| 555 | simp only [Set.mem_setOf_eq] at hv₁ hv₂ |
| 556 | have hd := Finset.disjoint_left.mp hAB' |
| 557 | rcases hv₁ with rfl | ⟨b, hfb, rfl⟩ <;> rcases hv₂ with h | ⟨b', hfb', h'⟩ |
| 558 | · exact ha (Subtype.ext h) |
| 559 | · exact hd a₁.property (h' ▸ b'.property) |
| 560 | · exact hd a₂.property (by rw [← h]; exact b.property) |
| 561 | · have hbb' : b = b' := Subtype.ext h' |
| 562 | have hfb_eq : f b = a₂ := by rw [hbb']; exact hfb' |
| 563 | exact ha (hfb.symm.trans hfb_eq) |
| 564 | branchRadius := by |
| 565 | intro a v hv |
| 566 | simp only [Set.mem_setOf_eq] at hv |
| 567 | rcases hv with rfl | ⟨b, hfb, rfl⟩ |
| 568 | · exact ⟨SimpleGraph.Walk.nil, SimpleGraph.Walk.IsPath.nil, by simp, |
| 569 | fun w hw => by |
| 570 | simp only [SimpleGraph.Walk.support_nil, List.mem_singleton] at hw |
| 571 | exact hw ▸ Set.mem_setOf.mpr (Or.inl rfl)⟩ |
| 572 | · have hadj : G.Adj a.val b.val := hfb ▸ hf_adj b |
| 573 | refine ⟨hadj.toWalk, SimpleGraph.Walk.IsPath.of_adj hadj, |
| 574 | by simp [SimpleGraph.Adj.toWalk, SimpleGraph.Walk.length_cons], |
| 575 | fun w hw => ?_⟩ |
| 576 | simp only [SimpleGraph.Adj.toWalk, SimpleGraph.Walk.support_cons, |
| 577 | SimpleGraph.Walk.support_nil, List.mem_cons, |
| 578 | List.mem_nil_iff, or_false] at hw |
| 579 | rcases hw with rfl | rfl |
| 580 | · exact Set.mem_setOf.mpr (Or.inl rfl) |
| 581 | · exact Set.mem_setOf.mpr (Or.inr ⟨b, hfb, rfl⟩) |
| 582 | branchEdge := by |
| 583 | intro a₁ a₂ hadj |
| 584 | obtain ⟨b, hb | hb⟩ := hE_witness a₁ a₂ hadj |
| 585 | · exact ⟨b.val, Set.mem_setOf.mpr (Or.inr ⟨b, hb.1, rfl⟩), |
| 586 | a₂.val, Set.mem_setOf.mpr (Or.inl rfl), hb.2⟩ |
| 587 | · exact ⟨a₁.val, Set.mem_setOf.mpr (Or.inl rfl), |
| 588 | b.val, Set.mem_setOf.mpr (Or.inr ⟨b, hb.1, rfl⟩), hb.2.symm⟩ |
| 589 | |
| 590 | /-- Given a depth-1 minor model, a clique `S` in the source graph, and a vertex `b₀` |
| 591 | adjacent in `G` to the center of every element of `S` and not in any branch set, |
| 592 | we get `K_{|S|+1} ≼₁ G`. -/ |
| 593 | private noncomputable def clique_extension_minor |
| 594 | {V W : Type} [DecidableEq V] [DecidableEq W] |
| 595 | {H : SimpleGraph W} {G : SimpleGraph V} |
| 596 | (M : ShallowMinorModel H G 1) |
| 597 | (S : Finset W) |
| 598 | (hS_clique : ∀ a₁ ∈ S, ∀ a₂ ∈ S, a₁ ≠ a₂ → H.Adj a₁ a₂) |
| 599 | (b₀ : V) |
| 600 | (hb₀_adj : ∀ a ∈ S, G.Adj b₀ (M.center a)) |
| 601 | (hb₀_not_branch : ∀ w : W, b₀ ∉ M.branchSet w) : |
| 602 | ShallowMinorModel (SimpleGraph.completeGraph (Fin (S.card + 1))) G 1 := |
| 603 | let φ := S.equivFin |
| 604 | let toW : Fin S.card → W := fun i => (φ.symm i).val |
| 605 | have htoW_inj : Function.Injective toW := fun i j h => |
| 606 | φ.symm.injective (Subtype.val_injective h) |
| 607 | have htoW_mem : ∀ i, toW i ∈ S := fun i => (φ.symm i).property |
| 608 | { branchSet := fun i => |
| 609 | if h : (i : ℕ) < S.card then M.branchSet (toW ⟨i, h⟩) else {b₀} |
| 610 | center := fun i => |
| 611 | if h : (i : ℕ) < S.card then M.center (toW ⟨i, h⟩) else b₀ |
| 612 | center_mem := by |
| 613 | intro i; split |
| 614 | · exact M.center_mem _ |
| 615 | · exact rfl |
| 616 | branchDisjoint := by |
| 617 | intro i j hij |
| 618 | by_cases hi : (i : ℕ) < S.card <;> by_cases hj : (j : ℕ) < S.card |
| 619 | · rw [dif_pos hi, dif_pos hj] |
| 620 | exact M.branchDisjoint _ _ (fun heq => hij (Fin.ext (by |
| 621 | exact_mod_cast congrArg Fin.val (htoW_inj heq)))) |
| 622 | · rw [dif_pos hi, dif_neg hj] |
| 623 | exact Set.disjoint_singleton_right.mpr (hb₀_not_branch _) |
| 624 | · rw [dif_neg hi, dif_pos hj] |
| 625 | exact Set.disjoint_singleton_left.mpr (hb₀_not_branch _) |
| 626 | · exact absurd (Fin.ext (by omega)) hij |
| 627 | branchRadius := by |
| 628 | intro i x hx |
| 629 | by_cases h : (i : ℕ) < S.card |
| 630 | · rw [dif_pos h] at hx; rw [dif_pos h]; rw [dif_pos h] |
| 631 | exact M.branchRadius _ x hx |
| 632 | · rw [dif_neg h] at hx; rw [dif_neg h]; rw [dif_neg h] |
| 633 | rw [Set.mem_singleton_iff.mp hx] |
| 634 | exact ⟨SimpleGraph.Walk.nil, SimpleGraph.Walk.IsPath.nil, by norm_num, |
| 635 | fun w hw => by |
| 636 | simp only [SimpleGraph.Walk.support_nil, List.mem_singleton] at hw |
| 637 | exact hw⟩ |
| 638 | branchEdge := by |
| 639 | intro i j hij |
| 640 | simp only [SimpleGraph.top_adj] at hij |
| 641 | by_cases hi : (i : ℕ) < S.card <;> by_cases hj : (j : ℕ) < S.card |
| 642 | · rw [dif_pos hi, dif_pos hj] |
| 643 | exact M.branchEdge _ _ (hS_clique _ (htoW_mem _) _ (htoW_mem _) |
| 644 | (fun heq => hij (Fin.ext (by exact_mod_cast congrArg Fin.val (htoW_inj heq))))) |
| 645 | · rw [dif_pos hi, dif_neg hj] |
| 646 | exact ⟨M.center _, M.center_mem _, b₀, rfl, (hb₀_adj _ (htoW_mem _)).symm⟩ |
| 647 | · rw [dif_neg hi, dif_pos hj] |
| 648 | exact ⟨b₀, rfl, M.center _, M.center_mem _, hb₀_adj _ (htoW_mem _)⟩ |
| 649 | · exact absurd (Fin.ext (by omega)) hij } |
| 650 | |
| 651 | /-- **Step 2 (greedy edges or clique)**: Core induction — either find `K_{t+1} ≼₁ G` |
| 652 | for `t ≥ log n`, or find an edge set `E` with `|B| ≤ |E|`, an assignment `f : B → A` |
| 653 | with `G.Adj (f b) b`, and witnesses for the minor-model construction. -/ |
| 654 | private lemma greedy_edges_or_clique |
| 655 | {V : Type} [DecidableEq V] [Fintype V] |
| 656 | (G : SimpleGraph V) [DecidableRel G.Adj] |
| 657 | (A B : Finset V) (hAB : Disjoint A B) |
| 658 | (hB_nbrs : ∀ b ∈ B, log ↑(Fintype.card V) ≤ ↑(G.neighborFinset b ∩ A).card) : |
| 659 | (∃ t : ℕ, log ↑(Fintype.card V) ≤ ↑t ∧ |
| 660 | IsShallowMinor (SimpleGraph.completeGraph (Fin (t + 1))) G 1) ∨ |
| 661 | (∃ (E : Finset (Sym2 {a : V // a ∈ A})) |
| 662 | (f : {b : V // b ∈ B} → {a : V // a ∈ A}), |
| 663 | B.card ≤ E.card ∧ |
| 664 | (∀ e ∈ E, ¬e.IsDiag) ∧ |
| 665 | (∀ b : {b : V // b ∈ B}, G.Adj (f b).val b.val) ∧ |
| 666 | ∀ (a a' : {a : V // a ∈ A}), |
| 667 | (SimpleGraph.fromEdgeSet (↑E : Set (Sym2 {a : V // a ∈ A}))).Adj a a' → |
| 668 | ∃ b : {b : V // b ∈ B}, |
| 669 | (f b = a ∧ G.Adj b.val a'.val) ∨ (f b = a' ∧ G.Adj b.val a.val)) := by |
| 670 | classical |
| 671 | refine Finset.induction_on B ?_ ?_ hAB hB_nbrs |
| 672 | · intro hAB_empty hB_empty |
| 673 | refine Or.inr ?_ |
| 674 | refine ⟨∅, (fun b => nomatch b.property), ?_⟩ |
| 675 | simp |
| 676 | · intro b₀ B₀ hb₀ ih hAB_ins hB_ins |
| 677 | have hAB₀ : Disjoint A B₀ := by |
| 678 | rw [Finset.disjoint_left] at hAB_ins ⊢ |
| 679 | intro a haA haB₀ |
| 680 | exact hAB_ins haA (Finset.mem_insert_of_mem haB₀) |
| 681 | have hB₀_nbrs : ∀ b ∈ B₀, log ↑(Fintype.card V) ≤ ↑(G.neighborFinset b ∩ A).card := by |
| 682 | intro b hb |
| 683 | exact hB_ins b (Finset.mem_insert_of_mem hb) |
| 684 | rcases ih hAB₀ hB₀_nbrs with |
| 685 | hclique | ⟨E₀, f₀, hcard₀, hnd₀, hf₀_adj, hwitness₀⟩ |
| 686 | · exact Or.inl hclique |
| 687 | · let S : Finset {a : V // a ∈ A} := |
| 688 | (G.neighborFinset b₀ ∩ A).subtype (fun a => a ∈ A) |
| 689 | have hS_ge : log ↑(Fintype.card V) ≤ ↑S.card := by |
| 690 | have hS_card : S.card = (G.neighborFinset b₀ ∩ A).card := by |
| 691 | unfold S |
| 692 | rw [Finset.card_subtype] |
| 693 | apply congrArg Finset.card |
| 694 | ext a |
| 695 | simp [Finset.mem_inter] |
| 696 | rw [hS_card] |
| 697 | exact hB_ins b₀ (Finset.mem_insert_self b₀ B₀) |
| 698 | by_cases hnew : |
| 699 | ∃ a₁ ∈ S, ∃ a₂ ∈ S, a₁ ≠ a₂ ∧ s(a₁, a₂) ∉ E₀ |
| 700 | · rcases hnew with ⟨a₁, ha₁S, a₂, ha₂S, ha12, hnotE₀⟩ |
| 701 | let E : Finset (Sym2 {a : V // a ∈ A}) := insert (s(a₁, a₂)) E₀ |
| 702 | let f : {b : V // b ∈ insert b₀ B₀} → {a : V // a ∈ A} := fun b => |
| 703 | if h : b.val = b₀ then a₁ else f₀ ⟨b.val, (Finset.mem_insert.mp b.property).resolve_left h⟩ |
| 704 | refine Or.inr ⟨E, f, ?_, ?_, ?_, ?_⟩ |
| 705 | · calc |
| 706 | (insert b₀ B₀).card = B₀.card + 1 := by simp [hb₀] |
| 707 | _ ≤ E₀.card + 1 := Nat.succ_le_succ hcard₀ |
| 708 | _ = E.card := by simp [E, hnotE₀] |
| 709 | · intro e he |
| 710 | rcases Finset.mem_insert.mp he with rfl | he₀ |
| 711 | · simpa [Sym2.mk_isDiag_iff] using ha12 |
| 712 | · exact hnd₀ e he₀ |
| 713 | · intro b |
| 714 | by_cases hb : b.val = b₀ |
| 715 | · rw [show f b = a₁ by simp [f, hb]] |
| 716 | have ha₁_mem : a₁.val ∈ G.neighborFinset b₀ ∩ A := by |
| 717 | simpa [S] using ha₁S |
| 718 | simpa [hb] using ((G.mem_neighborFinset b₀ a₁.val).mp (Finset.mem_inter.mp ha₁_mem).1).symm |
| 719 | · rw [show f b = f₀ ⟨b.val, (Finset.mem_insert.mp b.property).resolve_left hb⟩ by |
| 720 | simp [f, hb]] |
| 721 | exact hf₀_adj ⟨b.val, (Finset.mem_insert.mp b.property).resolve_left hb⟩ |
| 722 | · intro a a' hadj |
| 723 | rw [SimpleGraph.fromEdgeSet_adj] at hadj |
| 724 | rcases Finset.mem_insert.mp hadj.1 with hE | hE |
| 725 | · have hs : s(a, a') = s(a₁, a₂) := hE |
| 726 | let b : {b : V // b ∈ insert b₀ B₀} := ⟨b₀, Finset.mem_insert_self b₀ B₀⟩ |
| 727 | have ha₁_mem : a₁.val ∈ G.neighborFinset b₀ ∩ A := by |
| 728 | simpa [S] using ha₁S |
| 729 | have ha₂_mem : a₂.val ∈ G.neighborFinset b₀ ∩ A := by |
| 730 | simpa [S] using ha₂S |
| 731 | have ha₁_adj : G.Adj b₀ a₁.val := |
| 732 | (G.mem_neighborFinset b₀ a₁.val).mp (Finset.mem_inter.mp ha₁_mem).1 |
| 733 | have ha₂_adj : G.Adj b₀ a₂.val := |
| 734 | (G.mem_neighborFinset b₀ a₂.val).mp (Finset.mem_inter.mp ha₂_mem).1 |
| 735 | rcases Sym2.eq_iff.mp hs with h | h |
| 736 | · refine ⟨b, Or.inl ?_⟩ |
| 737 | rcases h with ⟨rfl, rfl⟩ |
| 738 | exact ⟨by simp [b, f], ha₂_adj⟩ |
| 739 | · refine ⟨b, Or.inr ?_⟩ |
| 740 | rcases h with ⟨rfl, rfl⟩ |
| 741 | exact ⟨by simp [b, f], ha₂_adj⟩ |
| 742 | · obtain ⟨b, hb | hb⟩ := hwitness₀ a a' ((SimpleGraph.fromEdgeSet_adj _).2 ⟨hE, hadj.2⟩) |
| 743 | · refine ⟨⟨b.val, Finset.mem_insert_of_mem b.property⟩, Or.inl ?_⟩ |
| 744 | refine ⟨?_, hb.2⟩ |
| 745 | have hbne : b.val ≠ b₀ := by |
| 746 | intro hEq |
| 747 | exact hb₀ (hEq ▸ b.property) |
| 748 | simp [f, hbne, hb.1] |
| 749 | · refine ⟨⟨b.val, Finset.mem_insert_of_mem b.property⟩, Or.inr ?_⟩ |
| 750 | refine ⟨?_, hb.2⟩ |
| 751 | have hbne : b.val ≠ b₀ := by |
| 752 | intro hEq |
| 753 | exact hb₀ (hEq ▸ b.property) |
| 754 | simp [f, hbne, hb.1] |
| 755 | · have hall : |
| 756 | ∀ a₁ ∈ S, ∀ a₂ ∈ S, a₁ ≠ a₂ → s(a₁, a₂) ∈ E₀ := by |
| 757 | intro a₁ ha₁S a₂ ha₂S ha12 |
| 758 | by_contra hnotmem |
| 759 | exact hnew ⟨a₁, ha₁S, a₂, ha₂S, ha12, hnotmem⟩ |
| 760 | let M₀ := minorModelFromAssignment G A B₀ hAB₀ E₀ f₀ hf₀_adj hwitness₀ |
| 761 | have hS_clique : |
| 762 | ∀ a₁ ∈ S, ∀ a₂ ∈ S, a₁ ≠ a₂ → |
| 763 | (SimpleGraph.fromEdgeSet (↑E₀ : Set (Sym2 {a : V // a ∈ A}))).Adj a₁ a₂ := by |
| 764 | intro a₁ ha₁S a₂ ha₂S ha12 |
| 765 | rw [SimpleGraph.fromEdgeSet_adj] |
| 766 | exact ⟨hall a₁ ha₁S a₂ ha₂S ha12, ha12⟩ |
| 767 | have hb₀_adj : |
| 768 | ∀ a ∈ S, G.Adj b₀ (M₀.center a) := by |
| 769 | intro a haS |
| 770 | change G.Adj b₀ a.val |
| 771 | have ha_mem : a.val ∈ G.neighborFinset b₀ ∩ A := by |
| 772 | simpa [S] using haS |
| 773 | exact (G.mem_neighborFinset b₀ a.val).mp (Finset.mem_inter.mp ha_mem).1 |
| 774 | have hb₀_not_branch : |
| 775 | ∀ w : {a : V // a ∈ A}, b₀ ∉ M₀.branchSet w := by |
| 776 | intro w |
| 777 | change b₀ ∉ {v : V | v = w.val ∨ ∃ b : {b : V // b ∈ B₀}, f₀ b = w ∧ v = b.val} |
| 778 | intro hb |
| 779 | rcases hb with hEq | ⟨b, -, hbval⟩ |
| 780 | · rw [Finset.disjoint_left] at hAB_ins |
| 781 | exact (hAB_ins w.property) (hEq ▸ Finset.mem_insert_self b₀ B₀) |
| 782 | · exact hb₀ (hbval ▸ b.property) |
| 783 | exact Or.inl ⟨S.card, hS_ge, ⟨clique_extension_minor M₀ S hS_clique b₀ hb₀_adj hb₀_not_branch⟩⟩ |
| 784 | |
| 785 | /-- **Step 2 (greedy construction)**: Given a "good pair" (A, B) in G, the greedy |
| 786 | process either finds a clique minor K_{t+1} for t ≥ log n, or builds a depth-1 |
| 787 | minor G' on vertex set {a : V // a ∈ A} with ≥ |B| edges. |
| 788 | |
| 789 | Uses `greedy_edges_or_clique` for the inductive construction and |
| 790 | `minorModelFromAssignment` to build the minor model from the assignment. -/ |
| 791 | private lemma greedy_densify |
| 792 | {V : Type} [DecidableEq V] [Fintype V] |
| 793 | (G : SimpleGraph V) [DecidableRel G.Adj] |
| 794 | (A B : Finset V) (hAB : Disjoint A B) |
| 795 | (hB_nbrs : ∀ b ∈ B, log ↑(Fintype.card V) ≤ ↑(G.neighborFinset b ∩ A).card) : |
| 796 | (∃ t : ℕ, log ↑(Fintype.card V) ≤ ↑t ∧ |
| 797 | IsShallowMinor (SimpleGraph.completeGraph (Fin (t + 1))) G 1) ∨ |
| 798 | (∃ (G' : SimpleGraph {a : V // a ∈ A}) (_ : DecidableRel G'.Adj), |
| 799 | IsShallowMinor G' G 1 ∧ |
| 800 | (↑B.card : ℝ) ≤ ↑G'.edgeFinset.card) := by |
| 801 | rcases greedy_edges_or_clique G A B hAB hB_nbrs with |
| 802 | clique | ⟨E, f, hcard, hnd, hf_adj, hwitness⟩ |
| 803 | · exact Or.inl clique |
| 804 | · right |
| 805 | letI : DecidableRel (SimpleGraph.fromEdgeSet (↑E : Set (Sym2 {a : V // a ∈ A})) : |
| 806 | SimpleGraph {a : V // a ∈ A}).Adj := |
| 807 | fun a a' => by rw [SimpleGraph.fromEdgeSet_adj]; exact inferInstance |
| 808 | refine ⟨SimpleGraph.fromEdgeSet (↑E : Set _), ‹_›, |
| 809 | ⟨minorModelFromAssignment G A B hAB E f hf_adj hwitness⟩, ?_⟩ |
| 810 | simp only [Nat.cast_le] |
| 811 | apply hcard.trans |
| 812 | apply Finset.card_le_card |
| 813 | intro e he |
| 814 | simp only [SimpleGraph.mem_edgeFinset, SimpleGraph.edgeSet_fromEdgeSet, |
| 815 | Set.mem_diff, Finset.mem_coe, Sym2.mem_diagSet] |
| 816 | exact ⟨he, hnd e he⟩ |
| 817 | |
| 818 | /-- **Step 3 (arithmetic)**: For large n, if n' ≤ 3n^{1-ε} log n then |
| 819 | (n')^{1+ε+ε²} ≤ n/2. |
| 820 | |
| 821 | Proof: |
| 822 | (n')^{1+ε+ε²} ≤ (3n^{1-ε} log n)^{1+ε+ε²} |
| 823 | = 3^{1+ε+ε²} · n^{(1-ε)(1+ε+ε²)} · (log n)^{1+ε+ε²} |
| 824 | = 3^{1+ε+ε²} · n^{1-ε³} · (log n)^{1+ε+ε²} [since (1-ε)(1+ε+ε²) = 1-ε³] |
| 825 | By isLittleO_log_rpow_rpow_atTop (ε³ > 0): eventually |
| 826 | (log n)^{1+ε+ε²} ≤ n^{ε³} / (2 · 3^{1+ε+ε²}) |
| 827 | So the bound is ≤ 3^{1+ε+ε²} · n^{1-ε³} · n^{ε³} / (2·3^{1+ε+ε²}) = n/2. -/ |
| 828 | private lemma edge_density_bound (ε : ℝ) (hε_pos : 0 < ε) : |
| 829 | ∃ M : ℕ, ∀ (n n' : ℕ), M ≤ n → |
| 830 | (↑n' : ℝ) ≤ 3 * (↑n : ℝ) ^ (1 - ε) * Real.log ↑n → |
| 831 | (↑n' : ℝ) ^ (1 + ε + ε ^ 2) ≤ (↑n : ℝ) / 2 := by |
| 832 | have hε3 : (0 : ℝ) < ε ^ 3 := by positivity |
| 833 | -- (log x)^(1+ε+ε²) =o[atTop] x^(ε³) since ε³ > 0 |
| 834 | have hiso := isLittleO_log_rpow_rpow_atTop (1 + ε + ε ^ 2) hε3 |
| 835 | -- Extract: eventually |log x|^(...) ≤ (2·3^{...})⁻¹ · x^(ε³) |
| 836 | have hc_pos : (0 : ℝ) < (2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ := by positivity |
| 837 | have hbnd_nat : ∀ᶠ m : ℕ in atTop, |
| 838 | ‖Real.log (↑m : ℝ) ^ (1 + ε + ε ^ 2)‖ ≤ |
| 839 | (2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * ‖(↑m : ℝ) ^ ε ^ 3‖ := |
| 840 | tendsto_natCast_atTop_atTop.eventually (hiso.bound hc_pos) |
| 841 | rw [Filter.eventually_atTop] at hbnd_nat |
| 842 | obtain ⟨M₀, hM₀⟩ := hbnd_nat |
| 843 | -- M = max M₀ 3 ensures n ≥ 3 so log n ≥ 0 |
| 844 | refine ⟨max M₀ 3, ?_⟩ |
| 845 | intro n n' hn_ge hn'_le |
| 846 | have hM₀n : M₀ ≤ n := (Nat.le_max_left M₀ 3).trans hn_ge |
| 847 | have hn_ge3 : (3 : ℕ) ≤ n := (Nat.le_max_right M₀ 3).trans hn_ge |
| 848 | have hn_pos : (0 : ℝ) < (↑n : ℝ) := by exact_mod_cast show 0 < n by omega |
| 849 | have hnn : (0 : ℝ) ≤ (↑n : ℝ) := le_of_lt hn_pos |
| 850 | have hlog_nn : (0 : ℝ) ≤ Real.log (↑n : ℝ) := |
| 851 | Real.log_nonneg (by norm_cast; linarith) |
| 852 | -- Trivial when n' = 0: (0:ℝ)^(1+ε+ε²) = 0 ≤ n/2 |
| 853 | rcases Nat.eq_zero_or_pos n' with rfl | hn'_pos |
| 854 | · simp only [Nat.cast_zero, |
| 855 | Real.zero_rpow (show (1 + ε + ε ^ 2 : ℝ) ≠ 0 by positivity)] |
| 856 | positivity |
| 857 | -- Main case: n' > 0 |
| 858 | have hn'_pos_r : (0 : ℝ) < (↑n' : ℝ) := Nat.cast_pos.mpr hn'_pos |
| 859 | -- Step 1: (n')^{1+ε+ε²} ≤ (3·n^{1-ε}·log n)^{1+ε+ε²} |
| 860 | have hstep1 : (↑n' : ℝ) ^ (1 + ε + ε ^ 2) ≤ |
| 861 | (3 * (↑n : ℝ) ^ (1 - ε) * Real.log (↑n : ℝ)) ^ (1 + ε + ε ^ 2) := |
| 862 | Real.rpow_le_rpow (by positivity) hn'_le (by positivity) |
| 863 | -- Step 2: expand (3·n^{1-ε}·log n)^{1+ε+ε²} = 3^{...}·n^{1-ε³}·(log n)^{...} |
| 864 | have hstep2 : (3 * (↑n : ℝ) ^ (1 - ε) * Real.log (↑n : ℝ)) ^ (1 + ε + ε ^ 2) = |
| 865 | (3 : ℝ) ^ (1 + ε + ε ^ 2) * (↑n : ℝ) ^ (1 - ε ^ 3) * |
| 866 | Real.log (↑n : ℝ) ^ (1 + ε + ε ^ 2) := by |
| 867 | rw [Real.mul_rpow (by positivity) hlog_nn, |
| 868 | Real.mul_rpow (by norm_num : (0 : ℝ) ≤ 3) (Real.rpow_nonneg hnn _), |
| 869 | ← Real.rpow_mul hnn, show (1 - ε) * (1 + ε + ε ^ 2) = 1 - ε ^ 3 from by ring] |
| 870 | -- Step 3: log bound from hM₀: (log n)^{...} ≤ (2·3^{...})⁻¹ · n^{ε³} |
| 871 | have hlog_bnd : Real.log (↑n : ℝ) ^ (1 + ε + ε ^ 2) ≤ |
| 872 | (2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * (↑n : ℝ) ^ ε ^ 3 := by |
| 873 | have h := hM₀ n hM₀n |
| 874 | rwa [Real.norm_of_nonneg (Real.rpow_nonneg hlog_nn _), |
| 875 | Real.norm_of_nonneg (Real.rpow_nonneg hnn _)] at h |
| 876 | -- Step 4: algebraic simplification 3^r · n^{1-ε³} · (2·3^r)⁻¹ · n^{ε³} = n/2 |
| 877 | have hstep4 : (3 : ℝ) ^ (1 + ε + ε ^ 2) * (↑n : ℝ) ^ (1 - ε ^ 3) * |
| 878 | ((2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * (↑n : ℝ) ^ ε ^ 3) = (↑n : ℝ) / 2 := by |
| 879 | have h3pos : (0 : ℝ) < (3 : ℝ) ^ (1 + ε + ε ^ 2) := by positivity |
| 880 | rw [show (3 : ℝ) ^ (1 + ε + ε ^ 2) * (↑n : ℝ) ^ (1 - ε ^ 3) * |
| 881 | ((2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * (↑n : ℝ) ^ ε ^ 3) = |
| 882 | (3 : ℝ) ^ (1 + ε + ε ^ 2) * (2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * |
| 883 | ((↑n : ℝ) ^ (1 - ε ^ 3) * (↑n : ℝ) ^ ε ^ 3) from by ring] |
| 884 | rw [← Real.rpow_add hn_pos, show (1 - ε ^ 3) + ε ^ 3 = 1 from by ring, Real.rpow_one] |
| 885 | have h_half : (3 : ℝ) ^ (1 + ε + ε ^ 2) * (2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ = 1 / 2 := by |
| 886 | rw [mul_inv, mul_comm (2 : ℝ)⁻¹, ← mul_assoc, |
| 887 | mul_inv_cancel₀ h3pos.ne', one_mul, inv_eq_one_div] |
| 888 | rw [h_half]; ring |
| 889 | -- Chain the steps |
| 890 | calc (↑n' : ℝ) ^ (1 + ε + ε ^ 2) |
| 891 | ≤ (3 * (↑n : ℝ) ^ (1 - ε) * Real.log (↑n : ℝ)) ^ (1 + ε + ε ^ 2) := hstep1 |
| 892 | _ = (3 : ℝ) ^ (1 + ε + ε ^ 2) * (↑n : ℝ) ^ (1 - ε ^ 3) * |
| 893 | Real.log (↑n : ℝ) ^ (1 + ε + ε ^ 2) := hstep2 |
| 894 | _ ≤ (3 : ℝ) ^ (1 + ε + ε ^ 2) * (↑n : ℝ) ^ (1 - ε ^ 3) * |
| 895 | ((2 * (3 : ℝ) ^ (1 + ε + ε ^ 2))⁻¹ * (↑n : ℝ) ^ ε ^ 3) := by |
| 896 | gcongr |
| 897 | _ = (↑n : ℝ) / 2 := hstep4 |
| 898 | |
| 899 | /-- Lemma 3.4/ch1: Densification lemma. -/ |
| 900 | theorem densification (ε : ℝ) (hε_pos : 0 < ε) (hε_le : ε ≤ 2 / 3) : |
| 901 | ∃ M : ℕ, ∀ {V : Type} [DecidableEq V] [Fintype V] |
| 902 | (G : SimpleGraph V) [DecidableRel G.Adj], |
| 903 | M ≤ Fintype.card V → |
| 904 | (∀ v : V, (Fintype.card V : ℝ) ^ ε ≤ ↑(G.degree v)) → |
| 905 | (∃ t : ℕ, Real.log ↑(Fintype.card V) ≤ ↑t ∧ |
| 906 | IsShallowMinor (SimpleGraph.completeGraph (Fin (t + 1))) G 1) ∨ |
| 907 | (∃ (W : Type) (_ : DecidableEq W) (_ : Fintype W) |
| 908 | (G' : SimpleGraph W) (_ : DecidableRel G'.Adj), |
| 909 | IsShallowMinor G' G 1 ∧ |
| 910 | (Fintype.card V : ℝ) ^ (1 - ε) ≤ ↑(Fintype.card W) ∧ |
| 911 | (Fintype.card W : ℝ) ^ (1 + ε + ε ^ 2) ≤ ↑(G'.edgeFinset.card)) := by |
| 912 | obtain ⟨M₁, hM₁⟩ := exists_good_pair ε hε_pos hε_le |
| 913 | obtain ⟨M₂, hM₂⟩ := edge_density_bound ε hε_pos |
| 914 | refine ⟨max M₁ M₂, ?_⟩ |
| 915 | intro V _ _ G _ hn_ge hmin |
| 916 | have hM₁n : M₁ ≤ Fintype.card V := (Nat.le_max_left M₁ M₂).trans hn_ge |
| 917 | have hM₂n : M₂ ≤ Fintype.card V := (Nat.le_max_right M₁ M₂).trans hn_ge |
| 918 | obtain ⟨A, B, hAB, hA_lower, hA_upper, hB_lower, hB_nbrs⟩ := hM₁ G hM₁n hmin |
| 919 | rcases greedy_densify G A B hAB hB_nbrs with |
| 920 | ⟨t, ht_log, ht_minor⟩ | ⟨G', hG'_dec, hG'_minor, hG'_edges⟩ |
| 921 | · exact Or.inl ⟨t, ht_log, ht_minor⟩ |
| 922 | · right |
| 923 | refine ⟨{a : V // a ∈ A}, inferInstance, inferInstance, G', hG'_dec, |
| 924 | hG'_minor, ?_, ?_⟩ |
| 925 | · -- (Fintype.card V)^{1-ε} ≤ Fintype.card W = A.card |
| 926 | simp only [Fintype.card_coe] |
| 927 | exact_mod_cast hA_lower |
| 928 | · -- (Fintype.card W)^{1+ε+ε²} ≤ G'.edgeFinset.card |
| 929 | simp only [Fintype.card_coe] |
| 930 | have h_arith : (↑A.card : ℝ) ^ (1 + ε + ε ^ 2) ≤ (↑(Fintype.card V) : ℝ) / 2 := |
| 931 | hM₂ (Fintype.card V) A.card hM₂n (by exact_mod_cast hA_upper) |
| 932 | calc (↑A.card : ℝ) ^ (1 + ε + ε ^ 2) |
| 933 | ≤ (↑(Fintype.card V) : ℝ) / 2 := h_arith |
| 934 | _ ≤ ↑B.card := hB_lower |
| 935 | _ ≤ ↑G'.edgeFinset.card := hG'_edges |
| 936 | |
| 937 | end Catalog.Sparsity.Densification |
| 938 |