Skip to content

Commit 2dc41f3

Browse files
Redefine parts
1 parent b8d7ef2 commit 2dc41f3

1 file changed

Lines changed: 116 additions & 71 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean

Lines changed: 116 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -337,61 +337,94 @@ variable {V : Type*} {G : SimpleGraph V}
337337
/-- A complete equipartite subgraph in `r` parts each of size `t` in `G` is `r` subsets
338338
of vertices each of size `t` such that vertices in distinct subsets are adjacent. -/
339339
structure CompleteEquipartiteSubgraph (G : SimpleGraph V) (r t : ℕ) where
340-
/-- The `r` parts. -/
341-
parts : Fin r → Finset V
342-
/-- Each part is size `t`. -/
343-
card_parts (i : Fin r) : #(parts i) = t
344-
/-- Vertices in distinct parts are adjacent. -/
345-
isCompleteBetween : Pairwise fun ⦃i₁ i₂⦄ ↦ G.IsCompleteBetween (parts i₁) (parts i₂)
340+
/-- The parts in a complete equipartite subgraph. -/
341+
parts : Finset (Finset V)
342+
/-- There are `r` parts or `t = 0`. -/
343+
card_parts : #parts = r ∨ t = 0
344+
/-- There are `t` vertices in each part. -/
345+
card_mem_parts {p} : p ∈ parts → #p = t
346+
/-- The vertices in distinct parts are adjacent. -/
347+
isCompleteBetween : (parts : Set (Finset V)).Pairwise (G.IsCompleteBetween · ·)
346348

347349
variable {r t : ℕ} (K : G.CompleteEquipartiteSubgraph r t)
348350

349351
namespace CompleteEquipartiteSubgraph
350352

351353
/-- The parts in a complete equipartite subgraph are pairwise disjoint. -/
352-
theorem pairwise_disjoint_on_parts : Pairwise (Disjoint on K.parts) :=
353-
fun _ _ hne ↦ disjoint_left.mpr fun _ h₁ h₂ ↦ (G.loopless _) (K.isCompleteBetween hne h₁ h₂)
354+
theorem disjoint : (K.parts : Set (Finset V)).Pairwise Disjoint :=
355+
fun _ h₁ _ h₂ hne ↦ disjoint_left.mpr fun _ h₁' h₂' ↦
356+
(G.loopless _) (K.isCompleteBetween h₁ h₂ hne h₁' h₂')
354357

355358
/-- The finset of vertices in a complete equipartite subgraph. -/
356-
abbrev verts : Finset V :=
357-
univ.disjiUnion K.parts (K.pairwise_disjoint_on_parts.set_pairwise (SetLike.coe univ))
359+
def verts : Finset V := K.parts.disjiUnion id K.disjoint
360+
361+
open Classical in
362+
/-- The finset of vertices in a complete equipartite subgraph as a `biUnion`. -/
363+
lemma verts_eq_biUnion : K.verts = K.parts.biUnion id := by rw [verts, disjiUnion_eq_biUnion]
358364

359365
/-- There are `r * t` vertices in a complete equipartite subgraph with `r` parts of size `t`. -/
360-
theorem card_verts : #K.verts = r * t := by simp [verts, card_parts]
366+
theorem card_verts : #K.verts = r * t := by
367+
simp_rw [verts, card_disjiUnion, id_eq, sum_congr rfl fun _ ↦ K.card_mem_parts, sum_const,
368+
smul_eq_mul, mul_eq_mul_right_iff]
369+
exact K.card_parts
361370

