Dev/MonadicDependence/WeaklySparseMonDepIsNowhereDense/Full.lean
| 1 | import Mathlib.Data.Fintype.Pigeonhole |
| 2 | import Mathlib.Order.Interval.Finset.Basic |
| 3 | import Mathlib.Order.Interval.Finset.Nat |
| 4 | import Catalog.Sparsity.Preliminaries.Full |
| 5 | import Dev.MonadicDependence.WeaklySparse.Full |
| 6 | import Dev.MonadicDependence.MonadicDependence.Full |
| 7 | import Dev.MonadicDependence.NowhereDense.Full |
| 8 | import Dev.MonadicDependence.Biclique.Full |
| 9 | import Dev.MonadicDependence.Subdivision.Full |
| 10 | import Dev.MonadicDependence.Flip.Full |
| 11 | import Dev.MonadicDependence.StarCrossing.Full |
| 12 | import Dev.MonadicDependence.SubdividedBicliqueRamsey.Full |
| 13 | |
| 14 | namespace Dev.MonadicDependence.WeaklySparseMonDepIsNowhereDense |
| 15 | |
| 16 | open Catalog.Sparsity.Preliminaries |
| 17 | open Dev.MonadicDependence.WeaklySparse |
| 18 | open Dev.MonadicDependence.MonadicDependence |
| 19 | open Dev.MonadicDependence.NowhereDense |
| 20 | open Dev.MonadicDependence.Biclique |
| 21 | open Dev.MonadicDependence.Subdivision |
| 22 | open Dev.MonadicDependence.Flip |
| 23 | open Dev.MonadicDependence.StarCrossing |
| 24 | open Dev.MonadicDependence.SubdividedBicliqueRamsey |
| 25 | |
| 26 | /-- With the empty layer relation `F = ⊥` the flip operation returns the |
| 27 | original graph. Used in Step 3b to identify the unflipped star |
| 28 | `r'`-crossing with a flipped one. -/ |
| 29 | lemma flip_bot {V α : Type*} (G : SimpleGraph V) (κ : V → α) : |
| 30 | flip G κ (⊥ : α → α → Prop) (fun _ _ h => h) = G := by |
| 31 | ext u v |
| 32 | change (u ≠ v ∧ (G.Adj u v ↔ ¬ (⊥ : α → α → Prop) (κ u) (κ v))) ↔ G.Adj u v |
| 33 | refine ⟨fun ⟨_, hiff⟩ => hiff.mpr (id : ¬ False), fun h => ⟨G.ne_of_adj h, ?_⟩⟩ |
| 34 | exact ⟨fun _ hbot => hbot, fun _ => h⟩ |
| 35 | |
| 36 | /-! |
| 37 | ### Step 1 helper: an `r`-subdivided biclique of order `⌊N/2⌋` is contained |
| 38 | as a subgraph in the `r`-subdivided clique of order `N`. |
| 39 | |
| 40 | The embedding sends the left roots to `{0, …, ⌊N/2⌋ - 1}`, the right roots |
| 41 | to `{⌊N/2⌋, …, 2⌊N/2⌋ - 1}`, and path vertices to the corresponding |
| 42 | subdivision paths of the ordered edges `(leftFin i, rightFin j)` (well-defined |
| 43 | because `leftFin i < rightFin j` whenever both are in range). The map is an |
| 44 | injective graph homomorphism into the subdivided clique; the subdivided |
| 45 | clique has *additional* edges (subdivision paths within each half, plus, for |
| 46 | `r = 0`, every pair of principals adjacent) which are tolerated because |
| 47 | `IsContained` is non-induced. |
| 48 | |
| 49 | Filling in the mechanical case analysis for `bicliqueHomToClique.map_rel'` |
| 50 | and full injectivity is left as a sub-`sorry` pending a dedicated Close |
| 51 | session; the top-level structure of the rest of the proof depends only on |
| 52 | the statement of this lemma. |
| 53 | -/ |
| 54 | |
| 55 | /-- Left-half embedding `Fin (N/2) ↪ Fin N`: `i ↦ i`. -/ |
| 56 | private def leftFin (N : ℕ) (i : Fin (N / 2)) : Fin N := |
| 57 | ⟨i.val, lt_of_lt_of_le i.isLt (Nat.div_le_self N 2)⟩ |
| 58 | |
| 59 | /-- Right-half embedding `Fin (N/2) ↪ Fin N`: `j ↦ ⌊N/2⌋ + j`. -/ |
| 60 | private def rightFin (N : ℕ) (j : Fin (N / 2)) : Fin N := |
| 61 | ⟨N / 2 + j.val, by |
| 62 | have h1 : j.val < N / 2 := j.isLt |
| 63 | have h2 : N / 2 * 2 ≤ N := Nat.div_mul_le_self N 2 |
| 64 | omega⟩ |
| 65 | |
| 66 | private lemma leftFin_val (N : ℕ) (i : Fin (N / 2)) : |
| 67 | (leftFin N i).val = i.val := rfl |
| 68 | |
| 69 | private lemma rightFin_val (N : ℕ) (j : Fin (N / 2)) : |
| 70 | (rightFin N j).val = N / 2 + j.val := rfl |
| 71 | |
| 72 | private lemma leftFin_lt_rightFin (N : ℕ) (i j : Fin (N / 2)) : |
| 73 | (leftFin N i).val < (rightFin N j).val := by |
| 74 | simp only [leftFin_val, rightFin_val] |
| 75 | have := i.isLt; omega |
| 76 | |
| 77 | private lemma leftFin_ne_rightFin (N : ℕ) (i j : Fin (N / 2)) : |
| 78 | leftFin N i ≠ rightFin N j := fun h => by |
| 79 | have h' : (leftFin N i).val = (rightFin N j).val := by rw [h] |
| 80 | simp only [leftFin_val, rightFin_val] at h' |
| 81 | have := i.isLt |
| 82 | omega |
| 83 | |
| 84 | private lemma leftFin_injective (N : ℕ) : Function.Injective (leftFin N) := by |
| 85 | intro i j h |
| 86 | apply Fin.ext |
| 87 | have h' : (leftFin N i).val = (leftFin N j).val := by rw [h] |
| 88 | simpa [leftFin_val] using h' |
| 89 | |
| 90 | private lemma rightFin_injective (N : ℕ) : Function.Injective (rightFin N) := by |
| 91 | intro i j h |
| 92 | apply Fin.ext |
| 93 | have h' : (rightFin N i).val = (rightFin N j).val := by rw [h] |
| 94 | simpa [rightFin_val] using h' |
| 95 | |
| 96 | /-- Vertex embedding `SubdividedBicliqueVert (N/2) r → SubdividedCliqueVert N r`. -/ |
| 97 | private def bicliqueVertToClique (N r : ℕ) : |
| 98 | SubdividedBicliqueVert (N / 2) r → SubdividedCliqueVert N r |
| 99 | | .inl (.inl i) => .inl (leftFin N i) |
| 100 | | .inl (.inr j) => .inl (rightFin N j) |
| 101 | | .inr ⟨⟨i, j⟩, k⟩ => |
| 102 | .inr ⟨⟨(leftFin N i, rightFin N j), leftFin_lt_rightFin N i j⟩, k⟩ |
| 103 | |
| 104 | private lemma bicliqueVertToClique_injective (N r : ℕ) : |
| 105 | Function.Injective (bicliqueVertToClique N r) := by |
| 106 | intro u v heq |
| 107 | rcases u with (iU | jU) | ⟨⟨iU, jU⟩, kU⟩ <;> |
| 108 | rcases v with (iV | jV) | ⟨⟨iV, jV⟩, kV⟩ <;> |
| 109 | dsimp only [bicliqueVertToClique] at heq |
| 110 | · exact congrArg (fun x => (Sum.inl (Sum.inl x) : SubdividedBicliqueVert (N/2) r)) |
| 111 | (leftFin_injective N (Sum.inl.inj heq)) |
| 112 | · exact absurd (Sum.inl.inj heq) (leftFin_ne_rightFin N _ _) |
| 113 | · cases heq |
| 114 | · exact absurd (Sum.inl.inj heq).symm (leftFin_ne_rightFin N _ _) |
| 115 | · exact congrArg (fun x => (Sum.inl (Sum.inr x) : SubdividedBicliqueVert (N/2) r)) |
| 116 | (rightFin_injective N (Sum.inl.inj heq)) |
| 117 | · cases heq |
| 118 | · cases heq |
| 119 | · cases heq |
| 120 | · have h := Sum.inr.inj heq |
| 121 | -- h : ((⟨(leftFin iU, rightFin jU), _⟩ : _ × _), kU) |
| 122 | -- = ((⟨(leftFin iV, rightFin jV), _⟩ : _ × _), kV) |
| 123 | obtain ⟨hSub, hk⟩ := Prod.mk.inj h |
| 124 | -- hSub : ⟨(leftFin iU, rightFin jU), _⟩ = ⟨(leftFin iV, rightFin jV), _⟩ |
| 125 | have hpair : (leftFin N iU, rightFin N jU) = (leftFin N iV, rightFin N jV) := |
| 126 | Subtype.ext_iff.mp hSub |
| 127 | obtain ⟨hil, hir⟩ := Prod.mk.inj hpair |
| 128 | have hi : iU = iV := leftFin_injective N hil |
| 129 | have hj : jU = jV := rightFin_injective N hir |
| 130 | subst hi; subst hj; subst hk; rfl |
| 131 | |
| 132 | /-- Adjacency-preserving hom induced by `bicliqueVertToClique`. -/ |
| 133 | private def bicliqueHomToClique (N r : ℕ) : |
| 134 | subdividedBiclique (N / 2) r →g subdividedClique N r where |
| 135 | toFun := bicliqueVertToClique N r |
| 136 | map_rel' := by |
| 137 | intro u v huv |
| 138 | rw [subdividedBiclique, SimpleGraph.fromRel_adj] at huv |
| 139 | rw [subdividedClique, SimpleGraph.fromRel_adj] |
| 140 | obtain ⟨hne, hor⟩ := huv |
| 141 | refine ⟨fun h => hne (bicliqueVertToClique_injective N r h), ?_⟩ |
| 142 | rcases u with (iU | jU) | ⟨⟨iU, jU⟩, kU⟩ <;> |
| 143 | rcases v with (iV | jV) | ⟨⟨iV, jV⟩, kV⟩ <;> |
| 144 | dsimp only [bicliqueVertToClique] at * |
| 145 | · -- (L iU, L iV): biclique hor is `False ∨ False` |
| 146 | exact (hor.elim id id).elim |
| 147 | · -- (L iU, R jV): biclique hor is `r = 0 ∨ False`; clique goal is `r = 0 ∨ r = 0` |
| 148 | rcases hor with h | h |
| 149 | · exact Or.inl h |
| 150 | · exact h.elim |
| 151 | · -- (L iU, P iV jV kV): biclique hor is `(iU = iV ∧ kV = 0) ∨ False`; |
| 152 | -- clique goal is (iU,jU,kV)-relation on principal vs path |
| 153 | rcases hor with ⟨hii, hk⟩ | h |
| 154 | · exact Or.inl (Or.inl ⟨by rw [hii], hk⟩) |
| 155 | · exact h.elim |
| 156 | · -- (R jU, L iV): biclique hor is `False ∨ r = 0`; clique goal `r = 0 ∨ r = 0` |
| 157 | rcases hor with h | h |
| 158 | · exact h.elim |
| 159 | · exact Or.inr h |
| 160 | · -- (R jU, R jV): biclique hor `False ∨ False` |
| 161 | exact (hor.elim id id).elim |
| 162 | · -- (R jU, P iV jV kV): biclique hor is `(jU = jV ∧ kV = r-1) ∨ False` |
| 163 | rcases hor with ⟨hjj, hk⟩ | h |
| 164 | · exact Or.inl (Or.inr ⟨by rw [hjj], hk⟩) |
| 165 | · exact h.elim |
| 166 | · -- (P iU jU kU, L iV): biclique hor is `False ∨ (iV = iU ∧ kU = 0)` |
| 167 | rcases hor with h | ⟨hii, hk⟩ |
| 168 | · exact h.elim |
| 169 | · exact Or.inr (Or.inl ⟨by rw [hii], hk⟩) |
| 170 | · -- (P iU jU kU, R jV): biclique hor is `False ∨ (jV = jU ∧ kU = r-1)` |
| 171 | rcases hor with h | ⟨hjj, hk⟩ |
| 172 | · exact h.elim |
| 173 | · exact Or.inr (Or.inr ⟨by rw [hjj], hk⟩) |
| 174 | · -- (P iU jU kU, P iV jV kV): biclique hor |
| 175 | -- is `((iU,jU) = (iV,jV) ∧ kU+1=kV) ∨ ((iV,jV) = (iU,jU) ∧ kV+1=kU)` |
| 176 | rcases hor with ⟨hij, hk⟩ | ⟨hij, hk⟩ |
| 177 | · refine Or.inl ⟨?_, hk⟩ |
| 178 | obtain ⟨hii, hjj⟩ := Prod.mk.inj hij |
| 179 | apply Subtype.ext |
| 180 | simp only [hii, hjj] |
| 181 | · refine Or.inr ⟨?_, hk⟩ |
| 182 | obtain ⟨hii, hjj⟩ := Prod.mk.inj hij |
| 183 | apply Subtype.ext |
| 184 | simp only [hii, hjj] |
| 185 | |
| 186 | /-- Step 1 helper: an `r`-subdivided biclique of order `⌊N/2⌋` is contained |
| 187 | as a subgraph in the `r`-subdivided clique of order `N`. -/ |
| 188 | lemma subdividedBiclique_isContained_subdividedClique (N r : ℕ) : |
| 189 | (subdividedBiclique (N / 2) r).IsContained (subdividedClique N r) := |
| 190 | ⟨(bicliqueHomToClique N r).toCopy (bicliqueVertToClique_injective N r)⟩ |
| 191 | |
| 192 | /-! |
| 193 | ### r=0 helper: the biclique `K_{⌊N/2⌋, ⌊N/2⌋}` is a subgraph of the |
| 194 | `0`-subdivided clique of order `N`. |
| 195 | -/ |
| 196 | |
| 197 | private def bicliqueVertToCliqueZero (N : ℕ) : |
| 198 | (Fin (N / 2) ⊕ Fin (N / 2)) → SubdividedCliqueVert N 0 |
| 199 | | .inl i => .inl (leftFin N i) |
| 200 | | .inr j => .inl (rightFin N j) |
| 201 | |
| 202 | private lemma bicliqueVertToCliqueZero_injective (N : ℕ) : |
| 203 | Function.Injective (bicliqueVertToCliqueZero N) := by |
| 204 | intro u v heq |
| 205 | rcases u with iU | jU <;> rcases v with iV | jV <;> |
| 206 | simp only [bicliqueVertToCliqueZero] at heq |
| 207 | · exact congrArg Sum.inl (leftFin_injective N (Sum.inl.inj heq)) |
| 208 | · exact absurd (Sum.inl.inj heq) (leftFin_ne_rightFin N _ _) |
| 209 | · exact absurd (Sum.inl.inj heq).symm (leftFin_ne_rightFin N _ _) |
| 210 | · exact congrArg Sum.inr (rightFin_injective N (Sum.inl.inj heq)) |
| 211 | |
| 212 | private def bicliqueHomToCliqueZero (N : ℕ) : |
| 213 | biclique (N / 2) →g subdividedClique N 0 where |
| 214 | toFun := bicliqueVertToCliqueZero N |
| 215 | map_rel' := by |
| 216 | intro u v huv |
| 217 | rcases u with iU | jU <;> rcases v with iV | jV |
| 218 | · exact absurd huv (by simp [biclique, completeBipartiteGraph]) |
| 219 | · refine ⟨fun h => leftFin_ne_rightFin N _ _ (Sum.inl.inj h), ?_⟩ |
| 220 | exact Or.inl (by show (0 : ℕ) = 0; rfl) |
| 221 | · refine ⟨fun h => (leftFin_ne_rightFin N _ _) (Sum.inl.inj h).symm, ?_⟩ |
| 222 | exact Or.inl (by show (0 : ℕ) = 0; rfl) |
| 223 | · exact absurd huv (by simp [biclique, completeBipartiteGraph]) |
| 224 | |
| 225 | /-- A biclique of order `⌊N/2⌋` is contained as a subgraph in the |
| 226 | `0`-subdivided clique of order `N`. -/ |
| 227 | lemma biclique_isContained_subdividedClique_zero (N : ℕ) : |
| 228 | (biclique (N / 2)).IsContained (subdividedClique N 0) := |
| 229 | ⟨(bicliqueHomToCliqueZero N).toCopy (bicliqueVertToCliqueZero_injective N)⟩ |
| 230 | |
| 231 | /-! |
| 232 | ### Helper: biclique-mono. |
| 233 | `biclique k ⊑ biclique m` whenever `k ≤ m`. |
| 234 | -/ |
| 235 | |
| 236 | lemma biclique_isContained_biclique_of_le {k m : ℕ} (h : k ≤ m) : |
| 237 | (biclique k).IsContained (biclique m) := by |
| 238 | -- `Fin k ↪ Fin m` via `Fin.castLE` gives a hom of complete bipartite graphs. |
| 239 | refine ⟨?_⟩ |
| 240 | refine |
| 241 | { toHom := |
| 242 | { toFun := fun v => |
| 243 | match v with |
| 244 | | .inl i => .inl (Fin.castLE h i) |
| 245 | | .inr j => .inr (Fin.castLE h j) |
| 246 | map_rel' := by |
| 247 | intro u v huv |
| 248 | rcases u with iU | jU <;> rcases v with iV | jV <;> |
| 249 | simp_all [biclique, completeBipartiteGraph] } |
| 250 | injective' := ?_ } |
| 251 | intro u v heq |
| 252 | rcases u with iU | jU <;> rcases v with iV | jV |
| 253 | · have h := Sum.inl.inj heq |
| 254 | exact congrArg (fun x => (Sum.inl x : Fin k ⊕ Fin k)) |
| 255 | (Fin.ext (by simpa using congrArg (Fin.val : Fin m → ℕ) h)) |
| 256 | · cases heq |
| 257 | · cases heq |
| 258 | · have h := Sum.inr.inj heq |
| 259 | exact congrArg (fun x => (Sum.inr x : Fin k ⊕ Fin k)) |
| 260 | (Fin.ext (by simpa using congrArg (Fin.val : Fin m → ℕ) h)) |
| 261 | |
| 262 | /-! |
| 263 | ### Helper: induced biclique mono. |
| 264 | `subdividedBiclique k r ⊴ subdividedBiclique m r` whenever `k ≤ m`, via |
| 265 | the obvious inclusion `Fin.castLE` on each coordinate. |
| 266 | -/ |
| 267 | |
| 268 | private lemma subdividedBiclique_isIndContained_of_le {k m r : ℕ} (h : k ≤ m) : |
| 269 | (subdividedBiclique k r).IsIndContained (subdividedBiclique m r) := by |
| 270 | refine ⟨{ |
| 271 | toFun := fun v => match v with |
| 272 | | .inl (.inl i) => .inl (.inl (Fin.castLE h i)) |
| 273 | | .inl (.inr j) => .inl (.inr (Fin.castLE h j)) |
| 274 | | .inr ⟨⟨i, j⟩, k'⟩ => .inr ⟨⟨Fin.castLE h i, Fin.castLE h j⟩, k'⟩ |
| 275 | inj' := by |
| 276 | intro u v heq |
| 277 | rcases u with (iU | jU) | ⟨⟨iU, jU⟩, kU⟩ <;> |
| 278 | rcases v with (iV | jV) | ⟨⟨iV, jV⟩, kV⟩ <;> |
| 279 | simp_all [Fin.ext_iff] |
| 280 | map_rel_iff' := by |
| 281 | intro u v |
| 282 | simp only [subdividedBiclique, SimpleGraph.fromRel_adj] |
| 283 | rcases u with (iU | jU) | ⟨⟨iU, jU⟩, kU⟩ <;> |
| 284 | rcases v with (iV | jV) | ⟨⟨iV, jV⟩, kV⟩ <;> |
| 285 | simp_all [Fin.ext_iff, Prod.ext_iff] |
| 286 | }⟩ |
| 287 | |
| 288 | /-! |
| 289 | ### Main theorem. |
| 290 | |
| 291 | Negate `IsNowhereDense`, extract the bad `r`, then case on `r = 0` vs |
| 292 | `r ≥ 1`. The `r = 0` branch uses `biclique_isContained_subdividedClique_zero` |
| 293 | and immediately contradicts weak sparseness. The `r ≥ 1` branch goes |
| 294 | through `subdividedBicliqueRamsey` and pigeonhole. |
| 295 | -/ |
| 296 | |
| 297 | /-- Mählmann Lemma 13.7: weakly sparse + monadically dependent ⇒ |
| 298 | nowhere dense (local sense). -/ |
| 299 | theorem weaklySparseMonDepIsNowhereDense (C : GraphClass) : |
| 300 | IsWeaklySparse C → IsMonadicallyDependent C → IsNowhereDense C := by |
| 301 | rintro ⟨kWS, hWS⟩ hMD |
| 302 | by_contra hNotND |
| 303 | -- Unfold and negate `IsNowhereDense`. Package all implicit instance |
| 304 | -- binders explicitly in the resulting existential. |
| 305 | have hBad : ∃ r : ℕ, ∀ N : ℕ, ∃ (V : Type) (_ : DecidableEq V) |
| 306 | (_ : Fintype V) (G : SimpleGraph V), |
| 307 | C G ∧ (subdividedClique N r).IsContained G := by |
| 308 | classical |
| 309 | by_contra hGood |
| 310 | apply hNotND |
| 311 | intro r |
| 312 | by_contra hNoN |
| 313 | apply hGood |
| 314 | refine ⟨r, ?_⟩ |
| 315 | intro N |
| 316 | by_contra hNoWitness |
| 317 | apply hNoN |
| 318 | refine ⟨N, ?_⟩ |
| 319 | intro V _ _ G hCG hContained |
| 320 | exact hNoWitness ⟨V, inferInstance, inferInstance, G, hCG, hContained⟩ |
| 321 | obtain ⟨r, hr⟩ := hBad |
| 322 | -- `r = 0` branch: biclique contradiction. |
| 323 | rcases Nat.eq_zero_or_pos r with hr0 | hrPos |
| 324 | · subst hr0 |
| 325 | -- For N = 2 * kWS + 1 we get a subdivided clique of order N with r=0; |
| 326 | -- this contains the biclique of order (N/2) ≥ kWS; contradicts weak |
| 327 | -- sparseness. |
| 328 | obtain ⟨V, instD, instF, G, hCG, hContained⟩ := hr (2 * kWS + 1) |
| 329 | have hContBiclique : (biclique ((2 * kWS + 1) / 2)).IsContained G := |
| 330 | (biclique_isContained_subdividedClique_zero (2 * kWS + 1)).trans hContained |
| 331 | have hDiv : (2 * kWS + 1) / 2 = kWS := by omega |
| 332 | rw [hDiv] at hContBiclique |
| 333 | exact hWS G hCG hContBiclique |
| 334 | -- `r ≥ 1`: apply Ramsey. |
| 335 | -- For every `n`, the subdivided biclique of order `n` is contained |
| 336 | -- in some `G ∈ C`. |
| 337 | have hBiclique : ∀ n : ℕ, ∃ (V : Type) (_ : DecidableEq V) |
| 338 | (_ : Fintype V) (G : SimpleGraph V), |
| 339 | C G ∧ (subdividedBiclique n r).IsContained G := by |
| 340 | intro n |
| 341 | obtain ⟨V, instD, instF, G, hCG, hContained⟩ := hr (2 * n + 1) |
| 342 | refine ⟨V, instD, instF, G, hCG, ?_⟩ |
| 343 | have hDiv : (2 * n + 1) / 2 = n := by omega |
| 344 | have step := subdividedBiclique_isContained_subdividedClique (2 * n + 1) r |
| 345 | rw [hDiv] at step |
| 346 | exact step.trans hContained |
| 347 | -- Apply `subdividedBicliqueRamsey`. |
| 348 | obtain ⟨U, _hUmono, hUunb, hRamsey⟩ := subdividedBicliqueRamsey r |
| 349 | -- Build the alternative at every `n`. |
| 350 | have hAlt : ∀ n : ℕ, ∃ (V : Type) (_ : DecidableEq V) |
| 351 | (_ : Fintype V) (G : SimpleGraph V), C G ∧ |
| 352 | ((biclique (U n)).IsContained G ∨ |
| 353 | ∃ r' : ℕ, 1 ≤ r' ∧ r' ≤ r ∧ |
| 354 | (subdividedBiclique (U n) r').IsIndContained G) := by |
| 355 | intro n |
| 356 | obtain ⟨V, instD, instF, G, hCG, hContained⟩ := hBiclique n |
| 357 | exact ⟨V, instD, instF, G, hCG, hRamsey G n hContained⟩ |
| 358 | -- Pigeonhole on the two top-level alternatives: either the biclique |
| 359 | -- alternative occurs for arbitrarily large `U n`, or the induced-biclique |
| 360 | -- alternative does; in the latter case, pigeonhole again on `Fin r`. |
| 361 | by_cases hBranch1 : ∀ M : ℕ, ∃ n : ℕ, M ≤ U n ∧ |
| 362 | ∃ (V : Type) (_ : DecidableEq V) (_ : Fintype V) (G : SimpleGraph V), |
| 363 | C G ∧ (biclique (U n)).IsContained G |
| 364 | · -- Step 3a: biclique alternative → weak-sparseness contradiction. |
| 365 | obtain ⟨n, hUn, V, instD, instF, G, hCG, hContained⟩ := hBranch1 kWS |
| 366 | have : (biclique kWS).IsContained G := |
| 367 | (biclique_isContained_biclique_of_le hUn).trans hContained |
| 368 | exact hWS G hCG this |
| 369 | · -- Branch 1 fails: then for some threshold `M₀`, no `n` with |
| 370 | -- `U n ≥ M₀` lands in the biclique alternative. Hence for every |
| 371 | -- larger target there is a new `n` landing in the induced-biclique |
| 372 | -- alternative. Pigeonhole on `Fin r` to fix a single `r' ∈ [r]`. |
| 373 | push_neg at hBranch1 |
| 374 | obtain ⟨M₀, hM₀⟩ := hBranch1 |
| 375 | -- For each `m ≥ M₀` choose an `n` with `U n ≥ m` exhibiting an induced |
| 376 | -- `r'`-biclique alternative (`r' ∈ [r]`), then pigeonhole on `r'`. |
| 377 | -- Combine into: there is a single `r' ∈ [r]` such that for every `m` |
| 378 | -- there is some `G ∈ C` containing an induced `r'`-subdivided biclique |
| 379 | -- of order ≥ `m`. |
| 380 | have hIndUnb : ∃ r' : ℕ, 1 ≤ r' ∧ r' ≤ r ∧ ∀ m : ℕ, |
| 381 | ∃ (V : Type) (_ : DecidableEq V) (_ : Fintype V) (G : SimpleGraph V), |
| 382 | C G ∧ ∃ n : ℕ, m ≤ n ∧ (subdividedBiclique n r').IsIndContained G := by |
| 383 | classical |
| 384 | haveI : NeZero r := ⟨Nat.one_le_iff_ne_zero.mp hrPos⟩ |
| 385 | -- For each `M`, choose an index `n` with `U n ≥ max M M₀`, apply `hAlt`, |
| 386 | -- rule out the biclique alternative via `hM₀`, extract `r'(M) ∈ Fin r`. |
| 387 | have step : ∀ M : ℕ, ∃ (r' : Fin r) (n : ℕ), |
| 388 | M ≤ U n ∧ |
| 389 | ∃ (V : Type) (_ : DecidableEq V) (_ : Fintype V) (G : SimpleGraph V), |
| 390 | C G ∧ (subdividedBiclique (U n) (r'.val + 1)).IsIndContained G := by |
| 391 | intro M |
| 392 | obtain ⟨n, hn⟩ := hUunb (max M M₀) |
| 393 | have hnM : M ≤ U n := (le_max_left _ _).trans hn |
| 394 | have hnM₀ : M₀ ≤ U n := (le_max_right _ _).trans hn |
| 395 | obtain ⟨V, instD, instF, G, hCG, hAltCase⟩ := hAlt n |
| 396 | rcases hAltCase with hbc | ⟨r', hr'1, hr'r, hIC⟩ |
| 397 | · exfalso |
| 398 | exact (hM₀ n hnM₀ V instD instF G hCG).false hbc.some |
| 399 | · refine ⟨⟨r' - 1, by omega⟩, n, hnM, V, instD, instF, G, hCG, ?_⟩ |
| 400 | have : r' - 1 + 1 = r' := by omega |
| 401 | rw [this]; exact hIC |
| 402 | -- Extract the r'-choice as a function ℕ → Fin r. |
| 403 | choose rChoice nChoice hChoice using step |
| 404 | -- Pigeonhole: some r₀ has infinite preimage under rChoice. |
| 405 | obtain ⟨r₀, hr₀inf⟩ := Finite.exists_infinite_fiber rChoice |
| 406 | refine ⟨r₀.val + 1, by omega, by omega, ?_⟩ |
| 407 | intro m |
| 408 | -- Use that the preimage is infinite to find M ≥ m with rChoice M = r₀. |
| 409 | have hSetInf : (rChoice ⁻¹' {r₀}).Infinite := Set.infinite_coe_iff.mp hr₀inf |
| 410 | obtain ⟨M, hMmem, hMlt⟩ := hSetInf.exists_gt m |
| 411 | have hMeq : rChoice M = r₀ := hMmem |
| 412 | obtain ⟨hMbd, V, instD, instF, G, hCG, hICM⟩ := hChoice M |
| 413 | refine ⟨V, instD, instF, G, hCG, U (nChoice M), ?_, ?_⟩ |
| 414 | · exact le_trans hMlt.le hMbd |
| 415 | · rw [← hMeq]; exact hICM |
| 416 | obtain ⟨r', hr'1, hr'r, hInd⟩ := hIndUnb |
| 417 | -- Step 3b: apply monadic dependence at `r'`. |
| 418 | obtain ⟨kMD, hMD'⟩ := hMD r' hr'1 |
| 419 | -- Pick `m = kMD` and get an induced subdivided biclique of order `≥ kMD`. |
| 420 | obtain ⟨V, instD, instF, G, hCG, n, hnBound, hContained⟩ := hInd kMD |
| 421 | -- An induced subdivided biclique of order `n ≥ kMD` contains one of |
| 422 | -- order `kMD` (also induced). |
| 423 | have hContainedKMD : |
| 424 | (subdividedBiclique kMD r').IsIndContained G := |
| 425 | (subdividedBiclique_isIndContained_of_le hnBound).trans hContained |
| 426 | -- The star `r'`-crossing is by definition `subdividedBiclique`, so the |
| 427 | -- induced subgraph is a flipped star `r'`-crossing with `F = ⊥`. |
| 428 | have hStar : (flip (starCrossing kMD r') layer |
| 429 | (⊥ : Fin (r' + 2) → Fin (r' + 2) → Prop) (fun _ _ h => h)).IsIndContained G := by |
| 430 | have : flip (starCrossing kMD r') layer |
| 431 | (⊥ : Fin (r' + 2) → Fin (r' + 2) → Prop) (fun _ _ h => h) = |
| 432 | subdividedBiclique kMD r' := by |
| 433 | simpa [starCrossing] using flip_bot (subdividedBiclique kMD r') layer |
| 434 | rw [this] |
| 435 | exact hContainedKMD |
| 436 | -- Contradiction with monadic dependence. |
| 437 | exact (hMD' G hCG).1 _ _ hStar |
| 438 | |
| 439 | end Dev.MonadicDependence.WeaklySparseMonDepIsNowhereDense |
| 440 |