Catalog/VC/ShortEdgeLemma/Full.lean
| 1 | import Catalog.VC.DualShatterFunction.Full |
| 2 | import Catalog.VC.PackingLemma.Full |
| 3 | import Catalog.VC.ShatterFunction.Full |
| 4 | import Mathlib.Analysis.SpecialFunctions.Pow.Real |
| 5 | import Mathlib.Data.Finset.Card |
| 6 | |
| 7 | namespace Catalog.VC.ShortEdgeLemma |
| 8 | |
| 9 | universe u |
| 10 | |
| 11 | section |
| 12 | |
| 13 | variable {α : Type*} [DecidableEq α] |
| 14 | |
| 15 | /-- The crossing number of an edge `{x, y}` by a subfamily `Q`: the number |
| 16 | of sets in `Q` that contain exactly one of `x, y`. -/ |
| 17 | abbrev crossingNumber (Q : Finset (Finset α)) (x y : α) : ℕ := |
| 18 | (Q.filter (fun S => (x ∈ S ∧ y ∉ S) ∨ (x ∉ S ∧ y ∈ S))).card |
| 19 | |
| 20 | private lemma symmDiff_atomMap_card_eq_crossingNumber |
| 21 | (Q : Finset (Finset α)) (x y : α) : |
| 22 | (symmDiff (Catalog.VC.DualShatterFunction.atomMap Q x) |
| 23 | (Catalog.VC.DualShatterFunction.atomMap Q y)).card = crossingNumber Q x y := by |
| 24 | unfold Catalog.VC.DualShatterFunction.atomMap crossingNumber |
| 25 | congr |
| 26 | ext S |
| 27 | by_cases hS : S ∈ Q |
| 28 | · simp [hS, Finset.mem_symmDiff, and_comm] |
| 29 | · simp [hS, Finset.mem_symmDiff] |
| 30 | |
| 31 | private lemma exists_atomMap_collision [Fintype α] (Q : Finset (Finset α)) |
| 32 | (hcard : (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card < Fintype.card α) : |
| 33 | ∃ x y : α, x ≠ y ∧ |
| 34 | Catalog.VC.DualShatterFunction.atomMap Q x = Catalog.VC.DualShatterFunction.atomMap Q y := by |
| 35 | simpa using |
| 36 | (Finset.exists_ne_map_eq_of_card_image_lt (s := (Finset.univ : Finset α)) |
| 37 | (f := Catalog.VC.DualShatterFunction.atomMap Q) hcard) |
| 38 | |
| 39 | private lemma crossingNumber_eq_zero_of_atomMap_eq |
| 40 | (Q : Finset (Finset α)) {x y : α} |
| 41 | (hxy : Catalog.VC.DualShatterFunction.atomMap Q x = Catalog.VC.DualShatterFunction.atomMap Q y) : |
| 42 | crossingNumber Q x y = 0 := by |
| 43 | rw [← symmDiff_atomMap_card_eq_crossingNumber] |
| 44 | rw [hxy] |
| 45 | simp |
| 46 | |
| 47 | private def atomMapOn (Q : Finset (Finset α)) (x : α) : |
| 48 | Finset {S // S ∈ Q} := |
| 49 | Q.attach.filter (fun S => x ∈ S.1) |
| 50 | |
| 51 | private lemma image_val_atomMapOn (Q : Finset (Finset α)) (x : α) : |
| 52 | (atomMapOn Q x).image Subtype.val = Catalog.VC.DualShatterFunction.atomMap Q x := by |
| 53 | ext S |
| 54 | simp [atomMapOn, Catalog.VC.DualShatterFunction.atomMap, and_comm] |
| 55 | |
| 56 | private lemma atomMapOn_eq_iff (Q : Finset (Finset α)) {x y : α} : |
| 57 | atomMapOn Q x = atomMapOn Q y ↔ |
| 58 | Catalog.VC.DualShatterFunction.atomMap Q x = Catalog.VC.DualShatterFunction.atomMap Q y := by |
| 59 | constructor |
| 60 | · intro h |
| 61 | simpa [image_val_atomMapOn] using congrArg (fun T => T.image Subtype.val) h |
| 62 | · intro h |
| 63 | ext S |
| 64 | have hmem := congrArg (fun T => S.1 ∈ T) h |
| 65 | simp [Catalog.VC.DualShatterFunction.atomMap] at hmem |
| 66 | simpa [atomMapOn] using hmem |
| 67 | |
| 68 | private lemma atomMapOn_inter_image_val |
| 69 | (Q : Finset (Finset α)) (Y : Finset {S // S ∈ Q}) (x : α) : |
| 70 | ((atomMapOn Q x ∩ Y).image Subtype.val) = |
| 71 | Catalog.VC.DualShatterFunction.atomMap (Y.image Subtype.val) x := by |
| 72 | ext S |
| 73 | simp [atomMapOn, Catalog.VC.DualShatterFunction.atomMap, and_comm] |
| 74 | |
| 75 | private lemma image_val_injective (Q : Finset (Finset α)) : |
| 76 | Function.Injective (fun T : Finset {S // S ∈ Q} => T.image Subtype.val) := by |
| 77 | intro T₁ T₂ h |
| 78 | ext S |
| 79 | constructor |
| 80 | · intro hS |
| 81 | have hmem₁ : S.1 ∈ T₁.image Subtype.val := Finset.mem_image.mpr ⟨S, hS, rfl⟩ |
| 82 | have hmem : S.1 ∈ T₂.image Subtype.val := by simpa [h] using hmem₁ |
| 83 | rcases Finset.mem_image.mp hmem with ⟨S', hS', hEq⟩ |
| 84 | exact Subtype.val_injective hEq ▸ hS' |
| 85 | · intro hS |
| 86 | have hmem₂ : S.1 ∈ T₂.image Subtype.val := Finset.mem_image.mpr ⟨S, hS, rfl⟩ |
| 87 | have hmem : S.1 ∈ T₁.image Subtype.val := by simpa [h] using hmem₂ |
| 88 | rcases Finset.mem_image.mp hmem with ⟨S', hS', hEq⟩ |
| 89 | exact Subtype.val_injective hEq ▸ hS' |
| 90 | |
| 91 | private lemma dualFamilyOn_card_eq [Fintype α] (Q : Finset (Finset α)) : |
| 92 | (Finset.univ.image (atomMapOn Q)).card = |
| 93 | (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card := by |
| 94 | let e : Finset {S // S ∈ Q} → Finset (Finset α) := fun T => T.image Subtype.val |
| 95 | have hEq : |
| 96 | (Finset.univ.image (atomMapOn Q)).image e = |
| 97 | Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q) := by |
| 98 | ext T |
| 99 | simp only [e, Finset.mem_image] |
| 100 | constructor |
| 101 | · rintro ⟨U, hU, rfl⟩ |
| 102 | rcases hU with ⟨x, -, rfl⟩ |
| 103 | exact ⟨x, Finset.mem_univ _, (image_val_atomMapOn Q x).symm⟩ |
| 104 | · rintro ⟨x, -, hT⟩ |
| 105 | exact ⟨atomMapOn Q x, ⟨x, Finset.mem_univ _, rfl⟩, by simpa [e] using (image_val_atomMapOn Q x).trans hT⟩ |
| 106 | calc |
| 107 | (Finset.univ.image (atomMapOn Q)).card |
| 108 | = ((Finset.univ.image (atomMapOn Q)).image e).card := by |
| 109 | symm |
| 110 | exact Finset.card_image_of_injective _ (image_val_injective Q) |
| 111 | _ = (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card := by rw [hEq] |
| 112 | |
| 113 | private lemma atomMapOn_sep_card_eq_crossingNumber |
| 114 | (Q : Finset (Finset α)) (x y : α) : |
| 115 | ((atomMapOn Q x \ atomMapOn Q y) ∪ (atomMapOn Q y \ atomMapOn Q x)).card = |
| 116 | crossingNumber Q x y := by |
| 117 | have hEq : |
| 118 | (((atomMapOn Q x \ atomMapOn Q y) ∪ (atomMapOn Q y \ atomMapOn Q x)).image Subtype.val) = |
| 119 | symmDiff (Catalog.VC.DualShatterFunction.atomMap Q x) (Catalog.VC.DualShatterFunction.atomMap Q y) := by |
| 120 | ext S |
| 121 | by_cases hS : S ∈ Q |
| 122 | · simp [hS, atomMapOn, Catalog.VC.DualShatterFunction.atomMap, Finset.mem_symmDiff, and_comm] |
| 123 | · simp [hS, atomMapOn, Catalog.VC.DualShatterFunction.atomMap, Finset.mem_symmDiff] |
| 124 | calc |
| 125 | ((atomMapOn Q x \ atomMapOn Q y) ∪ (atomMapOn Q y \ atomMapOn Q x)).card |
| 126 | = ((((atomMapOn Q x \ atomMapOn Q y) ∪ (atomMapOn Q y \ atomMapOn Q x)).image |
| 127 | Subtype.val)).card := by |
| 128 | symm |
| 129 | exact Finset.card_image_of_injective _ Subtype.val_injective |
| 130 | _ = (symmDiff (Catalog.VC.DualShatterFunction.atomMap Q x) |
| 131 | (Catalog.VC.DualShatterFunction.atomMap Q y)).card := by rw [hEq] |
| 132 | _ = crossingNumber Q x y := symmDiff_atomMap_card_eq_crossingNumber Q x y |
| 133 | |
| 134 | private lemma crossingNumber_le_card (Q : Finset (Finset α)) (x y : α) : |
| 135 | crossingNumber Q x y ≤ Q.card := by |
| 136 | unfold crossingNumber |
| 137 | exact Finset.card_filter_le _ _ |
| 138 | |
| 139 | private theorem le_floor_double {x : ℝ} (hx : 1 ≤ x) : |
| 140 | x ≤ Nat.floor (2 * x) := by |
| 141 | have hlt : 2 * x < Nat.floor (2 * x) + 1 := Nat.lt_floor_add_one (2 * x) |
| 142 | have hx2 : x ≤ 2 * x - 1 := by linarith |
| 143 | have hle : 2 * x - 1 < Nat.floor (2 * x) := by linarith |
| 144 | linarith |
| 145 | |
| 146 | private lemma card_image_atomMap_le_dualShatterFun |
| 147 | [Fintype α] (𝒜 Q : Finset (Finset α)) (hQ : Q ⊆ 𝒜) : |
| 148 | (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card ≤ |
| 149 | Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 Q.card := by |
| 150 | unfold Catalog.VC.DualShatterFunction.dualShatterFun |
| 151 | exact Finset.le_sup (f := fun 𝒴 => (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap 𝒴)).card) |
| 152 | (Finset.mem_filter.mpr ⟨Finset.mem_powerset.mpr hQ, rfl⟩) |
| 153 | |
| 154 | private lemma trace_dualFamily_card_le_dualShatterFun |
| 155 | [Fintype α] (𝒜 Q : Finset (Finset α)) (hQ : Q ⊆ 𝒜) |
| 156 | (Y : Finset {S // S ∈ Q}) : |
| 157 | (Catalog.VC.ShatterFunction.trace (Finset.univ.image (atomMapOn Q)) Y).card ≤ |
| 158 | Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 Y.card := by |
| 159 | let e : Finset {S // S ∈ Q} → Finset (Finset α) := fun T => T.image Subtype.val |
| 160 | have he_inj : Function.Injective e := image_val_injective Q |
| 161 | have hYsub : Y.image Subtype.val ⊆ 𝒜 := by |
| 162 | intro S hS |
| 163 | rcases Finset.mem_image.mp hS with ⟨T, hT, rfl⟩ |
| 164 | exact hQ T.2 |
| 165 | have hYcard : (Y.image Subtype.val).card = Y.card := by |
| 166 | rw [Finset.card_image_of_injective _ Subtype.val_injective] |
| 167 | calc |
| 168 | (Catalog.VC.ShatterFunction.trace (Finset.univ.image (atomMapOn Q)) Y).card |
| 169 | = ((Catalog.VC.ShatterFunction.trace (Finset.univ.image (atomMapOn Q)) Y).image e).card := by |
| 170 | symm |
| 171 | exact Finset.card_image_of_injective _ he_inj |
| 172 | _ ≤ (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap (Y.image Subtype.val))).card := by |
| 173 | apply Finset.card_le_card |
| 174 | intro T hT |
| 175 | rcases Finset.mem_image.mp hT with ⟨U, hU, rfl⟩ |
| 176 | simp only [Catalog.VC.ShatterFunction.trace, Finset.mem_image] at hU |
| 177 | rcases hU with ⟨A, hA, rfl⟩ |
| 178 | rcases hA with ⟨x, -, rfl⟩ |
| 179 | exact Finset.mem_image.mpr ⟨x, Finset.mem_univ _, (atomMapOn_inter_image_val Q Y x).symm⟩ |
| 180 | _ ≤ Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 Y.card := by |
| 181 | rw [← hYcard] |
| 182 | exact card_image_atomMap_le_dualShatterFun 𝒜 (Y.image Subtype.val) hYsub |
| 183 | |
| 184 | end |
| 185 | |
| 186 | /-- Short edge lemma: if the dual shatter function satisfies |
| 187 | `π*_𝒜(m) ≤ C · m^d` with `d > 1`, then for any subfamily `Q ⊆ 𝒜` |
| 188 | there exist distinct points `x, y` with crossing number at most |
| 189 | `C₂ · |Q| / n^{1/d}`. (Lemma 5.18) -/ |
| 190 | theorem shortEdgeLemma (d : ℕ) (C : ℝ) (hd : 1 < d) (hC : 0 < C) : |
| 191 | ∃ C₂ : ℝ, 0 < C₂ ∧ |
| 192 | ∀ (α : Type u) [DecidableEq α] [Fintype α] (𝒜 : Finset (Finset α)), |
| 193 | (∀ m : ℕ, (Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 m : ℝ) ≤ C * (m : ℝ) ^ d) → |
| 194 | 2 ≤ Fintype.card α → |
| 195 | ∀ (Q : Finset (Finset α)), Q ⊆ 𝒜 → |
| 196 | ∃ x y : α, x ≠ y ∧ |
| 197 | ((Q.filter (fun S => (x ∈ S ∧ y ∉ S) ∨ (x ∉ S ∧ y ∈ S))).card : ℝ) ≤ |
| 198 | C₂ * (Q.card : ℝ) / |
| 199 | (Fintype.card α : ℝ) ^ ((1 : ℝ) / d) := by |
| 200 | obtain ⟨C', hC'pos, hpack⟩ := Catalog.VC.PackingLemma.packingLemma d C hC |
| 201 | let A : ℝ := C + 2 * C' + 2 |
| 202 | refine ⟨2 * A, by positivity, ?_⟩ |
| 203 | intro α _ _ 𝒜 hdual hn Q hQ |
| 204 | change ∃ x y : α, x ≠ y ∧ |
| 205 | (crossingNumber Q x y : ℝ) ≤ (2 * A) * (Q.card : ℝ) / |
| 206 | (Fintype.card α : ℝ) ^ ((1 : ℝ) / d) |
| 207 | by_cases hlt : (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card < Fintype.card α |
| 208 | · obtain ⟨x, y, hxy, hatom⟩ := exists_atomMap_collision Q hlt |
| 209 | refine ⟨x, y, hxy, ?_⟩ |
| 210 | rw [crossingNumber_eq_zero_of_atomMap_eq Q hatom] |
| 211 | have hnonneg : |
| 212 | 0 ≤ (2 * A) * (Q.card : ℝ) / (Fintype.card α : ℝ) ^ ((1 : ℝ) / d) := by |
| 213 | positivity |
| 214 | linarith |
| 215 | · have himg_ge : Fintype.card α ≤ |
| 216 | (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card := by |
| 217 | exact Nat.le_of_not_lt hlt |
| 218 | have himg_le : (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card ≤ |
| 219 | Fintype.card α := Finset.card_image_le |
| 220 | have himg_eq : (Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card = |
| 221 | Fintype.card α := le_antisymm himg_le himg_ge |
| 222 | let nroot : ℝ := (Fintype.card α : ℝ) ^ ((1 : ℝ) / d) |
| 223 | let R : ℝ := (2 * A) * (Q.card : ℝ) / nroot |
| 224 | by_cases hRbig : (Q.card : ℝ) ≤ R |
| 225 | · have huniv : 1 < (Finset.univ : Finset α).card := by simpa using hn |
| 226 | obtain ⟨x, hx, y, hy, hxy⟩ := Finset.one_lt_card.mp huniv |
| 227 | refine ⟨x, y, hxy, ?_⟩ |
| 228 | have hcross : (crossingNumber Q x y : ℝ) ≤ Q.card := by |
| 229 | exact_mod_cast crossingNumber_le_card Q x y |
| 230 | calc |
| 231 | (crossingNumber Q x y : ℝ) ≤ Q.card := hcross |
| 232 | _ ≤ R := hRbig |
| 233 | _ = (2 * A) * (Q.card : ℝ) / nroot := rfl |
| 234 | · by_contra hshort |
| 235 | push_neg at hshort |
| 236 | let P : Finset (Finset {S // S ∈ Q}) := Finset.univ.image (atomMapOn Q) |
| 237 | let δ : ℕ := Nat.floor R |
| 238 | have hPcard : P.card = Fintype.card α := by |
| 239 | simp [P, dualFamilyOn_card_eq, himg_eq] |
| 240 | have hαle : (Fintype.card α : ℝ) ≤ C * (Q.card : ℝ) ^ d := by |
| 241 | calc |
| 242 | (Fintype.card α : ℝ) |
| 243 | = ((Finset.univ.image (Catalog.VC.DualShatterFunction.atomMap Q)).card : ℝ) := by |
| 244 | norm_num [himg_eq] |
| 245 | _ ≤ Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 Q.card := by |
| 246 | exact_mod_cast card_image_atomMap_le_dualShatterFun 𝒜 Q hQ |
| 247 | _ ≤ C * (Q.card : ℝ) ^ d := hdual Q.card |
| 248 | have hAone : 1 ≤ A := by |
| 249 | dsimp [A] |
| 250 | linarith |
| 251 | have hAle : C ≤ A := by |
| 252 | dsimp [A] |
| 253 | linarith |
| 254 | have hQnonneg : 0 ≤ (Q.card : ℝ) ^ d := by positivity |
| 255 | have hApow : A ≤ A ^ d := by |
| 256 | exact le_self_pow₀ hAone (by omega) |
| 257 | have hnroot_pos : 0 < nroot := by |
| 258 | dsimp [nroot] |
| 259 | positivity |
| 260 | have hRlt : R < (Q.card : ℝ) := lt_of_not_ge hRbig |
| 261 | have hnroot_le : nroot ≤ A * (Q.card : ℝ) := by |
| 262 | have hpow : |
| 263 | (Fintype.card α : ℝ) ≤ (A * (Q.card : ℝ)) ^ d := by |
| 264 | calc |
| 265 | (Fintype.card α : ℝ) ≤ C * (Q.card : ℝ) ^ d := hαle |
| 266 | _ ≤ A * (Q.card : ℝ) ^ d := by gcongr |
| 267 | _ ≤ A ^ d * (Q.card : ℝ) ^ d := by |
| 268 | gcongr |
| 269 | _ = (A * (Q.card : ℝ)) ^ d := by rw [mul_pow] |
| 270 | have hroot := |
| 271 | Real.rpow_le_rpow (by positivity : 0 ≤ (Fintype.card α : ℝ)) hpow |
| 272 | (by positivity : (0 : ℝ) ≤ (1 : ℝ) / d) |
| 273 | calc |
| 274 | nroot = (Fintype.card α : ℝ) ^ ((1 : ℝ) / d) := rfl |
| 275 | _ ≤ ((A * (Q.card : ℝ)) ^ d) ^ ((1 : ℝ) / d) := hroot |
| 276 | _ = A * (Q.card : ℝ) := by |
| 277 | calc |
| 278 | ((A * (Q.card : ℝ)) ^ d) ^ ((1 : ℝ) / d) |
| 279 | = (A * (Q.card : ℝ)) ^ ((d : ℝ) * ((1 : ℝ) / d)) := by |
| 280 | simpa [Real.rpow_natCast] using |
| 281 | (Real.rpow_mul (by positivity : 0 ≤ A * (Q.card : ℝ)) |
| 282 | (d : ℝ) ((1 : ℝ) / d)).symm |
| 283 | _ = (A * (Q.card : ℝ)) ^ (1 : ℝ) := by |
| 284 | field_simp [show (d : ℝ) ≠ 0 by exact_mod_cast (show (d : ℕ) ≠ 0 by omega)] |
| 285 | _ = A * (Q.card : ℝ) := by simp |
| 286 | have hxone : 1 ≤ A * (Q.card : ℝ) / nroot := by |
| 287 | rw [le_div_iff₀ hnroot_pos] |
| 288 | simpa [mul_comm] using hnroot_le |
| 289 | have hδge : A * (Q.card : ℝ) / nroot ≤ δ := by |
| 290 | have hfloor := le_floor_double hxone |
| 291 | have hR_eq : 2 * (A * (Q.card : ℝ) / nroot) = R := by |
| 292 | dsimp [R] |
| 293 | ring |
| 294 | simpa [δ, hR_eq] using hfloor |
| 295 | have hδpos : 0 < δ := by |
| 296 | have hδge1 : (1 : ℝ) ≤ δ := le_trans hxone hδge |
| 297 | exact_mod_cast hδge1 |
| 298 | have hδleQ : δ ≤ Q.card := by |
| 299 | have hδleR : (δ : ℝ) ≤ R := Nat.floor_le (by positivity : 0 ≤ R) |
| 300 | have hδltQ : (δ : ℝ) < Q.card := by linarith |
| 301 | exact_mod_cast hδltQ.le |
| 302 | have hsep : Catalog.VC.PackingLemma.IsSeparated P δ := by |
| 303 | intro S hS S' hS' hSS' |
| 304 | rcases Finset.mem_image.mp hS with ⟨x, -, rfl⟩ |
| 305 | rcases Finset.mem_image.mp hS' with ⟨y, -, rfl⟩ |
| 306 | have hxy : x ≠ y := by |
| 307 | intro hxy |
| 308 | apply hSS' |
| 309 | simp [hxy] |
| 310 | have hltcross : |
| 311 | R < (crossingNumber Q x y : ℝ) := by |
| 312 | have hnot : ¬ ((crossingNumber Q x y : ℝ) ≤ R) := by |
| 313 | simpa [R, nroot] using hshort x y hxy |
| 314 | exact lt_of_not_ge hnot |
| 315 | have hδltcross : (δ : ℝ) < (crossingNumber Q x y : ℝ) := by |
| 316 | have hδleR : (δ : ℝ) ≤ R := Nat.floor_le (by positivity : 0 ≤ R) |
| 317 | linarith |
| 318 | have hδltcross_nat : δ < crossingNumber Q x y := by |
| 319 | exact_mod_cast hδltcross |
| 320 | simpa [P, atomMapOn_sep_card_eq_crossingNumber] using hδltcross_nat |
| 321 | have hshatter : ∀ m : ℕ, (Catalog.VC.ShatterFunction.shatterFun P m : ℝ) ≤ C * (m : ℝ) ^ d := by |
| 322 | intro m |
| 323 | have hsf : Catalog.VC.ShatterFunction.shatterFun P m ≤ Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 m := by |
| 324 | unfold Catalog.VC.ShatterFunction.shatterFun |
| 325 | refine Finset.sup_le ?_ |
| 326 | intro Y hY |
| 327 | have hYm : Y.card = m := by |
| 328 | simpa using (Finset.mem_filter.mp hY).2 |
| 329 | calc |
| 330 | (Catalog.VC.ShatterFunction.trace P Y).card ≤ Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 Y.card := |
| 331 | trace_dualFamily_card_le_dualShatterFun 𝒜 Q hQ Y |
| 332 | _ = Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 m := by rw [hYm] |
| 333 | have hsf' : (Catalog.VC.ShatterFunction.shatterFun P m : ℝ) ≤ Catalog.VC.DualShatterFunction.dualShatterFun 𝒜 m := by |
| 334 | exact_mod_cast hsf |
| 335 | exact hsf'.trans (hdual m) |
| 336 | have hpack_bound := |
| 337 | hpack {S // S ∈ Q} P P (by intro T hT; exact hT) hshatter δ hδpos |
| 338 | (by simpa [Fintype.card_coe] using hδleQ) hsep |
| 339 | have hpack_bound' : (Fintype.card α : ℝ) ≤ C' * ((Q.card : ℝ) / δ) ^ d := by |
| 340 | simpa [P, hPcard, Fintype.card_coe] using hpack_bound |
| 341 | have hq_div : (Q.card : ℝ) / δ ≤ nroot / A := by |
| 342 | have hδpos' : (0 : ℝ) < δ := by exact_mod_cast hδpos |
| 343 | have hApos : 0 < A := by linarith |
| 344 | have hδge' : A * (Q.card : ℝ) ≤ δ * nroot := by |
| 345 | have htemp := hδge |
| 346 | rw [div_le_iff₀ hnroot_pos] at htemp |
| 347 | simpa [mul_comm, mul_left_comm, mul_assoc] using htemp |
| 348 | field_simp [hApos.ne', hδpos'.ne'] |
| 349 | nlinarith [hδge'] |
| 350 | have hpow_div : ((Q.card : ℝ) / δ) ^ d ≤ (nroot / A) ^ d := by |
| 351 | gcongr |
| 352 | have hpack_bound'' : (Fintype.card α : ℝ) ≤ C' * (nroot / A) ^ d := by |
| 353 | exact le_trans hpack_bound' (by gcongr) |
| 354 | have hnroot_pow : nroot ^ d = Fintype.card α := by |
| 355 | calc |
| 356 | nroot ^ d = nroot ^ (d : ℝ) := by rw [Real.rpow_natCast] |
| 357 | _ = (Fintype.card α : ℝ) ^ (((1 : ℝ) / d) * d) := by |
| 358 | dsimp [nroot] |
| 359 | rw [Real.rpow_mul (by positivity : 0 ≤ (Fintype.card α : ℝ))] |
| 360 | _ = (Fintype.card α : ℝ) ^ (1 : ℝ) := by |
| 361 | field_simp [show (d : ℝ) ≠ 0 by exact_mod_cast (show (d : ℕ) ≠ 0 by omega)] |
| 362 | _ = Fintype.card α := by simp |
| 363 | have hratio : (nroot / A) ^ d = (Fintype.card α : ℝ) / A ^ d := by |
| 364 | rw [div_pow, hnroot_pow] |
| 365 | have hC'ltA : C' < A := by |
| 366 | dsimp [A] |
| 367 | linarith |
| 368 | have hC'ltApow : C' < A ^ d := lt_of_lt_of_le hC'ltA hApow |
| 369 | have hαpos : 0 < (Fintype.card α : ℝ) := by |
| 370 | exact_mod_cast (lt_of_lt_of_le (by decide : 0 < 2) hn) |
| 371 | have hfinal_lt : C' * (nroot / A) ^ d < (Fintype.card α : ℝ) := by |
| 372 | rw [hratio] |
| 373 | have hApow_pos : 0 < A ^ d := by positivity |
| 374 | have hfrac_lt_one : C' / A ^ d < 1 := by |
| 375 | rw [div_lt_iff₀ hApow_pos] |
| 376 | simpa using hC'ltApow |
| 377 | have hmul := mul_lt_mul_of_pos_right hfrac_lt_one hαpos |
| 378 | have hrewrite : C' * ((Fintype.card α : ℝ) / A ^ d) = (C' / A ^ d) * (Fintype.card α : ℝ) := by |
| 379 | field_simp |
| 380 | rw [hrewrite] |
| 381 | simpa [one_mul] using hmul |
| 382 | exact (not_lt_of_ge hpack_bound'') hfinal_lt |
| 383 | |
| 384 | end Catalog.VC.ShortEdgeLemma |
| 385 |