|
| 1 | +/- |
| 2 | +Copyright (c) 2023 Yaël Dillies, Bhavik Mehta. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yaël Dillies, Bhavik Mehta |
| 5 | +-/ |
| 6 | +import Mathlib.Combinatorics.SimpleGraph.Triangle.Basic |
| 7 | + |
| 8 | +/-! |
| 9 | +# Construct a tripartite graph from its triangles |
| 10 | +
|
| 11 | +This file contains the construction of a simple graph on `α ⊕ β ⊕ γ` from a list of triangles |
| 12 | +`(a, b, c)` (with `a` in the first component, `b` in the second, `c` in the third). |
| 13 | +
|
| 14 | +We call |
| 15 | +* `t : Finset (α × β × γ)` the set of *triangle indices* (its elements are not triangles within the |
| 16 | + graph but instead index them). |
| 17 | +* *explicit* a triangle of the constructed graph coming from a triangle index. |
| 18 | +* *accidental* a triangle of the constructed graph not coming from a triangle index. |
| 19 | +
|
| 20 | +The two important properties of this construction are: |
| 21 | +* `SimpleGraph.TripartiteFromTriangles.ExplicitDisjoint`: Whether the explicit triangles are |
| 22 | + edge-disjoint. |
| 23 | +* `SimpleGraph.TripartiteFromTriangles.NoAccidental`: Whether all triangles are explicit. |
| 24 | +
|
| 25 | +This construction shows up unrelatedly twice in the theory of Roth numbers: |
| 26 | +* The lower bound of the Ruzsa-Szemerédi problem: From a set `s` in a finite abelian group `G` of |
| 27 | + odd order, we construct a tripartite graph on `G ⊕ G ⊕ G`. The triangle indices are |
| 28 | + `(x, x + a, x + 2 * a)` for `x` any element and `a ∈ s`. The explicit triangles are always |
| 29 | + edge-disjoint and there is no accidental triangle if `s` is 3AP-free. |
| 30 | +* The proof of the corners theorem from the triangle removal lemma: For a set `s` in a finite |
| 31 | + abelian group `G`, we construct a tripartite graph on `G ⊕ G ⊕ G`, whose vertices correspond to |
| 32 | + the horizontal, vertical and diagonal lines in `G × G`. The explicit triangles are `(h, v, d)` |
| 33 | + where `h`, `v`, `d` are horizontal, vertical, diagonal lines that intersect in an element of `s`. |
| 34 | + The explicit triangles are always edge-disjoint and there is no accidental triangle if `s` is |
| 35 | + corner-free. |
| 36 | +-/ |
| 37 | + |
| 38 | +open Finset Function Sum3 |
| 39 | + |
| 40 | +variable {α β γ 𝕜 : Type*} [LinearOrderedField 𝕜] {t : Finset (α × β × γ)} {a a' : α} {b b' : β} |
| 41 | + {c c' : γ} {x : α × β × γ} {ε : 𝕜} |
| 42 | + |
| 43 | +namespace SimpleGraph |
| 44 | +namespace TripartiteFromTriangles |
| 45 | + |
| 46 | +/-- The underlying relation of the tripartite-from-triangles graph. |
| 47 | +
|
| 48 | +Two vertices are related iff there exists a triangle index containing them both. -/ |
| 49 | +@[mk_iff] inductive Rel (t : Finset (α × β × γ)) : α ⊕ β ⊕ γ → α ⊕ β ⊕ γ → Prop |
| 50 | +| in₀₁ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₀ a) (in₁ b) |
| 51 | +| in₁₀ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₁ b) (in₀ a) |
| 52 | +| in₀₂ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₀ a) (in₂ c) |
| 53 | +| in₂₀ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₂ c) (in₀ a) |
| 54 | +| in₁₂ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₁ b) (in₂ c) |
| 55 | +| in₂₁ ⦃a b c⦄ : (a, b, c) ∈ t → Rel t (in₂ c) (in₁ b) |
| 56 | + |
| 57 | +open Rel |
| 58 | + |
| 59 | +lemma rel_irrefl : ∀ x, ¬ Rel t x x := fun _x hx ↦ nomatch hx |
| 60 | +lemma rel_symm : Symmetric (Rel t) := fun x y h ↦ by cases h <;> constructor <;> assumption |
| 61 | + |
| 62 | +/-- The tripartite-from-triangles graph. Two vertices are related iff there exists a triangle index |
| 63 | +containing them both. -/ |
| 64 | +def graph (t : Finset (α × β × γ)) : SimpleGraph (α ⊕ β ⊕ γ) := ⟨Rel t, rel_symm, rel_irrefl⟩ |
| 65 | + |
| 66 | +namespace Graph |
| 67 | + |
| 68 | +@[simp] lemma not_in₀₀ : ¬ (graph t).Adj (in₀ a) (in₀ a') := fun h ↦ nomatch h |
| 69 | +@[simp] lemma not_in₁₁ : ¬ (graph t).Adj (in₁ b) (in₁ b') := fun h ↦ nomatch h |
| 70 | +@[simp] lemma not_in₂₂ : ¬ (graph t).Adj (in₂ c) (in₂ c') := fun h ↦ nomatch h |
| 71 | + |
| 72 | +@[simp] lemma in₀₁_iff : (graph t).Adj (in₀ a) (in₁ b) ↔ ∃ c, (a, b, c) ∈ t := |
| 73 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₀₁ h⟩ |
| 74 | +@[simp] lemma in₁₀_iff : (graph t).Adj (in₁ b) (in₀ a) ↔ ∃ c, (a, b, c) ∈ t := |
| 75 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₁₀ h⟩ |
| 76 | +@[simp] lemma in₀₂_iff : (graph t).Adj (in₀ a) (in₂ c) ↔ ∃ b, (a, b, c) ∈ t := |
| 77 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₀₂ h⟩ |
| 78 | +@[simp] lemma in₂₀_iff : (graph t).Adj (in₂ c) (in₀ a) ↔ ∃ b, (a, b, c) ∈ t := |
| 79 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₂₀ h⟩ |
| 80 | +@[simp] lemma in₁₂_iff : (graph t).Adj (in₁ b) (in₂ c) ↔ ∃ a, (a, b, c) ∈ t := |
| 81 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₁₂ h⟩ |
| 82 | +@[simp] lemma in₂₁_iff : (graph t).Adj (in₂ c) (in₁ b) ↔ ∃ a, (a, b, c) ∈ t := |
| 83 | + ⟨by rintro ⟨⟩; exact ⟨_, ‹_›⟩, fun ⟨_, h⟩ ↦ in₂₁ h⟩ |
| 84 | + |
| 85 | +lemma in₀₁_iff' : |
| 86 | + (graph t).Adj (in₀ a) (in₁ b) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.1 = a ∧ x.2.1 = b where |
| 87 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 88 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 89 | +lemma in₁₀_iff' : |
| 90 | + (graph t).Adj (in₁ b) (in₀ a) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.2.1 = b ∧ x.1 = a where |
| 91 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 92 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 93 | +lemma in₀₂_iff' : |
| 94 | + (graph t).Adj (in₀ a) (in₂ c) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.1 = a ∧ x.2.2 = c where |
| 95 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 96 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 97 | +lemma in₂₀_iff' : |
| 98 | + (graph t).Adj (in₂ c) (in₀ a) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.2.2 = c ∧ x.1 = a where |
| 99 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 100 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 101 | +lemma in₁₂_iff' : |
| 102 | + (graph t).Adj (in₁ b) (in₂ c) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.2.1 = b ∧ x.2.2 = c where |
| 103 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 104 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 105 | +lemma in₂₁_iff' : |
| 106 | + (graph t).Adj (in₂ c) (in₁ b) ↔ ∃ x : α × β × γ, x ∈ t ∧ x.2.2 = c ∧ x.2.1 = b where |
| 107 | + mp := by rintro ⟨⟩; exact ⟨_, ‹_›, by simp⟩ |
| 108 | + mpr := by rintro ⟨⟨a, b, c⟩, h, rfl, rfl⟩; constructor; assumption |
| 109 | + |
| 110 | +end Graph |
| 111 | + |
| 112 | +open Graph |
| 113 | + |
| 114 | +/-- Predicate on the triangle indices for the explicit triangles to be edge-disjoint. -/ |
| 115 | +class ExplicitDisjoint (t : Finset (α × β × γ)) : Prop where |
| 116 | + inj₀ : ∀ ⦃a b c a'⦄, (a, b, c) ∈ t → (a', b, c) ∈ t → a = a' |
| 117 | + inj₁ : ∀ ⦃a b c b'⦄, (a, b, c) ∈ t → (a, b', c) ∈ t → b = b' |
| 118 | + inj₂ : ∀ ⦃a b c c'⦄, (a, b, c) ∈ t → (a, b, c') ∈ t → c = c' |
| 119 | + |
| 120 | +/-- Predicate on the triangle indices for there to be no accidental triangle. |
| 121 | +
|
| 122 | +Note that we cheat a bit, since the exact translation of this informal description would have |
| 123 | +`(a', b', c') ∈ t` as a conclusion rather than `a = a' ∨ b = b' ∨ c = c'`. Those conditions are |
| 124 | +equivalent when the explicit triangles are edge-disjoint (which is the case we care about). -/ |
| 125 | +class NoAccidental (t : Finset (α × β × γ)) : Prop where |
| 126 | + eq_or_eq_or_eq : ∀ ⦃a a' b b' c c'⦄, (a', b, c) ∈ t → (a, b', c) ∈ t → (a, b, c') ∈ t → |
| 127 | + a = a' ∨ b = b' ∨ c = c' |
| 128 | + |
| 129 | +section DecidableEq |
| 130 | +variable [DecidableEq α] [DecidableEq β] [DecidableEq γ] |
| 131 | + |
| 132 | +instance graph.instDecidableRelAdj : DecidableRel (graph t).Adj |
| 133 | + | in₀ _a, in₀ _a' => Decidable.isFalse not_in₀₀ |
| 134 | + | in₀ _a, in₁ _b' => decidable_of_iff' _ in₀₁_iff' |
| 135 | + | in₀ _a, in₂ _c' => decidable_of_iff' _ in₀₂_iff' |
| 136 | + | in₁ _b, in₀ _a' => decidable_of_iff' _ in₁₀_iff' |
| 137 | + | in₁ _b, in₁ _b' => Decidable.isFalse not_in₁₁ |
| 138 | + | in₁ _b, in₂ _b' => decidable_of_iff' _ in₁₂_iff' |
| 139 | + | in₂ _c, in₀ _a' => decidable_of_iff' _ in₂₀_iff' |
| 140 | + | in₂ _c, in₁ _b' => decidable_of_iff' _ in₂₁_iff' |
| 141 | + | in₂ _c, in₂ _b' => Decidable.isFalse not_in₂₂ |
| 142 | + |
| 143 | +/-- This lemma reorders the elements of a triangle in the tripartite graph. It turns a triangle |
| 144 | +`{x, y, z}` into a triangle `{a, b, c}` where `a : α `, `b : β`, `c : γ`. -/ |
| 145 | + lemma graph_triple ⦃x y z⦄ : |
| 146 | + (graph t).Adj x y → (graph t).Adj x z → (graph t).Adj y z → ∃ a b c, |
| 147 | + ({in₀ a, in₁ b, in₂ c} : Finset (α ⊕ β ⊕ γ)) = {x, y, z} ∧ (graph t).Adj (in₀ a) (in₁ b) ∧ |
| 148 | + (graph t).Adj (in₀ a) (in₂ c) ∧ (graph t).Adj (in₁ b) (in₂ c) := by |
| 149 | + rintro (_ | _ | _) (_ | _ | _) (_ | _ | _) <;> |
| 150 | + refine ⟨_, _, _, by ext; simp only [Finset.mem_insert, Finset.mem_singleton]; try tauto, |
| 151 | + ?_, ?_, ?_⟩ <;> constructor <;> assumption |
| 152 | + |
| 153 | +/-- The map that turns a triangle index into an explicit triangle. -/ |
| 154 | +@[simps] def toTriangle : α × β × γ ↪ Finset (α ⊕ β ⊕ γ) where |
| 155 | + toFun x := {in₀ x.1, in₁ x.2.1, in₂ x.2.2} |
| 156 | + inj' := fun ⟨a, b, c⟩ ⟨a', b', c'⟩ ↦ by simpa only [Finset.Subset.antisymm_iff, Finset.subset_iff, |
| 157 | + mem_insert, mem_singleton, forall_eq_or_imp, forall_eq, Prod.mk.inj_iff, or_false, false_or, |
| 158 | + in₀, in₁, in₂, Sum.inl.inj_iff, Sum.inr.inj_iff] using And.left |
| 159 | + |
| 160 | +lemma toTriangle_is3Clique (hx : x ∈ t) : (graph t).IsNClique 3 (toTriangle x) := by |
| 161 | + simp only [toTriangle_apply, is3Clique_triple_iff, in₀₁_iff, in₀₂_iff, in₁₂_iff] |
| 162 | + exact ⟨⟨_, hx⟩, ⟨_, hx⟩, _, hx⟩ |
| 163 | + |
| 164 | +lemma exists_mem_toTriangle {x y : α ⊕ β ⊕ γ} (hxy : (graph t).Adj x y) : |
| 165 | + ∃ z ∈ t, x ∈ toTriangle z ∧ y ∈ toTriangle z := by cases hxy <;> exact ⟨_, ‹_›, by simp⟩ |
| 166 | + |
| 167 | +nonrec lemma is3Clique_iff [NoAccidental t] {s : Finset (α ⊕ β ⊕ γ)} : |
| 168 | + (graph t).IsNClique 3 s ↔ ∃ x, x ∈ t ∧ toTriangle x = s := by |
| 169 | + refine ⟨fun h ↦ ?_, ?_⟩ |
| 170 | + · rw [is3Clique_iff] at h |
| 171 | + obtain ⟨x, y, z, hxy, hxz, hyz, rfl⟩ := h |
| 172 | + obtain ⟨a, b, c, habc, hab, hac, hbc⟩ := graph_triple hxy hxz hyz |
| 173 | + refine ⟨(a, b, c), ?_, habc⟩ |
| 174 | + obtain ⟨c', hc'⟩ := in₀₁_iff.1 hab |
| 175 | + obtain ⟨b', hb'⟩ := in₀₂_iff.1 hac |
| 176 | + obtain ⟨a', ha'⟩ := in₁₂_iff.1 hbc |
| 177 | + obtain rfl | rfl | rfl := NoAccidental.eq_or_eq_or_eq ha' hb' hc' <;> assumption |
| 178 | + · rintro ⟨x, hx, rfl⟩ |
| 179 | + exact toTriangle_is3Clique hx |
| 180 | + |
| 181 | +lemma toTriangle_surjOn [NoAccidental t] : |
| 182 | + (t : Set (α × β × γ)).SurjOn toTriangle ((graph t).cliqueSet 3) := fun _ ↦ is3Clique_iff.1 |
| 183 | + |
| 184 | +variable (t) |
| 185 | + |
| 186 | +lemma map_toTriangle_disjoint [ExplicitDisjoint t] : |
| 187 | + (t.map toTriangle : Set (Finset (α ⊕ β ⊕ γ))).Pairwise |
| 188 | + fun x y ↦ (x ∩ y : Set (α ⊕ β ⊕ γ)).Subsingleton := by |
| 189 | + clear x |
| 190 | + intro |
| 191 | + simp only [Finset.coe_map, Set.mem_image, Finset.mem_coe, Prod.exists, Ne, |
| 192 | + forall_exists_index, and_imp] |
| 193 | + rintro a b c habc rfl e x y z hxyz rfl h' |
| 194 | + have := ne_of_apply_ne _ h' |
| 195 | + simp only [Ne, Prod.mk.inj_iff, not_and] at this |
| 196 | + simp only [toTriangle_apply, in₀, in₁, in₂, Set.mem_inter_iff, mem_insert, mem_singleton, |
| 197 | + mem_coe, and_imp, Sum.forall, or_false, forall_eq, false_or, eq_self_iff_true, imp_true_iff, |
| 198 | + true_and, and_true, Set.Subsingleton] |
| 199 | + suffices ¬ (a = x ∧ b = y) ∧ ¬ (a = x ∧ c = z) ∧ ¬ (b = y ∧ c = z) by aesop |
| 200 | + refine ⟨?_, ?_, ?_⟩ |
| 201 | + · rintro ⟨rfl, rfl⟩ |
| 202 | + exact this rfl rfl (ExplicitDisjoint.inj₂ habc hxyz) |
| 203 | + · rintro ⟨rfl, rfl⟩ |
| 204 | + exact this rfl (ExplicitDisjoint.inj₁ habc hxyz) rfl |
| 205 | + · rintro ⟨rfl, rfl⟩ |
| 206 | + exact this (ExplicitDisjoint.inj₀ habc hxyz) rfl rfl |
| 207 | + |
| 208 | +lemma cliqueSet_eq_image [NoAccidental t] : (graph t).cliqueSet 3 = toTriangle '' t := by |
| 209 | + ext; exact is3Clique_iff |
| 210 | + |
| 211 | +section Fintype |
| 212 | +variable [Fintype α] [Fintype β] [Fintype γ] |
| 213 | + |
| 214 | +lemma cliqueFinset_eq_image [NoAccidental t] : (graph t).cliqueFinset 3 = t.image toTriangle := |
| 215 | + coe_injective $ by push_cast; exact cliqueSet_eq_image _ |
| 216 | + |
| 217 | +lemma cliqueFinset_eq_map [NoAccidental t] : (graph t).cliqueFinset 3 = t.map toTriangle := by |
| 218 | + simp [cliqueFinset_eq_image, map_eq_image] |
| 219 | + |
| 220 | +@[simp] lemma card_triangles [NoAccidental t] : ((graph t).cliqueFinset 3).card = t.card := by |
| 221 | + rw [cliqueFinset_eq_map, card_map] |
| 222 | + |
| 223 | +lemma farFromTriangleFree [ExplicitDisjoint t] {ε : 𝕜} |
| 224 | + (ht : ε * ((Fintype.card α + Fintype.card β + Fintype.card γ) ^ 2 : ℕ) ≤ t.card) : |
| 225 | + (graph t).FarFromTriangleFree ε := |
| 226 | + farFromTriangleFree_of_disjoint_triangles (t.map toTriangle) |
| 227 | + (map_subset_iff_subset_preimage.2 fun x hx ↦ by simpa using toTriangle_is3Clique hx) |
| 228 | + (map_toTriangle_disjoint t) $ by simpa [add_assoc] using ht |
| 229 | + |
| 230 | +end Fintype |
| 231 | +end DecidableEq |
| 232 | + |
| 233 | +variable (t) |
| 234 | + |
| 235 | +lemma locallyLinear [ExplicitDisjoint t] [NoAccidental t] : (graph t).LocallyLinear := by |
| 236 | + classical |
| 237 | + refine ⟨?_, fun x y hxy ↦ ?_⟩ |
| 238 | + · unfold EdgeDisjointTriangles |
| 239 | + convert map_toTriangle_disjoint t |
| 240 | + rw [cliqueSet_eq_image, coe_map] |
| 241 | + · obtain ⟨z, hz, hxy⟩ := exists_mem_toTriangle hxy |
| 242 | + exact ⟨_, toTriangle_is3Clique hz, hxy⟩ |
| 243 | + |
| 244 | +end TripartiteFromTriangles |
| 245 | +end SimpleGraph |
0 commit comments