Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
a071be8
Graph.Subgraph
Jun2M Jul 4, 2025
8576ce1
Add docstrings
Jun2M Jul 4, 2025
fc5d553
scoping notations
Jun2M Jul 4, 2025
e522a9a
move some to finite file
Jun2M Jul 6, 2025
380056e
fix imports
Jun2M Jul 6, 2025
80dd77b
Merge branch 'master' into subgraph
Jun2M Nov 14, 2025
b1aba94
focus on relations
Jun2M Nov 14, 2025
b1d595d
Docs update
Jun2M Nov 16, 2025
c4a0315
Remove unused imports
Jun2M Nov 16, 2025
d207dca
Merge branch 'master' into subgraph
Jun2M Jan 20, 2026
d85c334
module
Jun2M Jan 20, 2026
09af04c
Remove unnecessary braket
Jun2M Jan 29, 2026
90737a5
Eq to Iff
Jun2M Jan 29, 2026
f5f9689
Change comments to reflect inlineing
Jun2M Jan 30, 2026
7fc070d
Apply suggested changes
Jun2M Jan 30, 2026
250e8ce
Reflect `copy` being moved in the comment
Jun2M Feb 2, 2026
b4ff78a
Remove `_self`
Jun2M Feb 2, 2026
04640f9
inc_inj
Jun2M Feb 2, 2026
212b36e
Compatible
Jun2M Feb 2, 2026
f74dd69
nudge github action
Jun2M Feb 3, 2026
8f0a6a7
isInducedSubgraph_iff
Jun2M Feb 3, 2026
02a2f17
Merge branch 'master' into subgraph
Jun2M Feb 23, 2026
b3f3414
merge fixes
Jun2M Feb 23, 2026
70a5bb2
golf le_refl
Jun2M Feb 24, 2026
48362f3
Comment change
Jun2M Feb 25, 2026
3a8f13a
Use Compatible
Jun2M Feb 25, 2026
7786c69
strengthen to iffs
Jun2M Feb 25, 2026
eae4edd
le_iff_compatible_subset_subset
Jun2M Feb 26, 2026
ca11b5d
IsSubgraph structure
Jun2M Feb 28, 2026
8cc1662
Init
Jun2M Feb 28, 2026
49c5cf2
add docstring
Jun2M Feb 28, 2026
0b9a098
Merge remote-tracking branch 'upstream/master' into GraphDelete
Jun2M Mar 1, 2026
b872b19
mk_all
Jun2M Mar 1, 2026
065af13
inherit_doc
Jun2M Mar 1, 2026
1399321
minor change
Jun2M Mar 1, 2026
14893a4
remove some grind tags
Jun2M Mar 1, 2026
2f0c36d
Merge branch 'master' into GraphDelete
Jun2M Mar 21, 2026
a362f9f
fix
Jun2M Mar 21, 2026
fee0ede
Merge branch 'master' into GraphDelete
Jun2M Apr 3, 2026
62af1ad
name change
Jun2M Apr 3, 2026
762f72b
Update Mathlib/Combinatorics/Graph/Delete.lean
Jun2M Apr 7, 2026
428fea5
Merge branch 'master' into GraphDelete
Jun2M Apr 7, 2026
a4a4c9d
change notation
Jun2M Apr 7, 2026
901c5be
correct names
Jun2M Apr 7, 2026
39173bc
revert some name change & grind
Jun2M Apr 8, 2026
432a328
deprecate tag
Jun2M Apr 9, 2026
78aa105
init
Jun2M Apr 9, 2026
f8c94fa
expose
Jun2M Apr 9, 2026
9c2d488
add alias
Jun2M Apr 14, 2026
1f53f79
Merge branch 'master' into GraphEdgeCut
Jun2M Apr 14, 2026
0ee9b8b
Merge branch 'master' into GraphEdgeCut
Jun2M Apr 15, 2026
ea32bdd
lint
Jun2M Apr 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions Mathlib/Combinatorics/Graph/Connected/EdgeCut.Lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/-
Copyright (c) 2026 Jun Kwon. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jun Kwon
-/
module

public import Mathlib.Combinatorics.Graph.Delete

/-!
# Edge cuts and bridges of graphs

This file defines the edge cuts and bridges of a graph.

## Main definitions

* `IsEdgeCut`: a set of edges between a set of vertices and its complement.
* `IsBridge`: an edge that forms a singleton edge cut (an isthmus / bridge edge).
* `IsBond`: a bond of a graph is a minimal nonempty edge cut.

-/

public section

