Skip to content

Commit 67b6f4e

Browse files
feat(Combinatorics/SimpleGraph): define completeEquipartiteGraph (leanprover-community#27597)
Define the complete equipartite graph in `r` parts each of *equal* size `t` such that two vertices are adjacent if and only if they are in different parts. These graphs are typically denoted by $$K_r(t)$$.
1 parent 3fc9f7c commit 67b6f4e

4 files changed

Lines changed: 179 additions & 0 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Coloring.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ noncomputable instance [Fintype V] [Fintype α] : Fintype (Coloring G α) := by
121121
change Fintype (RelHom G.Adj (completeGraph α).Adj)
122122
apply Fintype.ofInjective _ RelHom.coe_fn_injective
123123

124+
instance [DecidableEq α] {c : α} :
125+
DecidablePred (· ∈ C.colorClass c) :=
126+
inferInstanceAs <| DecidablePred (· ∈ { v | C v = c })
127+
124128
variable (G)
125129

126130
/-- Whether a graph can be colored by at most `n` colors. -/

Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: John Talbot, Lian Bremner Tattersall
55
-/
66
import Mathlib.Combinatorics.SimpleGraph.Coloring
7+
import Mathlib.Combinatorics.SimpleGraph.Copy
8+
import Mathlib.Combinatorics.SimpleGraph.DegreeSum
79
import Mathlib.Combinatorics.SimpleGraph.Hasse
10+
import Mathlib.Combinatorics.SimpleGraph.Turan
811

912
/-!
1013
# Complete Multipartite Graphs
@@ -27,15 +30,37 @@ A graph is complete multipartite iff non-adjacency is transitive.
2730
* See also: `Mathlib/Combinatorics/SimpleGraph/FiveWheelLike.lean`
2831
`colorable_iff_isCompleteMultipartite_of_maximal_cliqueFree` a maximally `r + 1`- cliquefree graph
2932
is `r`-colorable iff it is complete-multipartite.
33+
34+
* `SimpleGraph.completeEquipartiteGraph`: the **complete equipartite graph** in parts of *equal*
35+
size such that two vertices are adjacent if and only if they are in different parts.
36+
37+
## Implementation Notes
38+
39+
The definition of `completeEquipartiteGraph` is similar to `completeMultipartiteGraph`
40+
except that `Sigma.fst` is replaced by `Prod.fst` in the definition. The difference is that the
41+
former vertices are a product type whereas the latter vertices are a *dependent* product type.
42+
43+
While `completeEquipartiteGraph r t` could have been defined as the specialisation
44+
`completeMultipartiteGraph (const (Fin r) (Fin t))` (or `turanGraph (r * t) r`), it is convenient
45+
to instead have a *non-dependent* *product* type for the vertices.
46+
47+
See `completeEquipartiteGraph.completeMultipartiteGraph`, `completeEquipartiteGraph.turanGraph`
48+
for the isomorphisms between a `completeEquipartiteGraph` and a corresponding
49+
`completeMultipartiteGraph`, `turanGraph`.
3050
-/
3151

52+
open Finset Fintype
53+
3254
universe u
3355
namespace SimpleGraph
3456
variable {α : Type u}
3557

3658
/-- `G` is `IsCompleteMultipartite` iff non-adjacency is transitive -/
3759
def IsCompleteMultipartite (G : SimpleGraph α) : Prop := Transitive (¬ G.Adj · ·)
3860

61+
theorem bot_isCompleteMultipartite : (⊥ : SimpleGraph α).IsCompleteMultipartite := by
62+
simp [IsCompleteMultipartite, Transitive]
63+
3964
variable {G : SimpleGraph α}
4065
/-- The setoid given by non-adjacency -/
4166
def IsCompleteMultipartite.setoid (h : G.IsCompleteMultipartite) : Setoid α :=
@@ -162,4 +187,136 @@ theorem IsCompleteMultipartite.comap {β : Type*} {H : SimpleGraph β} (f : H
162187
exact not_isCompleteMultipartite_of_pathGraph3ComplEmbedding
163188
<| f.comp (pathGraph3ComplEmbeddingOf h)
164189

190+
section CompleteEquipartiteGraph
191+
192+
variable {r t : ℕ}
193+
194+
/-- The **complete equipartite graph** in `r` parts each of *equal* size `t` such that two
195+
vertices are adjacent if and only if they are in different parts, often denoted $K_r(t)$.
196+
197+
This is isomorphic to a corresponding `completeMultipartiteGraph` and `turanGraph`. The difference
198+
is that the former vertices are a product type.
199+
200+
See `completeEquipartiteGraph.completeMultipartiteGraph`, `completeEquipartiteGraph.turanGraph`. -/
201+
abbrev completeEquipartiteGraph (r t : ℕ) : SimpleGraph (Fin r × Fin t) :=
202+
SimpleGraph.comap Prod.fst ⊤
203+
204+
lemma completeEquipartiteGraph_adj {v w} :
205+
(completeEquipartiteGraph r t).Adj v w ↔ v.1 ≠ w.1 := by rfl
206+
207+
/-- A `completeEquipartiteGraph` is isomorphic to a corresponding `completeMultipartiteGraph`.
208+
209+
The difference is that the former vertices are a product type whereas the latter vertices are a
210+
*dependent* product type. -/
211+
def completeEquipartiteGraph.completeMultipartiteGraph :
212+
completeEquipartiteGraph r t ≃g completeMultipartiteGraph (Function.const (Fin r) (Fin t)) :=
213+
{ (Equiv.sigmaEquivProd (Fin r) (Fin t)).symm with map_rel_iff' := by simp }
214+
215+
/-- A `completeEquipartiteGraph` is isomorphic to a corresponding `turanGraph`.
216+
217+
The difference is that the former vertices are a product type whereas the latter vertices are
218+
not. -/
219+
def completeEquipartiteGraph.turanGraph :
220+
completeEquipartiteGraph r t ≃g turanGraph (r * t) r where
221+
toFun := by
222+
refine fun v ↦ ⟨v.2 * r + v.1, ?_⟩
223+
conv_rhs =>
224+
rw [← Nat.sub_one_add_one_eq_of_pos v.2.pos, Nat.mul_add_one, mul_comm r (t - 1)]
225+
exact add_lt_add_of_le_of_lt (Nat.mul_le_mul_right r (Nat.le_pred_of_lt v.2.prop)) v.1.prop
226+
invFun := by
227+
refine fun v ↦ (⟨v % r, ?_⟩, ⟨v / r, ?_⟩)
228+
· have ⟨hr, _⟩ := CanonicallyOrderedAdd.mul_pos.mp v.pos
229+
exact Nat.mod_lt v hr
230+
· exact Nat.div_lt_of_lt_mul v.prop
231+
left_inv v := by
232+
refine Prod.ext (Fin.ext ?_) (Fin.ext ?_)
233+
· conv =>
234+
enter [1, 1, 1, 1, 1]
235+
rw [Nat.mul_add_mod_self_right]
236+
exact Nat.mod_eq_of_lt v.1.prop
237+
· apply le_antisymm
238+
· rw [Nat.div_le_iff_le_mul_add_pred v.1.pos, mul_comm r ↑v.2]
239+
exact Nat.add_le_add_left (Nat.le_pred_of_lt v.1.prop) (↑v.2 * r)
240+
· rw [Nat.le_div_iff_mul_le v.1.pos]
241+
exact Nat.le_add_right (↑v.2 * r) ↑v.1
242+
right_inv v := Fin.ext (Nat.div_add_mod' v r)
243+
map_rel_iff' {v w} := by
244+
rw [turanGraph_adj, Equiv.coe_fn_mk, Nat.mul_add_mod_self_right, Nat.mod_eq_of_lt v.1.prop,
245+
Nat.mul_add_mod_self_right, Nat.mod_eq_of_lt w.1.prop, ← Fin.ext_iff.ne,
246+
← completeEquipartiteGraph_adj]
247+
248+
/-- `completeEquipartiteGraph r t` contains no edges when `r ≤ 1` or `t = 0`. -/
249+
lemma completeEquipartiteGraph_eq_bot_iff :
250+
completeEquipartiteGraph r t = ⊥ ↔ r ≤ 1 ∨ t = 0 := by
251+
rw [← not_iff_not, not_or, ← ne_eq, ← edgeSet_nonempty, not_le, ← Nat.succ_le_iff,
252+
← Fin.nontrivial_iff_two_le, ← ne_eq, ← Nat.pos_iff_ne_zero, Fin.pos_iff_nonempty]
253+
refine ⟨fun ⟨e, he⟩ ↦ ?_, fun ⟨⟨i₁, i₂, hv⟩, ⟨x⟩⟩ ↦ ?_⟩
254+
· induction' e with v₁ v₂
255+
rw [mem_edgeSet, completeEquipartiteGraph_adj] at he
256+
exact ⟨⟨v₁.1, v₂.1, he⟩, ⟨v₁.2⟩⟩
257+
· use s((i₁, x), (i₂, x))
258+
rw [mem_edgeSet, completeEquipartiteGraph_adj]
259+
exact hv
260+
261+
theorem completeEquipartiteGraph.isCompleteMultipartite :
262+
(completeEquipartiteGraph r t).IsCompleteMultipartite := by
263+
rcases t.eq_zero_or_pos with ht_eq0 | ht_pos
264+
· rw [completeEquipartiteGraph_eq_bot_iff.mpr (Or.inr ht_eq0)]
265+
exact bot_isCompleteMultipartite
266+
· rw [isCompleteMultipartite_iff]
267+
use (Fin r), Function.const (Fin r) (Fin t)
268+
simp_rw [Function.const_apply, exists_prop]
269+
exact ⟨Function.const (Fin r) (Fin.pos_iff_nonempty.mp ht_pos),
270+
⟨completeEquipartiteGraph.completeMultipartiteGraph⟩⟩
271+
272+
theorem neighborSet_completeEquipartiteGraph (v) :
273+
(completeEquipartiteGraph r t).neighborSet v = {v.1}ᶜ ×ˢ Set.univ := by
274+
ext; simp [ne_comm]
275+
276+
theorem neighborFinset_completeEquipartiteGraph (v) :
277+
(completeEquipartiteGraph r t).neighborFinset v = {v.1}ᶜ ×ˢ univ := by
278+
ext; simp [ne_comm]
279+
280+
theorem degree_completeEquipartiteGraph (v) :
281+
(completeEquipartiteGraph r t).degree v = (r - 1) * t := by
282+
rw [← card_neighborFinset_eq_degree, neighborFinset_completeEquipartiteGraph v,
283+
card_product, card_compl, card_singleton, Fintype.card_fin, card_univ, Fintype.card_fin]
284+
285+
theorem card_edgeFinset_completeEquipartiteGraph :
286+
#(completeEquipartiteGraph r t).edgeFinset = r.choose 2 * t ^ 2 := by
287+
rw [← mul_right_inj' two_ne_zero, ← sum_degrees_eq_twice_card_edges]
288+
conv_lhs =>
289+
rhs; intro v
290+
rw [degree_completeEquipartiteGraph v]
291+
rw [sum_const, smul_eq_mul, card_univ, card_prod, Fintype.card_fin, Fintype.card_fin]
292+
conv_rhs =>
293+
rw [← Nat.mul_assoc, Nat.choose_two_right, Nat.mul_div_cancel' r.even_mul_pred_self.two_dvd]
294+
rw [← mul_assoc, mul_comm r _, mul_assoc t _ _, mul_comm t, mul_assoc _ t, ← pow_two]
295+
296+
variable [Fintype α]
297+
298+
/-- Every `n`-colorable graph is contained in a `completeEquipartiteGraph` in `n` parts (as long
299+
as the parts are at least as large as the largest color class). -/
300+
theorem isContained_completeEquipartiteGraph_of_colorable {n : ℕ} (C : G.Coloring (Fin n))
301+
(t : ℕ) (h : ∀ c, card (C.colorClass c) ≤ t) : G ⊑ completeEquipartiteGraph n t := by
302+
have (c : Fin n) : Nonempty (C.colorClass c ↪ Fin t) := by
303+
rw [Function.Embedding.nonempty_iff_card_le, Fintype.card_fin]
304+
exact h c
305+
have F (c : Fin n) := Classical.arbitrary (C.colorClass c ↪ Fin t)
306+
have hF {c₁ c₂ v₁ v₂} (hc : c₁ = c₂) (hv : F c₁ v₁ = F c₂ v₂) : v₁.val = v₂.val := by
307+
let v₁' : C.colorClass c₂ := ⟨v₁, by simp [← hc]⟩
308+
have hv' : F c₁ v₁ = F c₂ v₁' := by
309+
apply congr_heq
310+
· rw [hc]
311+
· rw [Subtype.heq_iff_coe_eq]
312+
simp [hc]
313+
rw [hv'] at hv
314+
simpa [Subtype.ext_iff] using (F c₂).injective hv
315+
use ⟨fun v ↦ (C v, F (C v) ⟨v, C.mem_colorClass v⟩), C.valid⟩
316+
intro v w h
317+
rw [Prod.mk.injEq] at h
318+
exact hF h.1 h.2
319+
320+
end CompleteEquipartiteGraph
321+
165322
end SimpleGraph

Mathlib/Combinatorics/SimpleGraph/ConcreteColorings.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Iván Renison
55
-/
66
import Mathlib.Combinatorics.SimpleGraph.Circulant
77
import Mathlib.Combinatorics.SimpleGraph.Coloring
8+
import Mathlib.Combinatorics.SimpleGraph.CompleteMultipartite
89
import Mathlib.Combinatorics.SimpleGraph.Hasse
910
import Mathlib.Data.Fin.Parity
1011

@@ -156,6 +157,20 @@ theorem chromaticNumber_cycleGraph_of_odd (n : ℕ) (h : 2 ≤ n) (hOdd : Odd n)
156157
rw [← hn3]
157158
exact Walk.three_le_chromaticNumber_of_odd_loop w hOdd'
158159

160+
section CompleteEquipartiteGraph
161+
162+
variable {r t : ℕ}
163+
164+
/-- The injection `(x₁, x₂) ↦ x₁` is always a `r`-coloring of a `completeEquipartiteGraph r ·`. -/
165+
def Coloring.completeEquipartiteGraph :
166+
(completeEquipartiteGraph r t).Coloring (Fin r) := ⟨Prod.fst, id⟩
167+
168+
/-- The `completeEquipartiteGraph r t` is always `r`-colorable. -/
169+
theorem completeEquipartiteGraph_colorable :
170+
(completeEquipartiteGraph r t).Colorable r := ⟨Coloring.completeEquipartiteGraph⟩
171+
172+
end CompleteEquipartiteGraph
173+
159174
open Walk
160175
lemma two_colorable_iff_forall_loop_even {α : Type*} {G : SimpleGraph α} :
161176
G.Colorable 2 ↔ ∀ u, ∀ (w : G.Walk u u), Even w.length := by

Mathlib/Combinatorics/SimpleGraph/Turan.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ lemma IsTuranMaximal.le_iff_eq (hG : G.IsTuranMaximal r) (hH : H.CliqueFree (r +
6363
/-- The canonical `r + 1`-cliquefree Turán graph on `n` vertices. -/
6464
def turanGraph (n r : ℕ) : SimpleGraph (Fin n) where Adj v w := v % r ≠ w % r
6565

66+
lemma turanGraph_adj {v w} :
67+
(turanGraph n r).Adj v w ↔ v % r ≠ w % r := by rfl
68+
6669
instance turanGraph.instDecidableRelAdj : DecidableRel (turanGraph n r).Adj := by
6770
dsimp only [turanGraph]; infer_instance
6871

0 commit comments

Comments
 (0)