@@ -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
338338of vertices each of size `t` such that vertices in distinct subsets are adjacent. -/
339339structure 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
347349variable {r t : ℕ} (K : G.CompleteEquipartiteSubgraph r t)
348350
349351namespace 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. -/
363372noncomputable 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
396429end 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
406440vertices 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
437482end CompleteEquipartiteSubgraph
438483
0 commit comments