Skip to content

Commit 69fd837

Browse files
committed
refactor: single-edge graph (#9736)
From #9267 (comment): > I would prefer we use lattice operations for adding edges. The idea is to make constructor `SimpleGraph.edge (v w : V) : SimpleGraph V` that creates a graph with a single edge between `v` and `w` if they're not equal (and no edge if they are), and then `G.addEdge v w` would instead be `G ⊔ edge v w`. This is more versatile, though perhaps lemmas such as `addEdge_of_adj` are a bit more brittle to apply.
1 parent d025702 commit 69fd837

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

Mathlib/Combinatorics/SimpleGraph/Clique.lean

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,8 @@ theorem cliqueFree_two : G.CliqueFree 2 ↔ G = ⊥ := by
338338
#align simple_graph.clique_free_two SimpleGraph.cliqueFree_two
339339

340340
/-- Adding an edge increases the clique number by at most one. -/
341-
protected theorem CliqueFree.addEdge (h : G.CliqueFree n) (v w) :
342-
(G.addEdge v w).CliqueFree (n + 1) := by
341+
protected theorem CliqueFree.sup_edge (h : G.CliqueFree n) (v w : α) :
342+
(G ⊔ edge v w).CliqueFree (n + 1) := by
343343
contrapose h
344344
obtain ⟨f, ha⟩ := topEmbeddingOfNotCliqueFree h
345345
simp only [ne_eq, top_adj] at ha
@@ -354,15 +354,17 @@ protected theorem CliqueFree.addEdge (h : G.CliqueFree n) (v w) :
354354
(hx ▸ f.apply_eq_iff_eq x (x.succAbove a)).ne.mpr (x.succAbove_ne a).symm
355355
have ib : w ≠ f (x.succAbove b) :=
356356
(hx ▸ f.apply_eq_iff_eq x (x.succAbove b)).ne.mpr (x.succAbove_ne b).symm
357-
simp only [addEdge, ia, ib, and_false, false_and, or_false] at hs
357+
rw [sup_adj, edge_adj] at hs
358+
simp only [ia.symm, ib.symm, and_false, false_and, or_false] at hs
358359
rw [hs, Fin.succAbove_right_inj]
359360
· use ⟨f ∘ Fin.succEmb n, (f.2.of_comp_iff _).mpr (RelEmbedding.injective _)⟩
360361
intro a b
361362
simp only [Fin.val_succEmb, Embedding.coeFn_mk, comp_apply, top_adj]
362363
have hs := @ha a.succ b.succ
363364
have ia : f a.succ ≠ w := by simp_all
364365
have ib : f b.succ ≠ w := by simp_all
365-
simp only [addEdge, ia.symm, ib.symm, and_false, false_and, or_false] at hs
366+
rw [sup_adj, edge_adj] at hs
367+
simp only [ia, ib, and_false, false_and, or_false] at hs
366368
rw [hs, Fin.succ_inj]
367369

368370
end CliqueFree

Mathlib/Combinatorics/SimpleGraph/Operations.lean

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ we also prove theorems about the number of edges in the modified graphs.
1616
1717
* `G.replaceVertex s t` is `G` with `t` replaced by a copy of `s`,
1818
removing the `s-t` edge if present.
19-
* `G.addEdge s t` is `G` with the `s-t` edge added, if that is a valid edge.
19+
* `edge s t` is the graph with a single `s-t` edge. Adding this edge to a graph `G` is then
20+
`G ⊔ edge s t`.
2021
-/
2122

2223

@@ -124,31 +125,40 @@ end ReplaceVertex
124125

125126
section AddEdge
126127

127-
/-- Given a vertex pair, add the corresponding edge to the graph's edge set if not present. -/
128-
def addEdge : SimpleGraph V where
129-
Adj v w := G.Adj v w ∨ s ≠ t ∧ (s = v ∧ t = w ∨ s = w ∧ t = v)
130-
symm v w := by simp_rw [adj_comm]; (conv_lhs => arg 2; arg 2; rw [or_comm]); exact id
128+
/-- The graph with a single `s-t` edge. It is empty iff `s = t`. -/
129+
def edge : SimpleGraph V := fromEdgeSet {s(s, t)}
130+
131+
lemma edge_adj (v w : V) : (edge s t).Adj v w ↔ (v = s ∧ w = t ∨ v = t ∧ w = s) ∧ v ≠ w := by
132+
rw [edge, fromEdgeSet_adj, Set.mem_singleton_iff, Sym2.eq_iff]
133+
134+
lemma edge_self_eq_bot : edge s s = ⊥ := by
135+
ext; rw [edge_adj]; aesop
131136

132137
@[simp]
133-
lemma addEdge_self : G.addEdge s s = G := by ext; simp [addEdge]
138+
lemma sup_edge_self : G ⊔ edge s s = G := by
139+
rw [edge_self_eq_bot, sup_of_le_left bot_le]
134140

135141
variable {s t}
136142

137-
lemma addEdge_of_adj (h : G.Adj s t) : G.addEdge s t = G := by
138-
ext
139-
simp only [addEdge, ne_eq, G.ne_of_adj h, not_false_eq_true, true_and, or_iff_left_iff_imp]
140-
rintro (_ | _) <;> simp_all [adj_comm]
143+
lemma edge_edgeSet_of_ne (h : s ≠ t) : (edge s t).edgeSet = {s(s, t)} := by
144+
rwa [edge, edgeSet_fromEdgeSet, sdiff_eq_left, Set.disjoint_singleton_left, Set.mem_setOf_eq,
145+
Sym2.isDiag_iff_proj_eq]
146+
147+
lemma sup_edge_of_adj (h : G.Adj s t) : G ⊔ edge s t = G := by
148+
rwa [sup_eq_left, ← edgeSet_subset_edgeSet, edge_edgeSet_of_ne h.ne, Set.singleton_subset_iff,
149+
mem_edgeSet]
141150

142151
variable [Fintype V] [DecidableRel G.Adj]
143152

144-
instance : DecidableRel (G.addEdge s t).Adj := by unfold addEdge; infer_instance
153+
instance : Fintype (edge s t).edgeSet := by rw [edge]; infer_instance
145154

146-
theorem edgeFinset_addEdge (hn : ¬G.Adj s t) (h : s ≠ t) :
147-
(G.addEdge s t).edgeFinset = G.edgeFinset.cons s(s, t) (by simp_all) := by
148-
ext e; refine' e.inductionOn _; unfold addEdge; aesop
155+
theorem edgeFinset_sup_edge (hn : ¬G.Adj s t) (h : s ≠ t) :
156+
(G ⊔ edge s t).edgeFinset = G.edgeFinset.cons s(s, t) (by simp_all) := by
157+
rw [edgeFinset_sup, cons_eq_insert, insert_eq, union_comm]
158+
simp_rw [edgeFinset, edge_edgeSet_of_ne h]; rfl
149159

150-
theorem card_edgeFinset_addEdge (hn : ¬G.Adj s t) (h : s ≠ t) :
151-
(G.addEdge s t).edgeFinset.card = G.edgeFinset.card + 1 := by
152-
rw [G.edgeFinset_addEdge hn h, card_cons]
160+
theorem card_edgeFinset_sup_edge (hn : ¬G.Adj s t) (h : s ≠ t) :
161+
(G ⊔ edge s t).edgeFinset.card = G.edgeFinset.card + 1 := by
162+
rw [G.edgeFinset_sup_edge hn h, card_cons]
153163

154164
end AddEdge

0 commit comments

Comments
 (0)