362371
/-- A complete equipartite subgraph gives rise to a copy of a complete equipartite graph. -/
363372
noncomputable def toCopy : Copy (completeEquipartiteGraph r t) G := by
364-
have (i : Fin r) : Nonempty (Fin t ↪ K.parts i) := by
365-
rw [Embedding.nonempty_iff_card_le, Fintype.card_fin, card_coe, K.card_parts i]
366-
have fᵣ (i : Fin r) : Fin t ↪ K.parts i := Classical.arbitrary (Fin t ↪ K.parts i)
367-
let f : (Fin r) × (Fin t) ↪ V := by
368-
use fun (i, x) ↦ fᵣ i x
369-
intro (i₁, x₁) (i₂, x₂) heq
370-
rw [Prod.mk.injEq]
371-
contrapose! heq with hne
372-
rcases eq_or_ne i₁ i₂ with heq | hne
373-
· rw [heq, ← Subtype.ext_iff.ne]
374-
exact (fᵣ i₂).injective.ne (hne heq)
375-
· exact (K.isCompleteBetween hne (fᵣ i₁ x₁).prop (fᵣ i₂ x₂).prop).ne
376-
use ⟨f, ?_⟩, f.injective
377-
intro (i₁, x₁) (i₂, x₂) hne
378-
exact K.isCompleteBetween hne (fᵣ i₁ x₁).prop (fᵣ i₂ x₂).prop
373+
by_cases ht : t = 0
374+
· rw [completeEquipartiteGraph_eq_bot_iff.mpr <| .inr ht]
375+
have : IsEmpty (Fin r × Fin t) := by simp [ht, Fin.isEmpty]
376+
exact Copy.bot .ofIsEmpty
377+
· have : Nonempty (Fin r ↪ K.parts) := by
378+
rw [Embedding.nonempty_iff_card_le,
379+
Fintype.card_fin, card_coe, K.card_parts.resolve_right ht]
380+
let fᵣ : Fin r ↪ K.parts := Classical.arbitrary (Fin r ↪ K.parts)
381+
have (p : K.parts) : Nonempty (Fin t ↪ p) := by
382+
rw [Embedding.nonempty_iff_card_le, Fintype.card_fin, card_coe, K.card_mem_parts p.prop]
383+
let fₜ (p : K.parts) : Fin t ↪ p :=
384+
Classical.arbitrary (Fin t ↪ p)
385+
let f : (Fin r) × (Fin t) ↪ V := by
386+
use fun (i, j) ↦ fₜ (fᵣ i) j
387+
intro (i₁, j₁) (i₂, j₂) heq
388+
rw [Prod.mk.injEq]
389+
contrapose! heq with hne
390+
rcases eq_or_ne i₁ i₂ with heq | hne
391+
· rw [heq, ← Subtype.ext_iff.ne]
392+
exact (fₜ _).injective.ne (hne heq)
393+
· refine (K.isCompleteBetween (fᵣ _).prop (fᵣ _).prop ?_ (fₜ _ _).prop (fₜ _ _).prop).ne
394+
exact Subtype.ext_iff.ne.mp <| fᵣ.injective.ne hne
395+
refine ⟨⟨f, fun hne ↦ ?_⟩, f.injective⟩
396+
refine K.isCompleteBetween (fᵣ _).prop (fᵣ _).prop ?_ (fₜ _ _).prop (fₜ _ _).prop
397+
exact Subtype.ext_iff.ne.mp <| fᵣ.injective.ne hne
379398

380399
/-- A copy of a complete equipartite graph identifies a complete equipartite subgraph. -/
381-
def ofCopy (f : Copy (completeEquipartiteGraph r t) G) : G.CompleteEquipartiteSubgraph r t where
382-
parts i := by
383-
let fᵣ (i : Fin r) : Fin t ↪ V := by
384-
use fun x ↦ f (i, x)
385-
intro _ _ h
386-
simpa using f.injective h
387-
exact univ.map (fᵣ i)
388-
card_parts i := by simp
389-
isCompleteBetween _ _ hne _ h₁ _ h₂ := by
390-
simp_rw [mem_coe, mem_map] at h₁ h₂
391-
obtain ⟨_, _, h₁⟩ := h₁
392-
obtain ⟨_, _, h₂⟩ := h₂
393-
rw [← h₁, ← h₂]
394-
exact f.toHom.map_adj hne
400+
def ofCopy (f : Copy (completeEquipartiteGraph r t) G) : G.CompleteEquipartiteSubgraph r t := by
401+
by_cases ht : t = 0
402+
· exact ⟨∅, .inr ht, by simp, by simp⟩
403+
· refine ⟨univ.map ⟨fun i ↦ univ.map ⟨fun j ↦ f (i, j), fun _ _ h ↦ ?_⟩, fun i₁ i₂ h ↦ ?_⟩,
404+
by simp, fun h ↦ ?_, fun _ h₁ _ h₂ hne _ h₁' _ h₂' ↦ ?_⟩
405+
· simpa using f.injective h
406+
· simp_rw [Finset.ext_iff] at h
407+
have : NeZero t := ⟨ht⟩
408+
obtain ⟨_, heq⟩ : ∃ j, f (i₁, j) = f (i₂, 0) := by simpa using h <| f (i₂, 0)
409+
apply f.injective at heq
410+
rw [Prod.mk.injEq] at heq
411+
exact heq.left
412+
· simp_rw [mem_map, mem_univ, Embedding.coeFn_mk, true_and] at h
413+
replace ⟨_, h⟩ := h
414+
simp [← h]
415+
· simp_rw [coe_map, Embedding.coeFn_mk, coe_univ, Set.image_univ, Set.mem_range] at h₁ h₂
416+
replace ⟨_, h₁⟩ := h₁
417+
replace ⟨_, h₂⟩ := h₂
418+
rw [← h₁] at h₁'
419+
rw [← h₂] at h₂'
420+
simp_rw [coe_map, Embedding.coeFn_mk, coe_univ, Set.image_univ, Set.mem_range] at h₁' h₂'
421+
replace ⟨_, h₁'⟩ := h₁'
422+
replace ⟨_, h₂'⟩ := h₂'
423+
rw [← h₁', ← h₂']
424+
apply f.toHom.map_adj
425+
simp_rw [completeEquipartiteGraph_adj]
426+
contrapose! hne with heq
427+
simp_rw [← h₁, ← h₂, heq]
395428

