Skip to content

Commit 1b7f970

Browse files
committed
feat(SimpleGraph): alternative characterizations of cycles/hamiltonian paths (leanprover-community#34766)
Give alternative characterizations of cycles, hamiltonian paths, and hamiltonian cycles in terms of the lengths of the underlying walks.
1 parent d1366e1 commit 1b7f970

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ theorem IsHamiltonian.getVert_surjective (hp : p.IsHamiltonian) : p.getVert.Surj
106106
.of_comp <| p.getVert_comp_val_eq_get_support ▸
107107
isHamiltonian_iff_support_get_bijective.mp hp |>.surjective
108108

109+
lemma isHamiltonian_iff_isPath_and_length_eq [Fintype α] :
110+
p.IsHamiltonian ↔ p.IsPath ∧ p.length = Fintype.card α - 1 := by
111+
by_cases! h : IsEmpty α
112+
· exact h.elim' a
113+
refine ⟨fun h ↦ ⟨h.isPath, h.length_eq⟩, fun ⟨hp, h⟩ ↦ ?_⟩
114+
have := p.isPath_iff_injective_get_support.mp hp
115+
refine isHamiltonian_iff_support_get_bijective.mpr ⟨this, this.surjective_of_finite ?_⟩
116+
refine (Fintype.equivFinOfCardEq ?_).symm
117+
simp_rw [length_support, h, Nat.sub_one_add_one Fintype.card_ne_zero]
118+
109119
/-- A Hamiltonian cycle is a cycle that visits every vertex once. -/
110120
structure IsHamiltonianCycle (p : G.Walk a a) : Prop extends p.IsCycle where
111121
isHamiltonian_tail : p.tail.IsHamiltonian
@@ -158,6 +168,12 @@ lemma IsHamiltonianCycle.support_count_of_ne (hp : p.IsHamiltonianCycle) (h : a
158168
p.support.count b = 1 := by
159169
rw [← cons_support_tail p hp.1.not_nil, List.count_cons_of_ne h, hp.isHamiltonian_tail]
160170

171+
lemma isHamiltonianCycle_iff_isCycle_and_length_eq [Fintype α] :
172+
p.IsHamiltonianCycle ↔ p.IsCycle ∧ p.length = Fintype.card α := by
173+
refine ⟨fun h ↦ ⟨h.isCycle, h.length_eq⟩, fun ⟨h₁, h₂⟩ ↦ ⟨h₁, ?_⟩⟩
174+
refine isHamiltonian_iff_isPath_and_length_eq.mpr ⟨h₁.isPath_tail, ?_⟩
175+
grind [length_tail_add_one, IsCycle.not_nil]
176+
161177
end Walk
162178

163179
variable [Fintype α]

Mathlib/Combinatorics/SimpleGraph/Paths.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ lemma IsCycle.isPath_of_append_left {p : G.Walk u v} {q : G.Walk v u} (h : ¬ q.
323323
(hcyc : (p.append q).IsCycle) : p.IsPath :=
324324
p.isPath_reverse_iff.mp ((reverse_append _ _ ▸ hcyc.reverse).isPath_of_append_right (by simpa))
325325

326+
theorem IsCycle.isPath_tail {p : G.Walk u u} (h : p.IsCycle) : p.tail.IsPath :=
327+
IsPath.mk' <| p.support_tail_of_not_nil h.not_nil ▸ h.support_nodup
328+
326329
lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) : p.tail.IsPath := by
327330
cases p with
328331
| nil => simp
@@ -492,6 +495,19 @@ lemma IsCycle.getVert_sub_one_ne_getVert_add_one {i : ℕ} {p : G.Walk u u} (hpc
492495
(by simp only [Set.mem_setOf_eq]; lia) h'
493496
lia
494497

498+
theorem isCycle_iff_isPath_tail_and_le_length {p : G.Walk u u} :
499+
p.IsCycle ↔ p.tail.IsPath ∧ 3 ≤ p.length := by
500+
refine ⟨fun h ↦ ⟨h.isPath_tail, h.three_le_length⟩, fun ⟨h₁, h₂⟩ ↦ ?_⟩
501+
cases p with
502+
| nil => simp_all
503+
| cons h' p =>
504+
simp only [getVert_cons_succ, tail_cons, isPath_copy, length_cons] at h₁ h₂
505+
refine p.cons_isCycle_iff h' |>.mpr ⟨h₁, fun hh ↦ ?_⟩
506+
have : p.support[0] = p.support[p.length - 1] := by
507+
simp [← List.head_eq_getElem_zero, h₁.eq_penultimate_of_mem_edges hh]
508+
have := p.isPath_iff_injective_get_support.mp h₁ this
509+
lia
510+
495511
/-! ### Walk decompositions -/
496512

497513
section WalkDecomp

0 commit comments

Comments
 (0)