Skip to content

Commit d8f2208

Browse files
committed
feat(Combinatorics/SimpleGraph/Hamiltonian): if mapping a Hamiltonian walk results in a path, the mapping function is injective (#36469)
1 parent b495b14 commit d8f2208

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,25 @@ In this file we introduce Hamiltonian paths, cycles and graphs.
2626
open Finset Function
2727

2828
namespace SimpleGraph
29-
variable {α β : Type*} [DecidableEq α] [DecidableEq β] {G : SimpleGraph α}
30-
{a b : α} {p : G.Walk a b}
29+
30+
variable {α : Type*} [DecidableEq α] {G : SimpleGraph α}
31+
variable {β : Type*} [DecidableEq β] {H : SimpleGraph β}
32+
variable {a b : α} {p : G.Walk a b} {f : G →g H}
3133

3234
namespace Walk
3335

3436
/-- A Hamiltonian path is a walk `p` that visits every vertex exactly once. Note that while
3537
this definition doesn't contain that `p` is a path, `p.isPath` gives that. -/
3638
def IsHamiltonian (p : G.Walk a b) : Prop := ∀ a, p.support.count a = 1
3739

38-
lemma IsHamiltonian.map {H : SimpleGraph β} (f : G →g H) (hf : Bijective f) (hp : p.IsHamiltonian) :
40+
variable (f) in
41+
lemma IsHamiltonian.map (hf : Bijective f) (hp : p.IsHamiltonian) :
3942
(p.map f).IsHamiltonian := by
4043
simp [IsHamiltonian, hf.surjective.forall, hf.injective, hp _]
4144

4245
/-- A Hamiltonian path visits every vertex. -/
43-
@[simp] lemma IsHamiltonian.mem_support (hp : p.IsHamiltonian) (c : α) : c ∈ p.support := by
44-
simp only [← List.count_pos_iff, hp _, Nat.zero_lt_one]
46+
@[simp] lemma IsHamiltonian.mem_support (hp : p.IsHamiltonian) (c : α) : c ∈ p.support :=
47+
p.support.one_le_count_iff.mp <| hp c |>.symm.le
4548

4649
/-- Hamiltonian paths are paths. -/
4750
lemma IsHamiltonian.isPath (hp : p.IsHamiltonian) : p.IsPath :=
@@ -69,14 +72,21 @@ section
6972
variable [Fintype α]
7073

7174
/-- The support of a Hamiltonian walk is the entire vertex set. -/
72-
lemma IsHamiltonian.support_toFinset (hp : p.IsHamiltonian) : p.support.toFinset = Finset.univ := by
75+
lemma IsHamiltonian.toFinset_support (hp : p.IsHamiltonian) : p.support.toFinset = Finset.univ := by
7376
simp [eq_univ_iff_forall, hp]
7477

78+
@[deprecated (since := "2026-03-11")]
79+
alias IsHamiltonian.support_toFinset := IsHamiltonian.toFinset_support
80+
81+
omit [Fintype α] in
82+
theorem IsHamiltonian.setOf_support (hp : p.IsHamiltonian) : {v | v ∈ p.support} = Set.univ :=
83+
Set.eq_univ_iff_forall.mpr hp.mem_support
84+
7585
/-- The length of a Hamiltonian path is one less than the number of vertices of the graph. -/
7686
lemma IsHamiltonian.length_eq (hp : p.IsHamiltonian) : p.length = Fintype.card α - 1 :=
7787
eq_tsub_of_add_eq <| by
7888
rw [← length_support, ← List.sum_toFinset_count_eq_length, Finset.sum_congr rfl fun _ _ ↦ hp _,
79-
← card_eq_sum_ones, hp.support_toFinset, card_univ]
89+
← card_eq_sum_ones, hp.toFinset_support, card_univ]
8090

