Skip to content

Commit 90795a0

Browse files
committed
feat(Combinatorics/SimpleGraphs): generalize SimpleGraph.map to any function (leanprover-community#36130)
The point is to be able to use map to define graph contractions. Added the injectivity assumption where needed.
1 parent 12760c9 commit 90795a0

File tree

4 files changed

+39
-31
lines changed

4 files changed

+39
-31
lines changed

Mathlib/Combinatorics/SimpleGraph/Clique.lean

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,19 @@ alias ⟨IsClique.subsingleton, _⟩ := isClique_bot_iff
107107

108108
protected theorem IsClique.map (h : G.IsClique s) {f : α ↪ β} : (G.map f).IsClique (f '' s) := by
109109
rintro _ ⟨a, ha, rfl⟩ _ ⟨b, hb, rfl⟩ hab
110-
exact ⟨a, b, h ha hb <| ne_of_apply_ne _ hab, rfl, rfl⟩
110+
exact ⟨hab, a, b, h ha hb <| ne_of_apply_ne _ hab, rfl, rfl⟩
111111

112112
theorem isClique_map_iff_of_nontrivial {f : α ↪ β} {t : Set β} (ht : t.Nontrivial) :
113113
(G.map f).IsClique t ↔ ∃ (s : Set α), G.IsClique s ∧ f '' s = t := by
114114
refine ⟨fun h ↦ ⟨f ⁻¹' t, ?_, ?_⟩, by rintro ⟨x, hs, rfl⟩; exact hs.map⟩
115115
· rintro x (hx : f x ∈ t) y (hy : f y ∈ t) hne
116-
obtain ⟨u, v, huv, hux, hvy⟩ := h hx hy (by simpa)
116+
obtain ⟨-, u, v, huv, hux, hvy⟩ := h hx hy (by simpa)
117117
rw [EmbeddingLike.apply_eq_iff_eq] at hux hvy
118118
rwa [← hux, ← hvy]
119119
rw [Set.image_preimage_eq_iff]
120120
intro x hxt
121121
obtain ⟨y, hyt, hyne⟩ := ht.exists_ne x
122-
obtain ⟨u, v, -, rfl, rfl⟩ := h hyt hxt hyne
122+
obtain ⟨-, u, v, -, rfl, rfl⟩ := h hyt hxt hyne
123123
exact Set.mem_range_self _
124124

125125
theorem isClique_map_iff {f : α ↪ β} {t : Set β} :
@@ -643,7 +643,7 @@ theorem cliqueSet_map (hn : n ≠ 1) (G : SimpleGraph α) (f : α ↪ β) :
643643
rw [map_eq_image, image_preimage, filter_true_of_mem]
644644
rintro a ha
645645
obtain ⟨b, hb, hba⟩ := exists_mem_ne (hn.lt_of_le' <| Finset.card_pos.2 ⟨a, ha⟩) a
646-
obtain ⟨c, _, _, hc, _⟩ := hs ha hb hba.symm
646+
obtain ⟨-, c, _, _, hc, _⟩ := hs ha hb hba.symm
647647
exact ⟨c, hc⟩
648648
refine ⟨s.preimage f f.injective.injOn, ⟨?_, by rw [← card_map f, hs']⟩, hs'⟩
649649
rw [coe_preimage]
@@ -653,11 +653,11 @@ theorem cliqueSet_map (hn : n ≠ 1) (G : SimpleGraph α) (f : α ↪ β) :
653653

654654
@[simp]
655655
theorem cliqueSet_map_of_equiv (G : SimpleGraph α) (e : α ≃ β) (n : ℕ) :
656-
(G.map e.toEmbedding).cliqueSet n = map e.toEmbedding '' G.cliqueSet n := by
656+
(G.map e).cliqueSet n = map e.toEmbedding '' G.cliqueSet n := by
657657
obtain rfl | hn := eq_or_ne n 1
658658
· ext
659659
simp [e.exists_congr_left]
660-
· exact cliqueSet_map hn _ _
660+
· simpa using cliqueSet_map hn G e.toEmbedding
661661

662662
end CliqueSet
663663

@@ -774,8 +774,7 @@ theorem cliqueFinset_map (f : α ↪ β) (hn : n ≠ 1) :
774774
simp_rw [coe_cliqueFinset, cliqueSet_map hn, coe_map, coe_cliqueFinset, Embedding.coeFn_mk]
775775

776776
@[simp]
777-
theorem cliqueFinset_map_of_equiv (e : α ≃ β) (n : ℕ) :
778-
(G.map e.toEmbedding).cliqueFinset n =
777+
theorem cliqueFinset_map_of_equiv (e : α ≃ β) (n : ℕ) : (G.map e).cliqueFinset n =
779778
(G.cliqueFinset n).map ⟨map e.toEmbedding, Finset.map_injective _⟩ :=
780779
coe_injective <| by push_cast; exact cliqueSet_map_of_equiv _ _ _
781780

Mathlib/Combinatorics/SimpleGraph/Coloring.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ graph. -/
180180
theorem Colorable.map (f : V ↪ β) [NeZero n] (hc : G.Colorable n) : (G.map f).Colorable n := by
181181
obtain ⟨C⟩ := hc
182182
use extend f C (const β default)
183-
intro a b ⟨_, _, hadj, ha, hb⟩
183+
intro a b ⟨_, _, _, hadj, ha, hb⟩
184184
rw [← ha, f.injective.extend_apply, ← hb, f.injective.extend_apply]
185185
exact C.valid hadj
186186

Mathlib/Combinatorics/SimpleGraph/Maps.lean

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,28 @@ variable {V W X : Type*} (G : SimpleGraph V) (G' : SimpleGraph W) {u v : V}
5050
/-! ## Map and comap -/
5151

5252

53-
/-- Given an injective function, there is a covariant induced map on graphs by pushing forward
53+
/-- Given a function, there is a covariant induced map on graphs by pushing forward
5454
the adjacency relation.
5555
56-
This is injective (see `SimpleGraph.map_injective`). -/
57-
protected def map (f : V W) (G : SimpleGraph V) : SimpleGraph W where
58-
Adj := Relation.Map G.Adj f f
56+
This is injective when the function is (see `SimpleGraph.map_injective`). -/
57+
protected def map (f : V W) (G : SimpleGraph V) : SimpleGraph W where
58+
Adj := Ne ⊓ Relation.Map G.Adj f f
5959
symm a b := by
6060
rintro ⟨v, w, h, _⟩
6161
aesop (add norm unfold Relation.Map) (add forward safe Adj.symm)
62-
loopless := ⟨fun a ↦ by aesop (add norm unfold Relation.Map)⟩
6362

64-
instance instDecidableMapAdj {f : V ↪ W} {a b} [Decidable (Relation.Map G.Adj f f a b)] :
65-
Decidable ((G.map f).Adj a b) := ‹Decidable (Relation.Map G.Adj f f a b)›
63+
instance instDecidableMapAdj [DecidableEq W] {f : V → W} {a b}
64+
[Decidable (Relation.Map G.Adj f f a b)] : Decidable ((G.map f).Adj a b) := by
65+
dsimp [SimpleGraph.map]; infer_instance
6666

6767
@[simp]
6868
theorem map_adj (f : V ↪ W) (G : SimpleGraph V) (u v : W) :
69-
(G.map f).Adj u v ↔ ∃ u' v' : V, G.Adj u' v' ∧ f u' = u ∧ f v' = v :=
69+
(G.map f).Adj u v ↔ ∃ u' v' : V, G.Adj u' v' ∧ f u' = u ∧ f v' = v := by
70+
dsimp [SimpleGraph.map, Relation.Map]
71+
grind [SimpleGraph.Adj.ne]
72+
73+
theorem map_adj' (f : V → W) (G : SimpleGraph V) (u v : W) :
74+
(G.map f).Adj u v ↔ u ≠ v ∧ ∃ u' v' : V, G.Adj u' v' ∧ f u' = u ∧ f v' = v :=
7075
Iff.rfl
7176

7277
theorem edgeSet_map (f : V ↪ W) (G : SimpleGraph V) :
@@ -86,15 +91,19 @@ theorem edgeSet_map (f : V ↪ W) (G : SimpleGraph V) :
8691
lemma map_adj_apply {G : SimpleGraph V} {f : V ↪ W} {a b : V} :
8792
(G.map f).Adj (f a) (f b) ↔ G.Adj a b := by simp
8893

89-
theorem map_monotone (f : V W) : Monotone (SimpleGraph.map f) := by
90-
rintro G G' h _ _ ⟨u, v, ha, rfl, rfl⟩
91-
exact ⟨_, _, h ha, rfl, rfl⟩
94+
theorem map_monotone (f : V W) : Monotone (SimpleGraph.map f) := by
95+
rintro G G' h z1 z2 ⟨huv, u, v, ha, rfl, rfl⟩
96+
exact ⟨huv, _, _, h ha, rfl, rfl⟩
9297

93-
@[simp] lemma map_id : G.map (Function.Embedding.refl _) = G :=
94-
SimpleGraph.ext <| Relation.map_id_id _
98+
@[simp] lemma map_id : G.map id = G := by
99+
ext
100+
dsimp [SimpleGraph.map, Relation.Map]
101+
grind [SimpleGraph.Adj.ne]
95102

96-
@[simp] lemma map_map (f : V ↪ W) (g : W ↪ X) : (G.map f).map g = G.map (f.trans g) :=
97-
SimpleGraph.ext <| Relation.map_map _ _ _ _ _
103+
@[simp] lemma map_map (f : V → W) (g : W → X) : (G.map f).map g = G.map (g ∘ f) := by
104+
ext
105+
dsimp [SimpleGraph.map, Relation.Map]
106+
grind [SimpleGraph.Adj.ne]
98107

99108
theorem support_map (f : V ↪ W) (G : SimpleGraph V) :
100109
(G.map f).support = f '' G.support := by
@@ -154,8 +163,8 @@ theorem comap_surjective (f : V ↪ W) : Function.Surjective (SimpleGraph.comap
154163

155164
theorem map_le_iff_le_comap (f : V ↪ W) (G : SimpleGraph V) (G' : SimpleGraph W) :
156165
G.map f ≤ G' ↔ G ≤ G'.comap f :=
157-
fun h _ _ ha => h ⟨_, _, ha, rfl, rfl⟩, by
158-
rintro h _ _ ⟨u, v, ha, rfl, rfl⟩
166+
fun h _ _ ha => h ⟨f.injective.ne ha.ne, _, _, ha, rfl, rfl⟩, by
167+
rintro h _ _ ⟨-, u, v, ha, rfl, rfl⟩
159168
exact h ha⟩
160169

161170
set_option backward.isDefEq.respectTransparency false in
@@ -578,15 +587,15 @@ protected def comap (f : V ≃ W) (G : SimpleGraph W) : G.comap f.toEmbedding
578587
lemma comap_apply (f : V ≃ W) (G : SimpleGraph W) (v : V) :
579588
SimpleGraph.Iso.comap f G v = f v := rfl
580589

590+
-- Porting note: `@[simps]` does not work here anymore since `f` is not a constructor application.
591+
-- `@[simps toEmbedding]` could work, but Floris suggested writing `map_apply` for now.
581592
@[simp]
582593
lemma comap_symm_apply (f : V ≃ W) (G : SimpleGraph W) (w : W) :
583594
(SimpleGraph.Iso.comap f G).symm w = f.symm w := rfl
584595

585-
/-- Given an injective function, there is an embedding from a graph into the mapped graph. -/
586-
-- Porting note: `@[simps]` does not work here anymore since `f` is not a constructor application.
587-
-- `@[simps toEmbedding]` could work, but Floris suggested writing `map_apply` for now.
596+
/-- Given a bijective function, there is an isomorphism from a graph into the mapped graph. -/
588597
protected def map (f : V ≃ W) (G : SimpleGraph V) : G ≃g G.map f.toEmbedding :=
589-
{ f with map_rel_iff' := by simp }
598+
{ f with map_rel_iff' := by aesop (add simp map_adj') }
590599

591600
@[simp]
592601
lemma map_apply (f : V ≃ W) (G : SimpleGraph V) (v : V) :

Mathlib/Combinatorics/SimpleGraph/Triangle/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ lemma EdgeDisjointTriangles.map (f : α ↪ β) (hG : G.EdgeDisjointTriangles) :
7575

7676
lemma LocallyLinear.map (f : α ↪ β) (hG : G.LocallyLinear) : (G.map f).LocallyLinear := by
7777
refine ⟨hG.1.map _, ?_⟩
78-
rintro _ _ ⟨a, b, h, rfl, rfl⟩
78+
rintro _ _ ⟨-, a, b, h, rfl, rfl⟩
7979
obtain ⟨s, hs, ha, hb⟩ := hG.2 h
8080
exact ⟨s.map f, hs.map, mem_map_of_mem _ ha, mem_map_of_mem _ hb⟩
8181

0 commit comments

Comments
 (0)