Skip to content

Commit 2a51a80

Browse files
committed
feat(Combinatorics/SimpleGraph/Walk/Paths): a trail which isn't a path has a cycle subwalk (#39061)
- `p.IsPath ↔ ∀ (v : V) (w : G.Walk v v), w.IsSubwalk p → w.Nil` - `p.IsTrail → (p.IsPath ↔ ∀ (v : V) (w : G.Walk v v), w.IsSubwalk p → ¬w.IsCycle)`
1 parent d698adf commit 2a51a80

3 files changed

Lines changed: 36 additions & 4 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ lemma exists_mem_support_mem_erase_mem_support_takeUntil_eq_empty (s : Finset V)
505505
have := p.length_takeUntil_le hx
506506
lia
507507
obtain ⟨y, hys, hyp, h⟩ := ih _ this (s.erase x) h rfl
508-
use y, mem_of_mem_erase hys, support_takeUntil_subset p hx hyp
508+
use y, mem_of_mem_erase hys, support_takeUntil_subset_support p hx hyp
509509
rwa [takeUntil_takeUntil, erase_right_comm, filter_erase, erase_eq_of_notMem] at h
510510
simp only [mem_filter, mem_erase, ne_eq, not_and, and_imp]
511511
rintro hxy -

Mathlib/Combinatorics/SimpleGraph/Paths.lean

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,30 @@ lemma endpoint_notMem_support_takeUntil {p : G.Walk u v} (hp : p.IsPath) (hw : w
612612

613613
end WalkDecomp
614614

615+
theorem isPath_iff_isSubwalk_imp_nil {u v} {p : G.Walk u v} :
616+
p.IsPath ↔ ∀ (v : V) (w : G.Walk v v), w.IsSubwalk p → w.Nil := by
617+
refine ⟨fun hp v w hwp ↦ ?_, fun h ↦ .mk' ?_⟩
618+
· simp [w.isPath_iff_eq_nil.mp <| isPath_of_isSubwalk hwp hp]
619+
· refine List.pairwise_iff_getElem.mpr fun i j _ _ _ _ ↦ ?_
620+
let p' := p.take j |>.drop i
621+
have : ¬p'.Nil := by grind [nil_drop_iff, take_length]
622+
have : p'.IsSubwalk p := isSubwalk_drop _ i |>.trans <| p.isSubwalk_take j
623+
grind [take_getVert, getVert_eq_support_getElem]
624+
625+
theorem IsTrail.isPath_iff_isSubwalk_imp_not_isCycle {u v} {p : G.Walk u v} (ht : p.IsTrail) :
626+
p.IsPath ↔ ∀ (v : V) (w : G.Walk v v), w.IsSubwalk p → ¬w.IsCycle := by
627+
refine ⟨by grind [isPath_iff_isSubwalk_imp_nil, IsCycle.not_nil], fun h ↦ ?_⟩
628+
classical
629+
match p with
630+
| .nil => simp
631+
| .cons hadj p =>
632+
have hp := isPath_iff_isSubwalk_imp_not_isCycle ht.of_cons |>.mpr (h · · <| ·.cons hadj)
633+
refine cons_isPath_iff .. |>.mpr ⟨hp, fun hup ↦ h u (p.takeUntil u hup |>.cons hadj) ?_ ?_⟩
634+
· rw [isSubwalk_iff_support_isInfix, support_cons, support_cons]
635+
exact (List.prefix_cons_inj u |>.mpr <| p.support_takeUntil_prefix_support hup).isInfix
636+
· refine cons_isCycle_iff .. |>.mpr ⟨hp.takeUntil hup, fun he ↦ ?_⟩
637+
exact ht.edges_nodup.notMem <| p.edges_takeUntil_subset hup he
638+
615639
end Walk
616640

617641
/-! ### Type of paths -/

Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,18 @@ theorem dropUntil_copy {u v w v' w'} (p : G.Walk v w) (hv : v = v') (hw : w = w'
185185
subst_vars
186186
rfl
187187

188-
theorem support_takeUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
188+
theorem support_takeUntil_prefix_support (p : G.Walk v w) (h : u ∈ p.support) :
189+
(p.takeUntil u h).support <+: p.support := by
190+
grw [takeUntil_eq_take, support_copy, take_support_eq_support_take_succ, List.take_prefix]
191+
192+
theorem support_takeUntil_subset_support {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
189193
(p.takeUntil u h).support ⊆ p.support := fun x hx => by
190194
rw [← take_spec p h, mem_support_append_iff]
191195
exact Or.inl hx
192196

197+
@[deprecated (since := "2026-05-25")]
198+
alias support_takeUntil_subset := support_takeUntil_subset_support
199+
193200
theorem support_dropUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
194201
(p.dropUntil u h).support ⊆ p.support := fun x hx => by
195202
rw [← take_spec p h, mem_support_append_iff]
@@ -270,12 +277,13 @@ lemma length_takeUntil_lt {u v w : V} {p : G.Walk v w} (h : u ∈ p.support) (hu
270277

271278
lemma takeUntil_takeUntil {w x : V} (p : G.Walk u v) (hw : w ∈ p.support)
272279
(hx : x ∈ (p.takeUntil w hw).support) :
273-
(p.takeUntil w hw).takeUntil x hx = p.takeUntil x (p.support_takeUntil_subset hw hx) := by
280+
(p.takeUntil w hw).takeUntil x hx =
281+
p.takeUntil x (p.support_takeUntil_subset_support hw hx) := by
274282
simp_rw [← takeUntil_append_of_mem_left _ (p.dropUntil w hw) hx, take_spec]
275283

276284
lemma notMem_support_takeUntil_support_takeUntil_subset {p : G.Walk u v} {w x : V} (h : x ≠ w)
277285
(hw : w ∈ p.support) (hx : x ∈ (p.takeUntil w hw).support) :
278-
w ∉ (p.takeUntil x (p.support_takeUntil_subset hw hx)).support := by
286+
w ∉ (p.takeUntil x (p.support_takeUntil_subset_support hw hx)).support := by
279287
rw [← takeUntil_takeUntil p hw hx]
280288
intro hw'
281289
have h1 : (((p.takeUntil w hw).takeUntil x hx).takeUntil w hw').length

0 commit comments

Comments
 (0)