@@ -445,4 +445,88 @@ theorem degree_le_between_add_compl (hw : w ∈ sᶜ) :
445445
446446end Between
447447
448+ section BipartiteDoubleCover
449+
450+ /-- `bipartiteDoubleCover G` has two vertices `inl v` and `inr v` for each vertex `v` in `G`
451+ such that `inl v` (`inr v`) is adjacent to `inr w` (`inl w`) iff `v` is adjacent to `w` in `G`. -/
452+ @[simp] def bipartiteDoubleCover (G : SimpleGraph V) : SimpleGraph (V ⊕ V) where
453+ Adj v w := match v, w with
454+ | .inl v', .inr w' | .inr v', .inl w' => G.Adj v' w'
455+ | _, _ => False
456+ symm v w := match v, w with
457+ | .inl _, .inr _ | .inr _, .inl _ => G.adj_symm
458+ | .inl _, .inl _ | .inr _, .inr _ => id
459+
460+ instance [h : DecidableRel G.Adj] : DecidableRel G.bipartiteDoubleCover.Adj :=
461+ fun v w ↦ match v, w with
462+ | .inl _, .inr _ | .inr _, .inl _ => h _ _
463+ | .inl _, .inl _ | .inr _, .inr _ => inferInstanceAs (Decidable False)
464+
465+ /-- The bipartite double cover of `G` is contained in the corresponding complete bipartite graph,
466+ that is, the bipartite double cover of `G` is bipartite. -/
467+ theorem bipartiteDoubleCover_le : G.bipartiteDoubleCover ≤ completeBipartiteGraph V V :=
468+ fun v w hadj ↦ match v, w with
469+ | .inl _, .inr _ | .inr _, .inl _ => by simp
470+ | .inl _, .inl _ | .inr _, .inr _ => by simp at hadj
471+
472+ /-- The bipartite double cover of `G` has twice the number of edges as `G`. -/
473+ theorem bipartiteDoubleCover_card_edgeFinset [Fintype V] [DecidableRel G.Adj] :
474+ #G.bipartiteDoubleCover.edgeFinset = 2 * #G.edgeFinset := by
475+ rw [two_mul_card_edgeFinset, eq_comm]
476+ apply card_bij (fun (v, w) _ ↦ s(.inl v, .inr w)) (fun _ h ↦ by simpa using h)
477+ (fun (_, _) _ (_, _) _ ↦ by simp) (fun e he ↦ ?_)
478+ induction e with | _ v w
479+ rw [Set.mem_toFinset, mem_edgeSet] at he
480+ match v, w with
481+ | .inl _, .inr _ => simpa using he
482+ | .inr _, .inl _ => simpa using he.symm
483+ | .inl _, .inl _ | .inr _, .inr _ => simp at he
484+
485+ /-- If the double cover of `G` contains `completeBipartiteGraph α β`, then `G` also
486+ contains `completeBipartiteGraph α β`. -/
487+ theorem bipartiteDoubleCover_completeBipartiteGraph_isContained
488+ {α β : Type *} [Fintype α] [Fintype β] [Nonempty α] [Nonempty β]
489+ (h : completeBipartiteGraph α β ⊑ G.bipartiteDoubleCover) :
490+ completeBipartiteGraph α β ⊑ G := by
491+ rw [completeBipartiteGraph_isContained_iff] at h ⊢
492+ obtain ⟨left, right, card_left, card_right, h⟩ := h
493+ simp_rw [← card_left, ← card_right]
494+ obtain ⟨l, hl⟩ : left.Nonempty := card_pos.mp <| card_pos.trans_le card_left.ge
495+ obtain ⟨r, hr⟩ : right.Nonempty := card_pos.mp <| card_pos.trans_le card_right.ge
496+ have hmem_left {l'} (hl' : l' ∈ left) : (l.isLeft → l'.isLeft) ∧ (l.isRight → l'.isRight) := by
497+ rcases l with l | l <;> rcases r with r | r <;> rcases l' with l' | l'
498+ all_goals solve | simp | simpa using h hl hr | simpa using h hl' hr
499+ have hmem_right {r'} (hr' : r' ∈ right) : (r.isLeft → r'.isLeft) ∧ (r.isRight → r'.isRight) := by
500+ rcases l with l | l <;> rcases r with r | r <;> rcases r' with r' | r'
501+ all_goals solve | simp | simpa using h hl hr | simpa using h hl hr'
502+ rcases l with l | l <;> rcases r with r | r
503+ · simpa using h hl hr
504+ · refine ⟨left.toLeft, right.toRight, ?_, ?_, fun i hi j hj ↦ ?_⟩
505+ · exact card_bij (fun i _ ↦ .inl i) (fun i hi ↦ by simpa using hi) (fun i hi j hj ↦ by simp)
506+ (fun i hi ↦ ⟨i.getLeft <| (hmem_left hi).left Sum.isLeft_inl, by simp [hi]⟩)
507+ · exact card_bij (fun j hj ↦ .inr j) (fun j hj ↦ by simpa using hj) (fun i hi j hj ↦ by simp)
508+ (fun j hj ↦ ⟨j.getRight <| (hmem_right hj).right Sum.isRight_inr, by simp [hj]⟩)
509+ · rw [mem_coe, mem_toLeft] at hi
510+ rw [mem_coe, mem_toRight] at hj
511+ simpa using h hi hj
512+ · refine ⟨left.toRight, right.toLeft, ?_, ?_, fun i hi j hj ↦ ?_⟩
513+ · exact card_bij (fun i _ ↦ .inr i) (fun i hi ↦ by simpa using hi) (fun i hi j hj ↦ by simp)
514+ (fun i hi ↦ ⟨i.getRight <| (hmem_left hi).right Sum.isRight_inr, by simp [hi]⟩)
515+ · exact card_bij (fun j hj ↦ .inl j) (fun j hj ↦ by simpa using hj) (fun i hi j hj ↦ by simp)
516+ (fun j hj ↦ ⟨j.getLeft <| (hmem_right hj).left Sum.isLeft_inl, by simp [hj]⟩)
517+ · rw [mem_coe, mem_toRight] at hi
518+ rw [mem_coe, mem_toLeft] at hj
519+ simpa using h hi hj
520+ · simpa using h hl hr
521+
522+ theorem bipartiteDoubleCover_isBipartiteWith :
523+ G.bipartiteDoubleCover.IsBipartiteWith {v | v.isLeft} {w | w.isRight} where
524+ disjoint := by simp [Set.disjoint_iff_forall_ne]
525+ mem_of_adj := by simp
526+
527+ theorem bipartiteDoubleCover_isBipartite : G.bipartiteDoubleCover.IsBipartite :=
528+ bipartiteDoubleCover_isBipartiteWith.isBipartite
529+
530+ end BipartiteDoubleCover
531+
448532end SimpleGraph
0 commit comments