396429
end CompleteEquipartiteSubgraph
397430

@@ -401,38 +434,50 @@ theorem completeEquipartiteGraph_isContained_iff :
401434
completeEquipartiteGraph r t ⊑ G ↔ Nonempty (G.CompleteEquipartiteSubgraph r t) :=
402435
fun ⟨f⟩ ↦ ⟨CompleteEquipartiteSubgraph.ofCopy f⟩, fun ⟨K⟩ ↦ ⟨K.toCopy⟩⟩
403436

404-
/-- Simple graphs contain a copy of a `completeEquipartiteGraph (n + 1) t` iff there exists
405-
`s : Finset V` of size `#s = t` and `K : G.CompleteEquipartiteSubgraph n t` such that the
437+
open Classical in
438+
/-- Simple graphs contain a copy of a `completeEquipartiteGraph (r + 1) t` iff there exists
439+
`s : Finset V` of size `#s = t` and `K : G.CompleteEquipartiteSubgraph r t` such that the
406440
vertices in `s` are adjacent to the vertices in `K`. -/
407-
theorem completeEquipartiteGraph_succ_isContained_iff {n : ℕ} :
408-
completeEquipartiteGraph (n + 1) t ⊑ G
409-
↔ ∃ᵉ (K : G.CompleteEquipartiteSubgraph n t) (s : Finset V),
410-
#s = t ∧ ∀ i, G.IsCompleteBetween (K.parts i) s := by
411-
rw [completeEquipartiteGraph_isContained_iff]
412-
refine ⟨fun ⟨K'⟩ ↦ ?_, fun ⟨K, s, hs, hadj⟩ ↦ ?_⟩
413-
· let K : G.CompleteEquipartiteSubgraph n t := by
414-
refine ⟨fun i ↦ K'.parts i.castSucc, fun i ↦ K'.card_parts i.castSucc, ?_⟩
415-
intro i j hne v₁ hv₁ v₂ hv₂
416-
rw [← Fin.castSucc_inj.ne] at hne
417-
exact K'.isCompleteBetween hne hv₁ hv₂
418-
refine ⟨K, K'.parts (Fin.last n), K'.card_parts (Fin.last n), fun i v₁ hv₁ v₂ hv₂ ↦ ?_⟩
419-
have hne : i.castSucc ≠ Fin.last n := Fin.exists_castSucc_eq.mp ⟨i, rfl⟩
420-
exact K'.isCompleteBetween hne hv₁ hv₂
421-
· refine ⟨fun i ↦ if hi : ↑i < n then K.parts ⟨i, hi⟩ else s, fun i ↦ ?_,
422-
fun i₁ i₂ hne v₁ hv₁ v₂ hv₂ ↦ ?_⟩
423-
· by_cases hi : ↑i < n
424-
· simp [hi, K.card_parts ⟨i, hi⟩]
425-
· simp [hi, hs]
426-
· by_cases hi₁ : ↑i₁ < n <;> by_cases hi₂ : ↑i₂ < n
427-
<;> simp [hi₁, hi₂] at hne hv₁ hv₂ ⊢
428-
· have hne : i₁.castLT hi₁ ≠ i₂.castLT hi₂ := by
429-
simp [Fin.ext_iff, Fin.val_ne_of_ne hne]
430-
exact K.isCompleteBetween hne hv₁ hv₂
431-
· exact hadj ⟨i₁, hi₁⟩ hv₁ hv₂
432-
· exact (hadj ⟨i₂, hi₂⟩ hv₂ hv₁).symm
433-
· absurd hne
434-
rw [Fin.ext_iff, Nat.eq_of_le_of_lt_succ (le_of_not_gt hi₁) i₁.isLt,
435-
Nat.eq_of_le_of_lt_succ (le_of_not_gt hi₂) i₂.isLt]
441+
theorem completeEquipartiteGraph_succ_isContained_iff :
442+
completeEquipartiteGraph (r + 1) t ⊑ G
443+
↔ ∃ᵉ (K : G.CompleteEquipartiteSubgraph r t) (s : Finset V),
444+
#s = t ∧ ∀ p ∈ K.parts, G.IsCompleteBetween p s := by
445+
by_cases ht : t = 0
446+
· have (r' : ℕ) : IsEmpty (Fin r' × Fin t) := by simp [ht, Fin.isEmpty]
447+
have h_bot (r' : ℕ) : completeEquipartiteGraph r' t = ⊥ :=
448+
completeEquipartiteGraph_eq_bot_iff.mpr <| .inr ht
449+
simp_rw [h_bot (r + 1), ht, Finset.card_eq_zero, exists_eq_left, IsCompleteBetween, mem_coe,
450+
notMem_empty, IsEmpty.forall_iff, implies_true, exists_true_iff_nonempty,
451+
← completeEquipartiteGraph_isContained_iff, h_bot r]
452+
exact ⟨fun _ ↦ ⟨Copy.bot .ofIsEmpty⟩, fun _ ↦ ⟨Copy.bot .ofIsEmpty⟩⟩
453+
· rw [completeEquipartiteGraph_isContained_iff]
454+
refine ⟨fun ⟨K'⟩ ↦ ?_, fun ⟨K, s, hs, hadj⟩ ↦ ?_⟩
455+
· obtain ⟨parts, hparts_sub, hparts_card⟩ := K'.parts.exists_subset_card_eq (Nat.pred_le _)
456+
let K : G.CompleteEquipartiteSubgraph r t := by
457+
refine ⟨parts, ?_, fun h ↦ K'.card_mem_parts (hparts_sub h),
458+
fun _ h₁ _ h₂ hne ↦ K'.isCompleteBetween (hparts_sub h₁) (hparts_sub h₂) hne⟩
459+
rw [hparts_card, K'.card_parts.resolve_right ht]
460+
exact .inl (Nat.pred_succ r)
461+
obtain ⟨s, nhs_mem, hs⟩ : ∃ s ∉ K.parts, insert s K.parts = K'.parts := by
462+
refine exists_eq_insert_iff.mpr ⟨hparts_sub, ?_⟩
463+
rw [K.card_parts.resolve_right ht, K'.card_parts.resolve_right ht]
464+
have hs_mem : s ∈ K'.parts := by simp [← hs]
465+
exact ⟨K, s, K'.card_mem_parts hs_mem,
466+
fun _ h ↦ K'.isCompleteBetween (hparts_sub h) hs_mem (ne_of_mem_of_not_mem h nhs_mem)⟩
467+
· refine ⟨K.parts.cons s ?_, ?_, ?_, ?_⟩
468+
· by_contra! hs_mem
469+
obtain ⟨v, hv⟩ : s.Nonempty := by
470+
rw [← Finset.card_pos, hs]
471+
exact Nat.pos_of_ne_zero ht
472+
absurd hadj s hs_mem hv hv
473+
exact G.loopless v
474+
· rw [Finset.card_cons, K.card_parts.resolve_right ht]
475+
exact .inl rfl
476+
· simp_rw [mem_cons, forall_eq_or_imp]
477+
exact ⟨hs, fun p ↦ K.card_mem_parts⟩
478+
· rw [coe_cons]
479+
refine K.isCompleteBetween.insert_of_symmetric ?_ (fun p hp _ ↦ (hadj p hp).symm)
480+
simp_rw [Symmetric, isCompleteBetween_comm, imp_self, implies_true]
436481

437482
end CompleteEquipartiteSubgraph
438483

0 commit comments

Comments
 (0)