Skip to content

Commit 6b83b4d

Browse files
committed
feat(SimpleGraph): relate takeUntil/dropUntil to take/drop (leanprover-community#34620)
Add lemmas to allow going from takeUntil/dropUntil to a take/drop in terms of an explicit index `p.support.idxOf w`.
1 parent 85028a6 commit 6b83b4d

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Connectivity/WalkDecomp.lean

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,24 @@ lemma takeUntil_first (p : G.Walk u v) :
5757
lemma nil_takeUntil (p : G.Walk u v) (hwp : w ∈ p.support) :
5858
(p.takeUntil w hwp).Nil ↔ u = w := ⟨Nil.eq, (by cases ·; simp)⟩
5959

60+
lemma takeUntil_eq_take (p : G.Walk u v) (h : w ∈ p.support) :
61+
p.takeUntil w h = (p.take <| p.support.idxOf w).copy rfl (p.getVert_support_idxOf h) := by
62+
apply ext_support
63+
induction p with
64+
| nil =>
65+
simp only [takeUntil, eq_mpr_eq_cast, support_nil, getVert_nil, take, support_copy]
66+
grind [mem_support_nil_iff, support_nil]
67+
| @cons a _ _ _ p ih =>
68+
by_cases! h' : w = a
69+
· grind [List.idxOf_cons_self, take_zero, copy_rfl_rfl, support_nil, takeUntil_first]
70+
· rw [take_cons_eq _ _ _ (by grind), takeUntil_cons (List.mem_of_ne_of_mem h' h) h'.symm,
71+
support_cons, support_copy, ih (by grind)]
72+
grind
73+
74+
lemma length_takeUntil (p : G.Walk u v) (h : w ∈ p.support) :
75+
(p.takeUntil w h).length = p.support.idxOf w := by
76+
simp [takeUntil_eq_take, Nat.le_iff_lt_add_one, ← length_support, List.idxOf_lt_length_of_mem h]
77+
6078
/-- Given a vertex in the support of a path, give the path from (and including) that vertex to
6179
the end. In other words, drop vertices from the front of a path until (and not including)
6280
that vertex. -/
@@ -85,6 +103,29 @@ theorem take_spec {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
85103
· simp! only
86104
split_ifs with h' <;> subst_vars <;> simp [*]
87105

106+
@[simp]
107+
lemma dropUntil_first (p : G.Walk u v) (h : u ∈ p.support) : p.dropUntil u h = p := by
108+
unfold dropUntil
109+
split <;> simp
110+
111+
lemma dropUntil_eq_drop (p : G.Walk u v) (h : w ∈ p.support) :
112+
p.dropUntil w h = (p.drop <| p.support.idxOf w).copy (p.getVert_support_idxOf h) rfl := by
113+
apply ext_support
114+
induction p with
115+
| nil =>
116+
simp only [dropUntil, eq_mpr_eq_cast, support_nil, getVert_nil, drop, support_copy]
117+
grind [mem_support_nil_iff, support_nil]
118+
| @cons a _ _ _ p ih =>
119+
by_cases! h' : w = a
120+
· subst h'
121+
simp [dropUntil_first, drop_support_eq_support_drop_min]
122+
· rw [drop_cons_eq _ _ _ (by grind), support_copy, dropUntil]
123+
grind
124+
125+
lemma length_dropUntil (p : G.Walk u v) (h : w ∈ p.support) :
126+
(p.dropUntil w h).length = p.length - p.support.idxOf w := by
127+
simp [dropUntil_eq_drop]
128+
88129
theorem isSubwalk_takeUntil (p : G.Walk u v) (h : w ∈ p.support) : (p.takeUntil w h).IsSubwalk p :=
89130
⟨nil, p.dropUntil w h, by simp⟩
90131

Mathlib/Combinatorics/SimpleGraph/Walks/Operations.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,13 @@ lemma drop_add_eq (p : G.Walk u v) (n m : ℕ) :
524524
lemma nil_drop_iff (p : G.Walk u v) (n : ℕ) : (p.drop n).Nil ↔ p.length ≤ n := by
525525
induction p generalizing n <;> cases n <;> simp [*, drop]
526526

527+
lemma drop_cons_eq (h : G.Adj u v) (p : G.Walk v w) (n : ℕ) (hn : n ≠ 0) :
528+
(cons h p).drop n = (p.drop (n - 1)).copy (p.getVert_cons h hn).symm rfl := by
529+
apply ext_support
530+
obtain ⟨_, rfl⟩ := Nat.exists_add_one_eq.mpr (Nat.ne_zero_iff_zero_lt.mp hn)
531+
conv_lhs => unfold drop
532+
simp
533+
527534
lemma darts_drop (p : G.Walk u v) (n : ℕ) : (p.drop n).darts = p.darts.drop n := by
528535
induction p generalizing n <;> cases n <;> simp [*, drop]
529536

@@ -576,6 +583,11 @@ lemma take_of_length_le {u v n} {p : G.Walk u v} (h : p.length ≤ n) :
576583
rw [length_cons, Nat.add_le_add_iff_right] at h
577584
simp [take, ih h]
578585

586+
lemma take_cons_eq (h : G.Adj u v) (p : G.Walk v w) (n : ℕ) (hn : n ≠ 0) :
587+
(cons h p).take n = cons h ((p.take <| n - 1).copy rfl (p.getVert_cons h hn).symm) := by
588+
apply ext_support
589+
grind [support_copy, take_support_eq_support_take_succ]
590+
579591
lemma darts_take (p : G.Walk u v) (n : ℕ) : (p.take n).darts = p.darts.take n := by
580592
induction p generalizing n <;> cases n <;> simp [*, take]
581593

Mathlib/Combinatorics/SimpleGraph/Walks/Traversal.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ lemma getVert_eq_getD_support {u v : V} (p : G.Walk u v) (n : ℕ) :
110110
· simp [← getVert_eq_support_getElem? p h]
111111
grind [getVert_of_length_le, length_support]
112112

113+
@[simp]
114+
lemma getVert_support_idxOf [DecidableEq V] (p : G.Walk u v) (h : w ∈ p.support) :
115+
p.getVert (p.support.idxOf w) = w := by
116+
grind [getVert_eq_support_getElem]
117+
113118
theorem getVert_comp_val_eq_get_support {u v : V} (p : G.Walk u v) :
114119
p.getVert ∘ Fin.val = p.support.get := by
115120
grind [getVert_eq_support_getElem, length_support]

0 commit comments

Comments
 (0)