|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Vlad Tsyrklevich. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Vlad Tsyrklevich |
| 5 | +-/ |
| 6 | +import Mathlib.Combinatorics.Hall.Basic |
| 7 | +import Mathlib.Combinatorics.SimpleGraph.Bipartite |
| 8 | +import Mathlib.Combinatorics.SimpleGraph.Matching |
| 9 | + |
| 10 | +/-! |
| 11 | +# Hall's Marriage Theorem |
| 12 | +
|
| 13 | +This file derives Hall's Marriage Theorem for bipartite graphs from the combinatorial formulation in |
| 14 | +`Mathlib/Combinatorics/Hall/Basic.lean`. |
| 15 | +
|
| 16 | +## Main statements |
| 17 | +
|
| 18 | +* `exists_isMatching_of_forall_ncard_le`: Hall's marriage theorem for a matching on a single |
| 19 | + partition of a bipartite graph. |
| 20 | +* `exists_isPerfectMatching_of_forall_ncard_le`: Hall's marriage theorem for a perfect matching on a |
| 21 | + bipartite graph. |
| 22 | +
|
| 23 | +## Tags |
| 24 | +
|
| 25 | +Hall's Marriage Theorem |
| 26 | +-/ |
| 27 | + |
| 28 | +open Function |
| 29 | + |
| 30 | +namespace SimpleGraph |
| 31 | + |
| 32 | +variable {V : Type*} {G : SimpleGraph V} |
| 33 | + |
| 34 | +/- Given a partition `p` and a function `f` mapping vertices in `p` to the other partition, create |
| 35 | +the subgraph including only the edges between `x` and `f x` for all `x` in `p`. -/ |
| 36 | +private |
| 37 | +abbrev hall_subgraph {p : Set V} [DecidablePred (· ∈ p)] (f : p → V) (h₁ : ∀ x : p, f x ∉ p) |
| 38 | + (h₂ : ∀ x : p, G.Adj x (f x)) : Subgraph G where |
| 39 | + verts := p ∪ Set.range f |
| 40 | + Adj v w := |
| 41 | + if h : v ∈ p then f ⟨v, h⟩ = w |
| 42 | + else if h : w ∈ p then f ⟨w, h⟩ = v |
| 43 | + else False |
| 44 | + adj_sub {v w} h := by |
| 45 | + repeat' split at h |
| 46 | + · exact h ▸ h₂ ⟨v, by assumption⟩ |
| 47 | + · exact h ▸ h₂ ⟨w, by assumption⟩ |>.symm |
| 48 | + · contradiction |
| 49 | + edge_vert {v w} := by grind |
| 50 | + symm {x y} := by grind |
| 51 | + |
| 52 | +variable [DecidableEq V] [G.LocallyFinite] {p₁ p₂ : Set V} |
| 53 | + |
| 54 | +/-- This is the version of **Hall's marriage theorem** for bipartite graphs that finds a matching |
| 55 | +for a single partition given that the neighborhood-condition only holds for elements of that |
| 56 | +partition. -/ |
| 57 | +theorem exists_isMatching_of_forall_ncard_le [DecidablePred (· ∈ p₁)] (h₁ : G.IsBipartiteWith p₁ p₂) |
| 58 | + (h₂ : ∀ s ⊆ p₁, s.ncard ≤ (⋃ x ∈ s, G.neighborSet x).ncard) : |
| 59 | + ∃ M : Subgraph G, p₁ ⊆ M.verts ∧ M.IsMatching := by |
| 60 | + obtain ⟨f, hf₁, hf₂⟩ := Finset.all_card_le_biUnion_card_iff_exists_injective |
| 61 | + (fun (x : p₁) ↦ G.neighborFinset x) |>.mp fun s ↦ by |
| 62 | + have := h₂ (s.image Subtype.val) (by simp) |
| 63 | + rw [Set.ncard_coe_finset, Finset.card_image_of_injective _ Subtype.val_injective] at this |
| 64 | + simpa [← Set.ncard_coe_finset, neighborFinset_def] |
| 65 | + have (x : p₁) : f x ∉ p₁ := h₁.disjoint |>.notMem_of_mem_right <| |
| 66 | + isBipartiteWith_neighborSet_subset h₁ x.2 <| Set.mem_toFinset.mp <| hf₂ x |
| 67 | + use hall_subgraph f this (fun v ↦ G.mem_neighborFinset _ _ |>.mp <| hf₂ v) |
| 68 | + refine ⟨by simp, fun v hv ↦ ?_⟩ |
| 69 | + simp only [Set.mem_union, Set.mem_range, Subtype.exists] at hv ⊢ |
| 70 | + rcases hv with h' | ⟨x, hx₁, hx₂⟩ |
| 71 | + · exact ⟨f ⟨v, h'⟩, by simp_all⟩ |
| 72 | + · use x |
| 73 | + have := hx₂ ▸ this ⟨x, hx₁⟩ |
| 74 | + simp only [this, ↓reduceDIte, hx₁, hx₂, dite_else_false, forall_exists_index, true_and] |
| 75 | + exact fun _ _ k ↦ Subtype.ext_iff.mp <| hf₁ (hx₂ ▸ k) |
| 76 | + |
| 77 | +lemma union_eq_univ_of_forall_ncard_le (h₁ : G.IsBipartiteWith p₁ p₂) |
| 78 | + (h₂ : ∀ s : Set V, s.ncard ≤ (⋃ x ∈ s, G.neighborSet x).ncard) : p₁ ∪ p₂ = Set.univ := by |
| 79 | + obtain ⟨f, _, hf₂⟩ := Finset.all_card_le_biUnion_card_iff_exists_injective |
| 80 | + (fun x ↦ G.neighborFinset x) |>.mp fun s ↦ by |
| 81 | + have := h₂ s |
| 82 | + simpa [← Set.ncard_coe_finset, neighborFinset_def] |
| 83 | + refine Set.eq_univ_iff_forall.mpr fun x ↦ ?_ |
| 84 | + have := h₁.mem_of_adj <| G.mem_neighborFinset _ _ |>.mp (hf₂ x) |
| 85 | + grind |
| 86 | + |
| 87 | +lemma exists_bijective_of_forall_ncard_le (h₁ : G.IsBipartiteWith p₁ p₂) |
| 88 | + (h₂ : ∀ s : Set V, s.ncard ≤ (⋃ x ∈ s, G.neighborSet x).ncard) : |
| 89 | + ∃ (h : p₁ → p₂), Function.Bijective h ∧ ∀ (a : p₁), G.Adj a (h a) := by |
| 90 | + obtain ⟨f, hf₁, hf₂⟩ := Finset.all_card_le_biUnion_card_iff_exists_injective |
| 91 | + (fun x ↦ G.neighborFinset x) |>.mp fun s ↦ by |
| 92 | + have := h₂ s |
| 93 | + simpa [← Set.ncard_coe_finset, neighborFinset_def] |
| 94 | + have (x : V) (h : x ∈ p₁) : f x ∉ p₁ := h₁.disjoint |>.notMem_of_mem_right <| |
| 95 | + isBipartiteWith_neighborSet_subset h₁ h <| Set.mem_toFinset.mp <| hf₂ x |
| 96 | + have (x : V) (h : x ∈ p₂) : f x ∉ p₂ := h₁.disjoint |>.notMem_of_mem_left <| |
| 97 | + isBipartiteWith_neighborSet_subset h₁.symm h <| Set.mem_toFinset.mp <| hf₂ x |
| 98 | + have (x : V) : f x ∈ p₁ ∨ f x ∈ p₂ := by |
| 99 | + simp [union_eq_univ_of_forall_ncard_le h₁ h₂, p₁.mem_union (f x) p₂ |>.mp] |
| 100 | + let f' (x : p₁) : p₂ := ⟨f x, by grind⟩ |
| 101 | + let g' (x : p₂) : p₁ := ⟨f x, by grind⟩ |
| 102 | + refine Embedding.schroeder_bernstein_of_rel (f := f') (g := g') ?_ ?_ (fun x y ↦ G.Adj x y) ?_ ?_ |
| 103 | + · exact Injective.of_comp (f := Subtype.val) <| hf₁.comp Subtype.val_injective |
| 104 | + · exact Injective.of_comp (f := Subtype.val) <| hf₁.comp Subtype.val_injective |
| 105 | + · exact fun v ↦ mem_neighborFinset _ _ _ |>.mp (hf₂ v) |
| 106 | + · exact fun v ↦ mem_neighborFinset _ _ _ |>.mp (hf₂ v) |>.symm |
| 107 | + |
| 108 | +/-- This is the version of **Hall's marriage theorem** for bipartite graphs that finds a perfect |
| 109 | +matching given that the neighborhood-condition holds globally. -/ |
| 110 | +theorem exists_isPerfectMatching_of_forall_ncard_le [DecidablePred (· ∈ p₁)] |
| 111 | + (h₁ : G.IsBipartiteWith p₁ p₂) (h₂ : ∀ s : Set V, s.ncard ≤ (⋃ x ∈ s, G.neighborSet x).ncard) : |
| 112 | + ∃ M : Subgraph G, M.IsPerfectMatching := by |
| 113 | + obtain ⟨b, hb₁, hb₂⟩ := exists_bijective_of_forall_ncard_le h₁ h₂ |
| 114 | + use hall_subgraph (fun v ↦ b v) (fun v ↦ h₁.disjoint.notMem_of_mem_right (b v).property) hb₂ |
| 115 | + have : p₁ ∪ Set.range (fun v ↦ (b v).1) = Set.univ := by |
| 116 | + rw [Set.range_comp', hb₁.surjective.range_eq, Subtype.coe_image_univ] |
| 117 | + exact union_eq_univ_of_forall_ncard_le h₁ h₂ |
| 118 | + refine ⟨fun v _ ↦ ?_, Subgraph.isSpanning_iff.mpr this⟩ |
| 119 | + simp only [dite_else_false] |
| 120 | + split |
| 121 | + · exact existsUnique_eq' |
| 122 | + · obtain ⟨x, _⟩ := hb₁.existsUnique ⟨v, by grind⟩ |
| 123 | + exact ⟨x, by grind⟩ |
| 124 | + |
| 125 | +end SimpleGraph |
0 commit comments