8191
/-- The length of the support of a Hamiltonian path equals the number of vertices of the graph. -/
8292
lemma IsHamiltonian.length_support (hp : p.IsHamiltonian) : p.support.length = Fintype.card α := by
@@ -107,6 +117,12 @@ theorem IsHamiltonian.getVert_surjective (hp : p.IsHamiltonian) : p.getVert.Surj
107117
.of_comp <| p.getVert_comp_val_eq_get_support ▸
108118
isHamiltonian_iff_support_get_bijective.mp hp |>.surjective
109119

120+
omit [DecidableEq β] in
121+
theorem IsHamiltonian.injective_of_isPath_map (hp : p.IsHamiltonian) (h : (p.map f).IsPath) :
122+
Function.Injective f := by
123+
rw [← Set.injOn_univ, ← hp.setOf_support]
124+
exact h.injOn_support_of_isPath_map
125+
110126
lemma isHamiltonian_iff_isPath_and_length_eq [Fintype α] :
111127
p.IsHamiltonian ↔ p.IsPath ∧ p.length = Fintype.card α - 1 := by
112128
by_cases! h : IsEmpty α
@@ -126,7 +142,7 @@ variable {p : G.Walk a a}
126142
lemma IsHamiltonianCycle.isCycle (hp : p.IsHamiltonianCycle) : p.IsCycle :=
127143
hp.toIsCycle
128144

129-
lemma IsHamiltonianCycle.map {H : SimpleGraph β} (f : G →g H) (hf : Bijective f)
145+
lemma IsHamiltonianCycle.map (hf : Bijective f)
130146
(hp : p.IsHamiltonianCycle) : (p.map f).IsHamiltonianCycle where
131147
toIsCycle := hp.isCycle.map hf.injective
132148
isHamiltonian_tail := by
@@ -187,7 +203,7 @@ def IsHamiltonian (G : SimpleGraph α) : Prop :=
187203

188204
lemma IsHamiltonian.mono {H : SimpleGraph α} (hGH : G ≤ H) (hG : G.IsHamiltonian) :
189205
H.IsHamiltonian :=
190-
fun hα ↦ let ⟨_, p, hp⟩ := hG hα; ⟨_, p.map <| .ofLE hGH, hp.map _ bijective_id⟩
206+
fun hα ↦ let ⟨_, p, hp⟩ := hG hα; ⟨_, p.map <| .ofLE hGH, hp.map bijective_id⟩
191207

192208
lemma not_isHamiltonian_of_isEmpty [IsEmpty α] : ¬G.IsHamiltonian :=
193209
(IsEmpty.exists_iff.mp <| · <| by simp)

Mathlib/Combinatorics/SimpleGraph/Paths.lean

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ variable (G : SimpleGraph V) (G' : SimpleGraph V')
6060

6161
namespace Walk
6262

63-
variable {G} {u u' v w : V}
63+
variable {G G'} {u u' v w : V} {p : G.Walk u v} {f : G →g G'}
6464

6565
/-! ### Trails, paths, circuits, cycles -/
6666

@@ -459,6 +459,17 @@ theorem IsPath.eq_penultimate_of_mem_edges {p : G.Walk u v} (hp : p.IsPath)
459459
(hmem : s(v, w) ∈ p.edges) : w = p.penultimate := by
460460
simpa [hmem] using isPath_reverse_iff p |>.mpr hp |>.eq_snd_of_mem_edges (w := w)
461461

462+
theorem IsPath.injOn_support_of_isPath_map (h : (p.map f).IsPath) :
463+
Set.InjOn f {w | w ∈ p.support} := by
464+
intro u hu v hv hf
465+
obtain ⟨u, rfl⟩ := List.get_of_mem hu
466+
obtain ⟨v, rfl⟩ := List.get_of_mem hv
467+
congr
468+
have := List.nodup_iff_injective_getElem.mp h.support_nodup
469+
rw! (castMode := .all) [support_map, List.length_map] at this
470+
apply this
471+
simpa
472+
462473
/-! ### About cycles -/
463474

464475
-- TODO: These results could possibly be less laborious with a periodic function getCycleVert

0 commit comments

Comments
 (0)