variable {α β : Type*} {G H K : Graph α β} {S : Set α} {F F' B : Set β} {e : β} {u v : α}

open Set symmDiff

namespace Graph

/-! ### Edge cuts -/

section edgeCut

/-- The edge cut of a graph `G` along a set of vertices `S`. -/
def edgeCut (G : Graph α β) (S : Set α) : Set β := {e | ∃ u v, G.IsLink e u v ∧ u ∈ S ∧ v ∉ S}

@[inherit_doc edgeCut] scoped notation "δ(" G ", " S ")" => Graph.edgeCut G S

@[grind =]
lemma mem_edgeCut_iff (G : Graph α β) (S : Set α) :
e ∈ δ(G, S) ↔ ∃ u v, G.IsLink e u v ∧ u ∈ S ∧ v ∉ S := Iff.rfl

lemma IsLink.mem_edgeCut_iff (h : G.IsLink e u v) :
e ∈ δ(G, S) ↔ (u ∈ S ∧ v ∉ S) ∨ (v ∈ S ∧ u ∉ S) := by
grind [isLink_comm, h.eq_and_eq_or_eq_and_eq]

@[grind .]
lemma edgeCut_subset (G : Graph α β) (S : Set α) : δ(G, S) ⊆ E(G) :=
fun _ ⟨_, _, huv, _, _⟩ ↦ huv.edge_mem

lemma edgeCut_eq_empty_iff (hS : S ⊆ V(G)) : δ(G, S) = ∅ ↔ G.induce S ≤c G := by
refine ⟨fun h ↦ IsClosedSubgraph.mk' (induce_le hS) fun e x ⟨y, hxy⟩ hxS ↦ ?_,
fun h ↦ by grind [h.mem_iff_of_isLink]⟩
rw [edgeSet_induce]
use x, y, hxy, hxS
contrapose! h
exact ⟨e, x, y, hxy, hxS, h⟩

@[simp]
lemma edgeCut_vertexSet_diff (G : Graph α β) (S : Set α) : δ(G, V(G) \ S) = δ(G, S) := by
grind [IsLink.left_mem, IsLink.right_mem, isLink_comm]

lemma IsSubgraph.edgeCut_eq_inter (hHG : H ≤ G) (S : Set α) : δ(H, S) = E(H) ∩ δ(G, S) := by
grind [hHG.isLink_iff']

lemma edgeCut_symmDiff (G : Graph α β) (S S' : Set α) : δ(G, S ∆ S') = δ(G, S) ∆ δ(G, S') := by
ext e
wlog he : e ∈ E(G)
· grind [IsSubgraph.isLink_iff']
obtain ⟨x, y, hxy⟩ := exists_isLink_of_mem_edgeSet he
grind [hxy.mem_edgeCut_iff]

lemma IsClosedSubgraph.edgeCut_subset (hHG : H ≤c G) (hS : S ⊆ V(H)) : δ(G, S) ⊆ E(H) :=
fun _ ⟨_, _, hxy, hu, _⟩ ↦ hHG.closed hxy.inc_left (hS hu)

end edgeCut

section IsEdgeCut

/-- A set of edges is an edge cut if there exists a set of vertices such that the edges in the set
are between the set of vertices and its complement. -/
def IsEdgeCut (G : Graph α β) (F : Set β) : Prop := ∃ S : Set α, δ(G, S) = F

lemma IsEdgeCut.exists (hF : G.IsEdgeCut F) : ∃ S ⊆ V(G), δ(G, S) = F := by
obtain ⟨S, rfl⟩ := hF
exact ⟨V(G) ∩ S, inter_subset_left .., by grind [edgeCut]⟩

lemma IsEdgeCut.exists_of_isLink (he : G.IsLink e u v) (heF : e ∈ F) (hF : G.IsEdgeCut F) :
∃ S ⊆ V(G), δ(G, S) = F ∧ u ∈ S ∧ v ∉ S := by
obtain ⟨S, hS, rfl⟩ := hF.exists
grind [he.mem_edgeCut_iff, G.edgeCut_vertexSet_diff S]

lemma IsEdgeCut.subset (hF : G.IsEdgeCut F) : F ⊆ E(G) := by
obtain ⟨S, rfl⟩ := hF
exact G.edgeCut_subset S

@[grind →]
lemma IsEdgeCut.symmDiff (hF : G.IsEdgeCut F) (hF' : G.IsEdgeCut F') : G.IsEdgeCut (F ∆ F') := by
obtain ⟨S, rfl⟩ := hF
obtain ⟨S', rfl⟩ := hF'
use S ∆ S', G.edgeCut_symmDiff S S'

lemma IsEdgeCut.anti (hHG : H ≤ G) (hF : G.IsEdgeCut F) : H.IsEdgeCut (E(H) ∩ F) := by
obtain ⟨S, rfl⟩ := hF
use S
exact hHG.edgeCut_eq_inter S

lemma IsEdgeCut.of_isClosedSubgraph (hGH : G ≤c H) (hF : G.IsEdgeCut F) : H.IsEdgeCut F := by
obtain ⟨S, hSG, rfl⟩ := hF.exists
use S
ext e
wlog he : e ∈ E(G)
· refine iff_of_false ?_ (he <| G.edgeCut_subset _ ·)
rintro ⟨u, v, hxy, hu, hv⟩
exact he <| hGH.closed hxy.inc_left (hSG hu)
obtain ⟨x, y, hxy⟩ := exists_isLink_of_mem_edgeSet he
rw [hxy.mem_edgeCut_iff, (hGH.le.isLink_mono hxy).mem_edgeCut_iff]
alias IsClosedSubgraph.isEdgeCut := IsEdgeCut.of_isClosedSubgraph

end IsEdgeCut

/-! ### Bridges: singleton edge cuts -/

section IsBridge

/-- A bridge (isthmus) is an edge that constitutes a singleton edge cut. -/
@[expose] def IsBridge (G : Graph α β) (e : β) : Prop := G.IsEdgeCut {e}

lemma IsBridge.isEdgeCut (he : G.IsBridge e) : G.IsEdgeCut {e} := he

@[grind .]
lemma IsBridge.mem_edgeSet (he : G.IsBridge e) : e ∈ E(G) := by
simpa using IsEdgeCut.subset he

lemma IsBridge.anti_of_mem (hHG : H ≤ G) (heH : e ∈ E(H)) (he : G.IsBridge e) : H.IsBridge e := by
obtain ⟨x, y, hxy⟩ := exists_isLink_of_mem_edgeSet heH
obtain ⟨S, hS, he⟩ := he.exists
use S
grind [hHG.edgeCut_eq_inter]

lemma IsBridge.of_isClosedSubgraph (hcle : H ≤c G) (he : H.IsBridge e) : G.IsBridge e := by
obtain ⟨x, y, hxy⟩ := exists_isLink_of_mem_edgeSet he.mem_edgeSet
obtain ⟨S, hS, he⟩ := he.exists
use S
rwa [hcle.edgeCut_eq_inter S, inter_eq_right.mpr <| hcle.edgeCut_subset hS] at he

lemma IsClosedSubgraph.isBridge_iff (he : e ∈ E(H)) (h : H ≤c G) : G.IsBridge e ↔ H.IsBridge e :=
⟨fun hb ↦ hb.anti_of_mem h.le he, fun hb ↦ hb.of_isClosedSubgraph h⟩

end IsBridge

/-! ### Bonds: minimal nonempty edge cuts -/

section IsBond

/-- A bond of a graph is a minimal nonempty edge-cut. -/
@[expose]
def IsBond (G : Graph α β) (F : Set β) : Prop := Minimal (fun F ↦ G.IsEdgeCut F ∧ F.Nonempty) F

@[grind →]
lemma IsBond.subset (hB : G.IsBond B) : B ⊆ E(G) := by
obtain ⟨h, -⟩ := hB.prop
exact h.subset

lemma IsBond.isEdgeCut (hB : G.IsBond B) : G.IsEdgeCut B := hB.prop.1

lemma IsBond.nonempty (hB : G.IsBond B) : B.Nonempty := hB.prop.2

@[grind .]
lemma IsBridge.isBond (he : G.IsBridge e) : G.IsBond {e} := by
refine ⟨⟨he, by simp⟩, fun F' hF' hF'e ↦ ?_⟩
obtain rfl | rfl := subset_singleton_iff_eq.mp hF'e
· simp at hF'
exact hF'e

lemma IsBond.isBridge (heB : e ∈ B) (hB : G.IsBond B) : (G.deleteEdges (B \ {e})).IsBridge e := by
have := hB.prop.1.anti (G.deleteEdges_le (F := B \ {e}))
rw [edgeSet_deleteEdges, inter_comm, inter_diff_distrib_left, inter_eq_left.mpr hB.subset,
inter_eq_right.mpr diff_subset] at this
simpa [heB] using this

lemma IsBond.of_isClosedSubgraph (hGH : G ≤c H) (hB : G.IsBond B) : H.IsBond B := by
refine ⟨⟨hB.isEdgeCut.of_isClosedSubgraph hGH, hB.nonempty⟩, fun C ⟨hC, e, heC⟩ hCB ↦ ?_⟩
exact hB.2 ⟨hC.anti hGH.le, e, hB.subset (hCB heC), heC⟩ (inter_subset_right
|>.trans hCB) |>.trans inter_subset_right
alias IsClosedSubgraph.isBond := IsBond.of_isClosedSubgraph

end IsBond

end Graph
3 changes: 3 additions & 0 deletions Mathlib/Combinatorics/Graph/Subgraph.lean
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ lemma IsSubgraph.isLink_eqOn (hHG : H ≤ G) : EqOn H.IsLink G.IsLink E(H) := by
ext x y
exact isLink_iff hHG he

lemma IsSubgraph.isLink_iff' (hHG : H ≤ G) : H.IsLink e x y ↔ G.IsLink e x y ∧ e ∈ E(H) := by
grind [hHG.isLink_iff, IsLink.edge_mem]

/-- Two subgraphs of the same graph are compatible. -/
lemma Compatible.of_le_le (hH₁G : H₁ ≤ G) (hH₂G : H₂ ≤ G) : H₁.Compatible H₂ :=
fun _ he₁ he₂ _ _ ↦ hH₁G.isLink_iff he₁ |>.trans <| (hH₂G.isLink_iff he₂).symm
Expand Down
Loading