File: Mathlib/Combinatorics/SimpleGraph/Walk.lean

full_name: SimpleGraph.Walk.cons
code: /-- A walk is a sequence of adjacent vertices.  For vertices `u v : V`,
the type `walk u v` consists of all walks starting at `u` and ending at `v`.

We say that a walk *visits* the vertices it contains.  The set of vertices a
walk visits is `SimpleGraph.Walk.support`.

See `SimpleGraph.Walk.nil'` and `SimpleGraph.Walk.cons'` for patterns that
can be useful in definitions since they make the vertices explicit. -/
inductive Walk : V → V → Type u
  | nil {u : V} : Walk u u
  | cons {u v w : V} (h : G.Adj u v) (p : Walk v w) : Walk u w
  deriving DecidableEq
goal: G.Walk u w

full_name: SimpleGraph.Walk.nil
code: /-- A walk is a sequence of adjacent vertices.  For vertices `u v : V`,
the type `walk u v` consists of all walks starting at `u` and ending at `v`.

We say that a walk *visits* the vertices it contains.  The set of vertices a
walk visits is `SimpleGraph.Walk.support`.

See `SimpleGraph.Walk.nil'` and `SimpleGraph.Walk.cons'` for patterns that
can be useful in definitions since they make the vertices explicit. -/
inductive Walk : V → V → Type u
  | nil {u : V} : Walk u u
  | cons {u v w : V} (h : G.Adj u v) (p : Walk v w) : Walk u w
  deriving DecidableEq
goal: G.Walk u u

full_name: SimpleGraph.Walk
code: /-- A walk is a sequence of adjacent vertices.  For vertices `u v : V`,
the type `walk u v` consists of all walks starting at `u` and ending at `v`.

We say that a walk *visits* the vertices it contains.  The set of vertices a
walk visits is `SimpleGraph.Walk.support`.

See `SimpleGraph.Walk.nil'` and `SimpleGraph.Walk.cons'` for patterns that
can be useful in definitions since they make the vertices explicit. -/
inductive Walk : V → V → Type u
  | nil {u : V} : Walk u u
  | cons {u v w : V} (h : G.Adj u v) (p : Walk v w) : Walk u w
  deriving DecidableEq
goal: V → V → Type u

full_name: SimpleGraph.Walk.instInhabited_default
code: @[simps]
instance Walk.instInhabited (v : V) : Inhabited (G.Walk v v) 
goal: default = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.instInhabited
code: @[simps]
instance Walk.instInhabited (v : V) : Inhabited (G.Walk v v) 
goal: Inhabited (G.Walk v v)

full_name: SimpleGraph.Adj.toWalk
code: /-- The one-edge walk associated to a pair of adjacent vertices. -/
@[match_pattern, reducible]
def Adj.toWalk {G : SimpleGraph V} {u v : V} (h : G.Adj u v) : G.Walk u v 
goal: G.Walk u v

full_name: SimpleGraph.Walk.nil'
code: /-- Pattern to get `Walk.nil` with the vertex as an explicit argument. -/
@[match_pattern]
abbrev nil' (u : V) : G.Walk u u 
goal: G.Walk u u

full_name: SimpleGraph.Walk.cons'
code: /-- Pattern to get `Walk.cons` with the vertices as explicit arguments. -/
@[match_pattern]
abbrev cons' (u v w : V) (h : G.Adj u v) (p : G.Walk v w) : G.Walk u w 
goal: G.Walk u w

full_name: SimpleGraph.Walk.copy
code: /-- Change the endpoints of a walk using equalities. This is helpful for relaxing
definitional equality constraints and to be able to state otherwise difficult-to-state
lemmas. While this is a simple wrapper around `Eq.rec`, it gives a canonical way to write it.

The simp-normal form is for the `copy` to be pushed outward. That way calculations can
occur within the "copy context." -/
protected def copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') : G.Walk u' v' 
goal: G.Walk u' v'

full_name: SimpleGraph.Walk.copy_rfl_rfl
code: @[simp]
theorem copy_rfl_rfl {u v} (p : G.Walk u v) : p.copy rfl rfl = p 
goal: p.copy ⋯ ⋯ = p

full_name: SimpleGraph.Walk.copy_copy
code: @[simp]
theorem copy_copy {u v u' v' u'' v''} (p : G.Walk u v)
    (hu : u = u') (hv : v = v') (hu' : u' = u'') (hv' : v' = v'') :
    (p.copy hu hv).copy hu' hv' = p.copy (hu.trans hu') (hv.trans hv') 
goal: (p.copy hu hv).copy hu' hv' = p.copy ⋯ ⋯

full_name: SimpleGraph.Walk.copy_nil
code: @[simp]
theorem copy_nil {u u'} (hu : u = u') : (Walk.nil : G.Walk u u).copy hu hu = Walk.nil 
goal: SimpleGraph.Walk.nil.copy hu hu = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.copy_cons
code: theorem copy_cons {u v w u' w'} (h : G.Adj u v) (p : G.Walk v w) (hu : u = u') (hw : w = w') :
    (Walk.cons h p).copy hu hw = Walk.cons (hu ▸ h) (p.copy rfl hw) 
goal: (SimpleGraph.Walk.cons h p).copy hu hw = SimpleGraph.Walk.cons ⋯ (p.copy ⋯ hw)

full_name: SimpleGraph.Walk.cons_copy
code: @[simp]
theorem cons_copy {u v w v' w'} (h : G.Adj u v) (p : G.Walk v' w') (hv : v' = v) (hw : w' = w) :
    Walk.cons h (p.copy hv hw) = (Walk.cons (hv ▸ h) p).copy rfl hw 
goal: SimpleGraph.Walk.cons h (p.copy hv hw) = (SimpleGraph.Walk.cons ⋯ p).copy ⋯ hw

full_name: SimpleGraph.Walk.exists_eq_cons_of_ne
code: theorem exists_eq_cons_of_ne {u v : V} (hne : u ≠ v) :
    ∀ (p : G.Walk u v), ∃ (w : V) (h : G.Adj u w) (p' : G.Walk w v), p = cons h p'
  
goal: ∃ w, ∃ (h : G.Adj u w), ∃ p', p = SimpleGraph.Walk.cons h p'

full_name: SimpleGraph.Walk.length
code: /-- The length of a walk is the number of edges/darts along it. -/
def length {u v : V} : G.Walk u v → ℕ
  
goal: G.Walk u v → ℕ

full_name: SimpleGraph.Walk.append
code: /-- The concatenation of two compatible walks. -/
@[trans]
def append {u v w : V} : G.Walk u v → G.Walk v w → G.Walk u w
  
goal: G.Walk u v → G.Walk v w → G.Walk u w

full_name: SimpleGraph.Walk.concat
code: /-- The reversed version of `SimpleGraph.Walk.cons`, concatenating an edge to
the end of a walk. -/
def concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) : G.Walk u w 
goal: G.Walk u w

full_name: SimpleGraph.Walk.concat_eq_append
code: theorem concat_eq_append {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    p.concat h = p.append (cons h nil) 
goal: p.concat h = p.append (SimpleGraph.Walk.cons h SimpleGraph.Walk.nil)

full_name: SimpleGraph.Walk.reverseAux
code: /-- The concatenation of the reverse of the first walk with the second walk. -/
protected def reverseAux {u v w : V} : G.Walk u v → G.Walk u w → G.Walk v w
  
goal: G.Walk u v → G.Walk u w → G.Walk v w

full_name: SimpleGraph.Walk.reverse
code: /-- The walk in reverse. -/
@[symm]
def reverse {u v : V} (w : G.Walk u v) : G.Walk v u 
goal: G.Walk v u

full_name: SimpleGraph.Walk.getVert
code: /-- Get the `n`th vertex from a walk, where `n` is generally expected to be
between `0` and `p.length`, inclusive.
If `n` is greater than or equal to `p.length`, the result is the path's endpoint. -/
def getVert {u v : V} : G.Walk u v → ℕ → V
  
goal: G.Walk u v → ℕ → V

full_name: SimpleGraph.Walk.getVert_zero
code: @[simp]
theorem getVert_zero {u v} (w : G.Walk u v) : w.getVert 0 = u 
goal: w.getVert 0 = u

full_name: SimpleGraph.Walk.getVert_of_length_le
code: theorem getVert_of_length_le {u v} (w : G.Walk u v) {i : ℕ} (hi : w.length ≤ i) :
    w.getVert i = v 
goal: w.getVert i = v

full_name: SimpleGraph.Walk.getVert_length
code: @[simp]
theorem getVert_length {u v} (w : G.Walk u v) : w.getVert w.length = v 
goal: w.getVert w.length = v

full_name: SimpleGraph.Walk.adj_getVert_succ
code: theorem adj_getVert_succ {u v} (w : G.Walk u v) {i : ℕ} (hi : i < w.length) :
    G.Adj (w.getVert i) (w.getVert (i + 1)) 
goal: G.Adj (w.getVert i) (w.getVert (i + 1))

full_name: SimpleGraph.Walk.cons_getVert_succ
code: @[simp]
lemma cons_getVert_succ {u v w n} (p : G.Walk v w) (h : G.Adj u v) :
    (p.cons h).getVert (n + 1) = p.getVert n 
goal: (SimpleGraph.Walk.cons h p).getVert (n + 1) = p.getVert n

full_name: SimpleGraph.Walk.cons_getVert
code: lemma cons_getVert {u v w n} (p : G.Walk v w) (h : G.Adj u v) (hn : n ≠ 0) :
    (p.cons h).getVert n = p.getVert (n - 1) 
goal: (SimpleGraph.Walk.cons h p).getVert n = p.getVert (n - 1)

full_name: SimpleGraph.Walk.cons_append
code: @[simp]
theorem cons_append {u v w x : V} (h : G.Adj u v) (p : G.Walk v w) (q : G.Walk w x) :
    (cons h p).append q = cons h (p.append q) 
goal: (SimpleGraph.Walk.cons h p).append q = SimpleGraph.Walk.cons h (p.append q)

full_name: SimpleGraph.Walk.cons_nil_append
code: @[simp]
theorem cons_nil_append {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h nil).append p = cons h p 
goal: (SimpleGraph.Walk.cons h SimpleGraph.Walk.nil).append p = SimpleGraph.Walk.cons h p

full_name: SimpleGraph.Walk.append_nil
code: @[simp]
theorem append_nil {u v : V} (p : G.Walk u v) : p.append nil = p 
goal: p.append SimpleGraph.Walk.nil = p

full_name: SimpleGraph.Walk.nil_append
code: @[simp]
theorem nil_append {u v : V} (p : G.Walk u v) : nil.append p = p 
goal: SimpleGraph.Walk.nil.append p = p

full_name: SimpleGraph.Walk.append_assoc
code: theorem append_assoc {u v w x : V} (p : G.Walk u v) (q : G.Walk v w) (r : G.Walk w x) :
    p.append (q.append r) = (p.append q).append r 
goal: p.append (q.append r) = (p.append q).append r

full_name: SimpleGraph.Walk.append_copy_copy
code: @[simp]
theorem append_copy_copy {u v w u' v' w'} (p : G.Walk u v) (q : G.Walk v w)
    (hu : u = u') (hv : v = v') (hw : w = w') :
    (p.copy hu hv).append (q.copy hv hw) = (p.append q).copy hu hw 
goal: (p.copy hu hv).append (q.copy hv hw) = (p.append q).copy hu hw

full_name: SimpleGraph.Walk.concat_nil
code: theorem concat_nil {u v : V} (h : G.Adj u v) : nil.concat h = cons h nil 
goal: SimpleGraph.Walk.nil.concat h = SimpleGraph.Walk.cons h SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.concat_cons
code: @[simp]
theorem concat_cons {u v w x : V} (h : G.Adj u v) (p : G.Walk v w) (h' : G.Adj w x) :
    (cons h p).concat h' = cons h (p.concat h') 
goal: (SimpleGraph.Walk.cons h p).concat h' = SimpleGraph.Walk.cons h (p.concat h')

full_name: SimpleGraph.Walk.append_concat
code: theorem append_concat {u v w x : V} (p : G.Walk u v) (q : G.Walk v w) (h : G.Adj w x) :
    p.append (q.concat h) = (p.append q).concat h 
goal: p.append (q.concat h) = (p.append q).concat h

full_name: SimpleGraph.Walk.concat_append
code: theorem concat_append {u v w x : V} (p : G.Walk u v) (h : G.Adj v w) (q : G.Walk w x) :
    (p.concat h).append q = p.append (cons h q) 
goal: (p.concat h).append q = p.append (SimpleGraph.Walk.cons h q)

full_name: SimpleGraph.Walk.exists_cons_eq_concat
code: /-- A non-trivial `cons` walk is representable as a `concat` walk. -/
theorem exists_cons_eq_concat {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    ∃ (x : V) (q : G.Walk u x) (h' : G.Adj x w), cons h p = q.concat h' 
goal: ∃ x q, ∃ (h' : G.Adj x w), SimpleGraph.Walk.cons h p = q.concat h'

full_name: SimpleGraph.Walk.exists_concat_eq_cons
code: /-- A non-trivial `concat` walk is representable as a `cons` walk. -/
theorem exists_concat_eq_cons {u v w : V} :
    ∀ (p : G.Walk u v) (h : G.Adj v w),
      ∃ (x : V) (h' : G.Adj u x) (q : G.Walk x w), p.concat h = cons h' q
  
goal: ∃ x, ∃ (h' : G.Adj u x), ∃ q, p.concat h = SimpleGraph.Walk.cons h' q

full_name: SimpleGraph.Walk.reverse_nil
code: @[simp]
theorem reverse_nil {u : V} : (nil : G.Walk u u).reverse = nil 
goal: SimpleGraph.Walk.nil.reverse = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.reverse_singleton
code: theorem reverse_singleton {u v : V} (h : G.Adj u v) : (cons h nil).reverse = cons (G.symm h) nil 
goal: (SimpleGraph.Walk.cons h SimpleGraph.Walk.nil).reverse = SimpleGraph.Walk.cons ⋯ SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.cons_reverseAux
code: @[simp]
theorem cons_reverseAux {u v w x : V} (p : G.Walk u v) (q : G.Walk w x) (h : G.Adj w u) :
    (cons h p).reverseAux q = p.reverseAux (cons (G.symm h) q) 
goal: (SimpleGraph.Walk.cons h p).reverseAux q = p.reverseAux (SimpleGraph.Walk.cons ⋯ q)

full_name: SimpleGraph.Walk.append_reverseAux
code: @[simp]
protected theorem append_reverseAux {u v w x : V}
    (p : G.Walk u v) (q : G.Walk v w) (r : G.Walk u x) :
    (p.append q).reverseAux r = q.reverseAux (p.reverseAux r) 
goal: (p.append q).reverseAux r = q.reverseAux (p.reverseAux r)

full_name: SimpleGraph.Walk.reverseAux_append
code: @[simp]
protected theorem reverseAux_append {u v w x : V}
    (p : G.Walk u v) (q : G.Walk u w) (r : G.Walk w x) :
    (p.reverseAux q).append r = p.reverseAux (q.append r) 
goal: (p.reverseAux q).append r = p.reverseAux (q.append r)

full_name: SimpleGraph.Walk.reverseAux_eq_reverse_append
code: protected theorem reverseAux_eq_reverse_append {u v w : V} (p : G.Walk u v) (q : G.Walk u w) :
    p.reverseAux q = p.reverse.append q 
goal: p.reverseAux q = p.reverse.append q

full_name: SimpleGraph.Walk.reverse_cons
code: @[simp]
theorem reverse_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).reverse = p.reverse.append (cons (G.symm h) nil) 
goal: (SimpleGraph.Walk.cons h p).reverse = p.reverse.append (SimpleGraph.Walk.cons ⋯ SimpleGraph.Walk.nil)

full_name: SimpleGraph.Walk.reverse_copy
code: @[simp]
theorem reverse_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).reverse = p.reverse.copy hv hu 
goal: (p.copy hu hv).reverse = p.reverse.copy hv hu

full_name: SimpleGraph.Walk.reverse_append
code: @[simp]
theorem reverse_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) :
    (p.append q).reverse = q.reverse.append p.reverse 
goal: (p.append q).reverse = q.reverse.append p.reverse

full_name: SimpleGraph.Walk.reverse_concat
code: @[simp]
theorem reverse_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    (p.concat h).reverse = cons (G.symm h) p.reverse 
goal: (p.concat h).reverse = SimpleGraph.Walk.cons ⋯ p.reverse

full_name: SimpleGraph.Walk.reverse_reverse
code: @[simp]
theorem reverse_reverse {u v : V} (p : G.Walk u v) : p.reverse.reverse = p 
goal: p.reverse.reverse = p

full_name: SimpleGraph.Walk.reverse_surjective
code: theorem reverse_surjective {u v : V} : Function.Surjective (reverse : G.Walk u v → _) 
goal: Function.Surjective SimpleGraph.Walk.reverse

full_name: SimpleGraph.Walk.reverse_injective
code: theorem reverse_injective {u v : V} : Function.Injective (reverse : G.Walk u v → _) 
goal: Function.Injective SimpleGraph.Walk.reverse

full_name: SimpleGraph.Walk.reverse_bijective
code: theorem reverse_bijective {u v : V} : Function.Bijective (reverse : G.Walk u v → _) 
goal: Function.Bijective SimpleGraph.Walk.reverse

full_name: SimpleGraph.Walk.length_nil
code: @[simp]
theorem length_nil {u : V} : (nil : G.Walk u u).length = 0 
goal: SimpleGraph.Walk.nil.length = 0

full_name: SimpleGraph.Walk.length_cons
code: @[simp]
theorem length_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).length = p.length + 1 
goal: (SimpleGraph.Walk.cons h p).length = p.length + 1

full_name: SimpleGraph.Walk.length_copy
code: @[simp]
theorem length_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).length = p.length 
goal: (p.copy hu hv).length = p.length

full_name: SimpleGraph.Walk.length_append
code: @[simp]
theorem length_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) :
    (p.append q).length = p.length + q.length 
goal: (p.append q).length = p.length + q.length

full_name: SimpleGraph.Walk.length_concat
code: @[simp]
theorem length_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    (p.concat h).length = p.length + 1 
goal: (p.concat h).length = p.length + 1

full_name: SimpleGraph.Walk.length_reverseAux
code: @[simp]
protected theorem length_reverseAux {u v w : V} (p : G.Walk u v) (q : G.Walk u w) :
    (p.reverseAux q).length = p.length + q.length 
goal: (p.reverseAux q).length = p.length + q.length

full_name: SimpleGraph.Walk.length_reverse
code: @[simp]
theorem length_reverse {u v : V} (p : G.Walk u v) : p.reverse.length = p.length 
goal: p.reverse.length = p.length

full_name: SimpleGraph.Walk.eq_of_length_eq_zero
code: theorem eq_of_length_eq_zero {u v : V} : ∀ {p : G.Walk u v}, p.length = 0 → u = v
  
goal: p.length = 0 → u = v

full_name: SimpleGraph.Walk.adj_of_length_eq_one
code: theorem adj_of_length_eq_one {u v : V} : ∀ {p : G.Walk u v}, p.length = 1 → G.Adj u v
  
goal: p.length = 1 → G.Adj u v

full_name: SimpleGraph.Walk.exists_length_eq_zero_iff
code: @[simp]
theorem exists_length_eq_zero_iff {u v : V} : (∃ p : G.Walk u v, p.length = 0) ↔ u = v 
goal: (∃ p, p.length = 0) ↔ u = v

full_name: SimpleGraph.Walk.length_eq_zero_iff
code: @[simp]
theorem length_eq_zero_iff {u : V} {p : G.Walk u u} : p.length = 0 ↔ p = nil 
goal: p.length = 0 ↔ p = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.getVert_append
code: theorem getVert_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) (i : ℕ) :
    (p.append q).getVert i = if i < p.length then p.getVert i else q.getVert (i - p.length) 
goal: (p.append q).getVert i = if i < p.length then p.getVert i else q.getVert (i - p.length)

full_name: SimpleGraph.Walk.getVert_reverse
code: theorem getVert_reverse {u v : V} (p : G.Walk u v) (i : ℕ) :
    p.reverse.getVert i = p.getVert (p.length - i) 
goal: p.reverse.getVert i = p.getVert (p.length - i)

full_name: SimpleGraph.Walk.concatRecAux
code: /-- Auxiliary definition for `SimpleGraph.Walk.concatRec` -/
def concatRecAux {u v : V} : (p : G.Walk u v) → motive v u p.reverse
  
goal: motive v u p.reverse

full_name: SimpleGraph.Walk.concatRec
code: /-- Recursor on walks by inducting on `SimpleGraph.Walk.concat`.

This is inducting from the opposite end of the walk compared
to `SimpleGraph.Walk.rec`, which inducts on `SimpleGraph.Walk.cons`. -/
@[elab_as_elim]
def concatRec {u v : V} (p : G.Walk u v) : motive u v p 
goal: motive u v p

full_name: SimpleGraph.Walk.concatRec_nil
code: @[simp]
theorem concatRec_nil (u : V) :
    @concatRec _ _ motive @Hnil @Hconcat _ _ (nil : G.Walk u u) = Hnil 
goal: SimpleGraph.Walk.concatRec Hnil Hconcat SimpleGraph.Walk.nil = Hnil

full_name: SimpleGraph.Walk.concatRec_concat
code: @[simp]
theorem concatRec_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    @concatRec _ _ motive @Hnil @Hconcat _ _ (p.concat h) =
      Hconcat p h (concatRec @Hnil @Hconcat p) 
goal: SimpleGraph.Walk.concatRec Hnil Hconcat (p.concat h) = Hconcat p h (SimpleGraph.Walk.concatRec Hnil Hconcat p)

full_name: SimpleGraph.Walk.concat_ne_nil
code: theorem concat_ne_nil {u v : V} (p : G.Walk u v) (h : G.Adj v u) : p.concat h ≠ nil 
goal: p.concat h ≠ SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.concat_inj
code: theorem concat_inj {u v v' w : V} {p : G.Walk u v} {h : G.Adj v w} {p' : G.Walk u v'}
    {h' : G.Adj v' w} (he : p.concat h = p'.concat h') : ∃ hv : v = v', p.copy rfl hv = p' 
goal: ∃ (hv : v = v'), p.copy ⋯ hv = p'

full_name: SimpleGraph.Walk.support
code: /-- The `support` of a walk is the list of vertices it visits in order. -/
def support {u v : V} : G.Walk u v → List V
  
goal: G.Walk u v → List V

full_name: SimpleGraph.Walk.darts
code: /-- The `darts` of a walk is the list of darts it visits in order. -/
def darts {u v : V} : G.Walk u v → List G.Dart
  
goal: G.Walk u v → List G.Dart

full_name: SimpleGraph.Walk.edges
code: /-- The `edges` of a walk is the list of edges it visits in order.
This is defined to be the list of edges underlying `SimpleGraph.Walk.darts`. -/
def edges {u v : V} (p : G.Walk u v) : List (Sym2 V) 
goal: List (Sym2 V)

full_name: SimpleGraph.Walk.support_nil
code: @[simp]
theorem support_nil {u : V} : (nil : G.Walk u u).support = [u] 
goal: SimpleGraph.Walk.nil.support = [u]

full_name: SimpleGraph.Walk.support_cons
code: @[simp]
theorem support_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).support = u :: p.support 
goal: (SimpleGraph.Walk.cons h p).support = u :: p.support

full_name: SimpleGraph.Walk.support_concat
code: @[simp]
theorem support_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    (p.concat h).support = p.support.concat w 
goal: (p.concat h).support = p.support.concat w

full_name: SimpleGraph.Walk.support_copy
code: @[simp]
theorem support_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).support = p.support 
goal: (p.copy hu hv).support = p.support

full_name: SimpleGraph.Walk.support_append
code: theorem support_append {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    (p.append p').support = p.support ++ p'.support.tail 
goal: (p.append p').support = p.support ++ p'.support.tail

full_name: SimpleGraph.Walk.support_reverse
code: @[simp]
theorem support_reverse {u v : V} (p : G.Walk u v) : p.reverse.support = p.support.reverse 
goal: p.reverse.support = p.support.reverse

full_name: SimpleGraph.Walk.support_ne_nil
code: @[simp]
theorem support_ne_nil {u v : V} (p : G.Walk u v) : p.support ≠ [] 
goal: p.support ≠ []

full_name: SimpleGraph.Walk.tail_support_append
code: theorem tail_support_append {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    (p.append p').support.tail = p.support.tail ++ p'.support.tail 
goal: (p.append p').support.tail = p.support.tail ++ p'.support.tail

full_name: SimpleGraph.Walk.support_eq_cons
code: theorem support_eq_cons {u v : V} (p : G.Walk u v) : p.support = u :: p.support.tail 
goal: p.support = u :: p.support.tail

full_name: SimpleGraph.Walk.start_mem_support
code: @[simp]
theorem start_mem_support {u v : V} (p : G.Walk u v) : u ∈ p.support 
goal: u ∈ p.support

full_name: SimpleGraph.Walk.end_mem_support
code: @[simp]
theorem end_mem_support {u v : V} (p : G.Walk u v) : v ∈ p.support 
goal: v ∈ p.support

full_name: SimpleGraph.Walk.support_nonempty
code: @[simp]
theorem support_nonempty {u v : V} (p : G.Walk u v) : { w | w ∈ p.support }.Nonempty 
goal: {w | w ∈ p.support}.Nonempty

full_name: SimpleGraph.Walk.mem_support_iff
code: theorem mem_support_iff {u v w : V} (p : G.Walk u v) :
    w ∈ p.support ↔ w = u ∨ w ∈ p.support.tail 
goal: w ∈ p.support ↔ w = u ∨ w ∈ p.support.tail

full_name: SimpleGraph.Walk.mem_support_nil_iff
code: theorem mem_support_nil_iff {u v : V} : u ∈ (nil : G.Walk v v).support ↔ u = v 
goal: u ∈ SimpleGraph.Walk.nil.support ↔ u = v

full_name: SimpleGraph.Walk.mem_tail_support_append_iff
code: @[simp]
theorem mem_tail_support_append_iff {t u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    t ∈ (p.append p').support.tail ↔ t ∈ p.support.tail ∨ t ∈ p'.support.tail 
goal: t ∈ (p.append p').support.tail ↔ t ∈ p.support.tail ∨ t ∈ p'.support.tail

full_name: SimpleGraph.Walk.end_mem_tail_support_of_ne
code: @[simp]
theorem end_mem_tail_support_of_ne {u v : V} (h : u ≠ v) (p : G.Walk u v) : v ∈ p.support.tail 
goal: v ∈ p.support.tail

full_name: SimpleGraph.Walk.mem_support_append_iff
code: @[simp, nolint unusedHavesSuffices]
theorem mem_support_append_iff {t u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    t ∈ (p.append p').support ↔ t ∈ p.support ∨ t ∈ p'.support 
goal: t ∈ (p.append p').support ↔ t ∈ p.support ∨ t ∈ p'.support

full_name: SimpleGraph.Walk.subset_support_append_left
code: @[simp]
theorem subset_support_append_left {V : Type u} {G : SimpleGraph V} {u v w : V}
    (p : G.Walk u v) (q : G.Walk v w) : p.support ⊆ (p.append q).support 
goal: p.support ⊆ (p.append q).support

full_name: SimpleGraph.Walk.subset_support_append_right
code: @[simp]
theorem subset_support_append_right {V : Type u} {G : SimpleGraph V} {u v w : V}
    (p : G.Walk u v) (q : G.Walk v w) : q.support ⊆ (p.append q).support 
goal: q.support ⊆ (p.append q).support

full_name: SimpleGraph.Walk.coe_support
code: theorem coe_support {u v : V} (p : G.Walk u v) :
    (p.support : Multiset V) = {u} + p.support.tail 
goal: ↑p.support = {u} + ↑p.support.tail

full_name: SimpleGraph.Walk.coe_support_append
code: theorem coe_support_append {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    ((p.append p').support : Multiset V) = {u} + p.support.tail + p'.support.tail 
goal: ↑(p.append p').support = {u} + ↑p.support.tail + ↑p'.support.tail

full_name: SimpleGraph.Walk.coe_support_append'
code: theorem coe_support_append' [DecidableEq V] {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    ((p.append p').support : Multiset V) = p.support + p'.support - {v} 
goal: ↑(p.append p').support = ↑p.support + ↑p'.support - {v}

full_name: SimpleGraph.Walk.chain_adj_support
code: theorem chain_adj_support {u v w : V} (h : G.Adj u v) :
    ∀ (p : G.Walk v w), List.Chain G.Adj u p.support
  
goal: List.Chain G.Adj u p.support

full_name: SimpleGraph.Walk.chain'_adj_support
code: theorem chain'_adj_support {u v : V} : ∀ (p : G.Walk u v), List.Chain' G.Adj p.support
  
goal: List.Chain' G.Adj p.support

full_name: SimpleGraph.Walk.chain_dartAdj_darts
code: theorem chain_dartAdj_darts {d : G.Dart} {v w : V} (h : d.snd = v) (p : G.Walk v w) :
    List.Chain G.DartAdj d p.darts 
goal: List.Chain G.DartAdj d p.darts

full_name: SimpleGraph.Walk.chain'_dartAdj_darts
code: theorem chain'_dartAdj_darts {u v : V} : ∀ (p : G.Walk u v), List.Chain' G.DartAdj p.darts
  
goal: List.Chain' G.DartAdj p.darts

full_name: SimpleGraph.Walk.edges_subset_edgeSet
code: /-- Every edge in a walk's edge list is an edge of the graph.
It is written in this form (rather than using `⊆`) to avoid unsightly coercions. -/
theorem edges_subset_edgeSet {u v : V} :
    ∀ (p : G.Walk u v) ⦃e : Sym2 V⦄, e ∈ p.edges → e ∈ G.edgeSet
  
goal: e ∈ p.edges → e ∈ G.edgeSet

full_name: SimpleGraph.Walk.adj_of_mem_edges
code: theorem adj_of_mem_edges {u v x y : V} (p : G.Walk u v) (h : s(x, y) ∈ p.edges) : G.Adj x y 
goal: G.Adj x y

full_name: SimpleGraph.Walk.darts_nil
code: @[simp]
theorem darts_nil {u : V} : (nil : G.Walk u u).darts = [] 
goal: SimpleGraph.Walk.nil.darts = []

full_name: SimpleGraph.Walk.darts_cons
code: @[simp]
theorem darts_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).darts = ⟨(u, v), h⟩ :: p.darts 
goal: (SimpleGraph.Walk.cons h p).darts = { toProd := (u, v), adj := h } :: p.darts

full_name: SimpleGraph.Walk.darts_concat
code: @[simp]
theorem darts_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    (p.concat h).darts = p.darts.concat ⟨(v, w), h⟩ 
goal: (p.concat h).darts = p.darts.concat { toProd := (v, w), adj := h }

full_name: SimpleGraph.Walk.darts_copy
code: @[simp]
theorem darts_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).darts = p.darts 
goal: (p.copy hu hv).darts = p.darts

full_name: SimpleGraph.Walk.darts_append
code: @[simp]
theorem darts_append {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    (p.append p').darts = p.darts ++ p'.darts 
goal: (p.append p').darts = p.darts ++ p'.darts

full_name: SimpleGraph.Walk.darts_reverse
code: @[simp]
theorem darts_reverse {u v : V} (p : G.Walk u v) :
    p.reverse.darts = (p.darts.map Dart.symm).reverse 
goal: p.reverse.darts = (List.map SimpleGraph.Dart.symm p.darts).reverse

full_name: SimpleGraph.Walk.mem_darts_reverse
code: theorem mem_darts_reverse {u v : V} {d : G.Dart} {p : G.Walk u v} :
    d ∈ p.reverse.darts ↔ d.symm ∈ p.darts 
goal: d ∈ p.reverse.darts ↔ d.symm ∈ p.darts

full_name: SimpleGraph.Walk.cons_map_snd_darts
code: theorem cons_map_snd_darts {u v : V} (p : G.Walk u v) : (u :: p.darts.map (·.snd)) = p.support 
goal: u :: List.map (fun x => x.toProd.2) p.darts = p.support

full_name: SimpleGraph.Walk.map_snd_darts
code: theorem map_snd_darts {u v : V} (p : G.Walk u v) : p.darts.map (·.snd) = p.support.tail 
goal: List.map (fun x => x.toProd.2) p.darts = p.support.tail

full_name: SimpleGraph.Walk.map_fst_darts_append
code: theorem map_fst_darts_append {u v : V} (p : G.Walk u v) :
    p.darts.map (·.fst) ++ [v] = p.support 
goal: List.map (fun x => x.toProd.1) p.darts ++ [v] = p.support

full_name: SimpleGraph.Walk.map_fst_darts
code: theorem map_fst_darts {u v : V} (p : G.Walk u v) : p.darts.map (·.fst) = p.support.dropLast 
goal: List.map (fun x => x.toProd.1) p.darts = p.support.dropLast

full_name: SimpleGraph.Walk.edges_nil
code: @[simp]
theorem edges_nil {u : V} : (nil : G.Walk u u).edges = [] 
goal: SimpleGraph.Walk.nil.edges = []

full_name: SimpleGraph.Walk.edges_cons
code: @[simp]
theorem edges_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).edges = s(u, v) :: p.edges 
goal: (SimpleGraph.Walk.cons h p).edges = s(u, v) :: p.edges

full_name: SimpleGraph.Walk.edges_concat
code: @[simp]
theorem edges_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) :
    (p.concat h).edges = p.edges.concat s(v, w) 
goal: (p.concat h).edges = p.edges.concat s(v, w)

full_name: SimpleGraph.Walk.edges_copy
code: @[simp]
theorem edges_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).edges = p.edges 
goal: (p.copy hu hv).edges = p.edges

full_name: SimpleGraph.Walk.edges_append
code: @[simp]
theorem edges_append {u v w : V} (p : G.Walk u v) (p' : G.Walk v w) :
    (p.append p').edges = p.edges ++ p'.edges 
goal: (p.append p').edges = p.edges ++ p'.edges

full_name: SimpleGraph.Walk.edges_reverse
code: @[simp]
theorem edges_reverse {u v : V} (p : G.Walk u v) : p.reverse.edges = p.edges.reverse 
goal: p.reverse.edges = p.edges.reverse

full_name: SimpleGraph.Walk.length_support
code: @[simp]
theorem length_support {u v : V} (p : G.Walk u v) : p.support.length = p.length + 1 
goal: p.support.length = p.length + 1

full_name: SimpleGraph.Walk.length_darts
code: @[simp]
theorem length_darts {u v : V} (p : G.Walk u v) : p.darts.length = p.length 
goal: p.darts.length = p.length

full_name: SimpleGraph.Walk.length_edges
code: @[simp]
theorem length_edges {u v : V} (p : G.Walk u v) : p.edges.length = p.length 
goal: p.edges.length = p.length

full_name: SimpleGraph.Walk.dart_fst_mem_support_of_mem_darts
code: theorem dart_fst_mem_support_of_mem_darts {u v : V} :
    ∀ (p : G.Walk u v) {d : G.Dart}, d ∈ p.darts → d.fst ∈ p.support
  
goal: d ∈ p.darts → d.toProd.1 ∈ p.support

full_name: SimpleGraph.Walk.dart_snd_mem_support_of_mem_darts
code: theorem dart_snd_mem_support_of_mem_darts {u v : V} (p : G.Walk u v) {d : G.Dart}
    (h : d ∈ p.darts) : d.snd ∈ p.support 
goal: d.toProd.2 ∈ p.support

full_name: SimpleGraph.Walk.fst_mem_support_of_mem_edges
code: theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : s(t, u) ∈ p.edges) :
    t ∈ p.support 
goal: t ∈ p.support

full_name: SimpleGraph.Walk.snd_mem_support_of_mem_edges
code: theorem snd_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : s(t, u) ∈ p.edges) :
    u ∈ p.support 
goal: u ∈ p.support

full_name: SimpleGraph.Walk.darts_nodup_of_support_nodup
code: theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup 
goal: p.darts.Nodup

full_name: SimpleGraph.Walk.edges_nodup_of_support_nodup
code: theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup 
goal: p.edges.Nodup

full_name: SimpleGraph.Walk.Nil
code: /-- Predicate for the empty walk.

Solves the dependent type problem where `p = G.Walk.nil` typechecks
only if `p` has defeq endpoints. -/
inductive Nil : {v w : V} → G.Walk v w → Prop
  | nil {u : V} : Nil (nil : G.Walk u u)
goal: G.Walk v w → Prop

full_name: SimpleGraph.Walk.Nil.nil
code: /-- Predicate for the empty walk.

Solves the dependent type problem where `p = G.Walk.nil` typechecks
only if `p` has defeq endpoints. -/
inductive Nil : {v w : V} → G.Walk v w → Prop
  | nil {u : V} : Nil (nil : G.Walk u u)
goal: SimpleGraph.Walk.nil.Nil

full_name: SimpleGraph.Walk.nil_nil
code: @[simp] lemma nil_nil : (nil : G.Walk u u).Nil 
goal: SimpleGraph.Walk.nil.Nil

full_name: SimpleGraph.Walk.not_nil_cons
code: @[simp] lemma not_nil_cons {h : G.Adj u v} {p : G.Walk v w} : ¬ (cons h p).Nil 
goal: ¬(SimpleGraph.Walk.cons h p).Nil

full_name: SimpleGraph.Walk.instDecidableNil
code: instance (p : G.Walk v w) : Decidable p.Nil 
goal: Decidable p.Nil

full_name: SimpleGraph.Walk.Nil.eq
code: protected lemma Nil.eq {p : G.Walk v w} : p.Nil → v = w 
goal: p.Nil → v = w

full_name: SimpleGraph.Walk.not_nil_of_ne
code: lemma not_nil_of_ne {p : G.Walk v w} : v ≠ w → ¬ p.Nil 
goal: v ≠ w → ¬p.Nil

full_name: SimpleGraph.Walk.nil_iff_support_eq
code: lemma nil_iff_support_eq {p : G.Walk v w} : p.Nil ↔ p.support = [v] 
goal: p.Nil ↔ p.support = [v]

full_name: SimpleGraph.Walk.nil_iff_length_eq
code: lemma nil_iff_length_eq {p : G.Walk v w} : p.Nil ↔ p.length = 0 
goal: p.Nil ↔ p.length = 0

full_name: SimpleGraph.Walk.not_nil_iff
code: lemma not_nil_iff {p : G.Walk v w} :
    ¬ p.Nil ↔ ∃ (u : V) (h : G.Adj v u) (q : G.Walk u w), p = cons h q 
goal: ¬p.Nil ↔ ∃ u, ∃ (h : G.Adj v u), ∃ q, p = SimpleGraph.Walk.cons h q

full_name: SimpleGraph.Walk.nil_iff_eq_nil
code: /-- A walk with its endpoints defeq is `Nil` if and only if it is equal to `nil`. -/
lemma nil_iff_eq_nil : ∀ {p : G.Walk v v}, p.Nil ↔ p = nil
  
goal: p.Nil ↔ p = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.notNilRec
code: @[elab_as_elim]
def notNilRec {motive : {u w : V} → (p : G.Walk u w) → (h : ¬ p.Nil) → Sort*}
    (cons : {u v w : V} → (h : G.Adj u v) → (q : G.Walk v w) → motive (cons h q) not_nil_cons)
    (p : G.Walk u w) : (hp : ¬ p.Nil) → motive p hp 
goal: motive p hp

full_name: SimpleGraph.Walk.notNilRec_cons
code: @[simp]
lemma notNilRec_cons {motive : {u w : V} → (p : G.Walk u w) → ¬ p.Nil → Sort*}
    (cons : {u v w : V} → (h : G.Adj u v) → (q : G.Walk v w) →
    motive (q.cons h) Walk.not_nil_cons) (h' : G.Adj u v) (q' : G.Walk v w) :
    @Walk.notNilRec _ _ _ _ _ cons _ _ = cons h' q' 
goal: SimpleGraph.Walk.notNilRec (fun {u v w} => cons) (SimpleGraph.Walk.cons h' q') ⋯ = cons h' q'

full_name: SimpleGraph.Walk.sndOfNotNil
code: /-- The second vertex along a non-nil walk. -/
def sndOfNotNil (p : G.Walk v w) (hp : ¬ p.Nil) : V 
goal: V

full_name: SimpleGraph.Walk.adj_sndOfNotNil
code: @[simp] lemma adj_sndOfNotNil {p : G.Walk v w} (hp : ¬ p.Nil) :
    G.Adj v (p.sndOfNotNil hp) 
goal: G.Adj v (p.sndOfNotNil hp)

full_name: SimpleGraph.Walk.tail
code: /-- The walk obtained by removing the first dart of a non-nil walk. -/
def tail (p : G.Walk u v) (hp : ¬ p.Nil) : G.Walk (p.sndOfNotNil hp) v 
goal: G.Walk (p.sndOfNotNil hp) v

full_name: SimpleGraph.Walk.firstDart_toProd
code: /-- The first dart of a walk. -/
@[simps]
def firstDart (p : G.Walk v w) (hp : ¬ p.Nil) : G.Dart 
goal: (p.firstDart hp).toProd = (v, p.sndOfNotNil hp)

full_name: SimpleGraph.Walk.firstDart
code: /-- The first dart of a walk. -/
@[simps]
def firstDart (p : G.Walk v w) (hp : ¬ p.Nil) : G.Dart 
goal: G.Dart

full_name: SimpleGraph.Walk.edge_firstDart
code: lemma edge_firstDart (p : G.Walk v w) (hp : ¬ p.Nil) :
    (p.firstDart hp).edge = s(v, p.sndOfNotNil hp) 
goal: (p.firstDart hp).edge = s(v, p.sndOfNotNil hp)

full_name: SimpleGraph.Walk.cons_tail_eq
code: @[simp] lemma cons_tail_eq (p : G.Walk x y) (hp : ¬ p.Nil) :
    cons (p.adj_sndOfNotNil hp) (p.tail hp) = p 
goal: SimpleGraph.Walk.cons ⋯ (p.tail hp) = p

full_name: SimpleGraph.Walk.cons_support_tail
code: @[simp] lemma cons_support_tail (p : G.Walk x y) (hp : ¬p.Nil) :
    x :: (p.tail hp).support = p.support 
goal: x :: (p.tail hp).support = p.support

full_name: SimpleGraph.Walk.length_tail_add_one
code: @[simp] lemma length_tail_add_one {p : G.Walk x y} (hp : ¬ p.Nil) :
    (p.tail hp).length + 1 = p.length 
goal: (p.tail hp).length + 1 = p.length

full_name: SimpleGraph.Walk.nil_copy
code: @[simp] lemma nil_copy {x' y' : V} {p : G.Walk x y} (hx : x = x') (hy : y = y') :
    (p.copy hx hy).Nil = p.Nil 
goal: (p.copy hx hy).Nil = p.Nil

full_name: SimpleGraph.Walk.support_tail
code: @[simp] lemma support_tail (p : G.Walk v v) (hp) :
    (p.tail hp).support = p.support.tail 
goal: (p.tail hp).support = p.support.tail

full_name: SimpleGraph.Walk.tail_cons
code: @[simp]
lemma tail_cons {t u v} (p : G.Walk u v) (h : G.Adj t u) :
    (p.cons h).tail not_nil_cons = p 
goal: (SimpleGraph.Walk.cons h p).tail ⋯ = p

full_name: SimpleGraph.Walk.tail_support_eq_support_tail
code: lemma tail_support_eq_support_tail (p : G.Walk u v) (hnp : ¬p.Nil) :
    (p.tail hnp).support = p.support.tail 
goal: (p.tail hnp).support = p.support.tail

full_name: SimpleGraph.Walk.takeUntil
code: /-- Given a vertex in the support of a path, give the path up until (and including) that vertex. -/
def takeUntil {v w : V} : ∀ (p : G.Walk v w) (u : V), u ∈ p.support → G.Walk v u
  
goal: u ∈ p.support → G.Walk v u

full_name: SimpleGraph.Walk.dropUntil
code: /-- Given a vertex in the support of a path, give the path from (and including) that vertex to
the end. In other words, drop vertices from the front of a path until (and not including)
that vertex. -/
def dropUntil {v w : V} : ∀ (p : G.Walk v w) (u : V), u ∈ p.support → G.Walk u w
  
goal: u ∈ p.support → G.Walk u w

full_name: SimpleGraph.Walk.take_spec
code: /-- The `takeUntil` and `dropUntil` functions split a walk into two pieces.
The lemma `SimpleGraph.Walk.count_support_takeUntil_eq_one` specifies where this split occurs. -/
@[simp]
theorem take_spec {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).append (p.dropUntil u h) = p 
goal: (p.takeUntil u h).append (p.dropUntil u h) = p

full_name: SimpleGraph.Walk.mem_support_iff_exists_append
code: theorem mem_support_iff_exists_append {V : Type u} {G : SimpleGraph V} {u v w : V}
    {p : G.Walk u v} : w ∈ p.support ↔ ∃ (q : G.Walk u w) (r : G.Walk w v), p = q.append r 
goal: w ∈ p.support ↔ ∃ q r, p = q.append r

full_name: SimpleGraph.Walk.count_support_takeUntil_eq_one
code: @[simp]
theorem count_support_takeUntil_eq_one {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).support.count u = 1 
goal: List.count u (p.takeUntil u h).support = 1

full_name: SimpleGraph.Walk.count_edges_takeUntil_le_one
code: theorem count_edges_takeUntil_le_one {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) (x : V) :
    (p.takeUntil u h).edges.count s(u, x) ≤ 1 
goal: List.count s(u, x) (p.takeUntil u h).edges ≤ 1

full_name: SimpleGraph.Walk.takeUntil_copy
code: @[simp]
theorem takeUntil_copy {u v w v' w'} (p : G.Walk v w) (hv : v = v') (hw : w = w')
    (h : u ∈ (p.copy hv hw).support) :
    (p.copy hv hw).takeUntil u h = (p.takeUntil u (by subst_vars; exact h)).copy hv rfl 
goal: (p.copy hv hw).takeUntil u h = (p.takeUntil u ⋯).copy hv ⋯

full_name: SimpleGraph.Walk.dropUntil_copy
code: @[simp]
theorem dropUntil_copy {u v w v' w'} (p : G.Walk v w) (hv : v = v') (hw : w = w')
    (h : u ∈ (p.copy hv hw).support) :
    (p.copy hv hw).dropUntil u h = (p.dropUntil u (by subst_vars; exact h)).copy rfl hw 
goal: (p.copy hv hw).dropUntil u h = (p.dropUntil u ⋯).copy ⋯ hw

full_name: SimpleGraph.Walk.support_takeUntil_subset
code: theorem support_takeUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).support ⊆ p.support 
goal: (p.takeUntil u h).support ⊆ p.support

full_name: SimpleGraph.Walk.support_dropUntil_subset
code: theorem support_dropUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.dropUntil u h).support ⊆ p.support 
goal: (p.dropUntil u h).support ⊆ p.support

full_name: SimpleGraph.Walk.darts_takeUntil_subset
code: theorem darts_takeUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).darts ⊆ p.darts 
goal: (p.takeUntil u h).darts ⊆ p.darts

full_name: SimpleGraph.Walk.darts_dropUntil_subset
code: theorem darts_dropUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.dropUntil u h).darts ⊆ p.darts 
goal: (p.dropUntil u h).darts ⊆ p.darts

full_name: SimpleGraph.Walk.edges_takeUntil_subset
code: theorem edges_takeUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).edges ⊆ p.edges 
goal: (p.takeUntil u h).edges ⊆ p.edges

full_name: SimpleGraph.Walk.edges_dropUntil_subset
code: theorem edges_dropUntil_subset {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.dropUntil u h).edges ⊆ p.edges 
goal: (p.dropUntil u h).edges ⊆ p.edges

full_name: SimpleGraph.Walk.length_takeUntil_le
code: theorem length_takeUntil_le {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.takeUntil u h).length ≤ p.length 
goal: (p.takeUntil u h).length ≤ p.length

full_name: SimpleGraph.Walk.length_dropUntil_le
code: theorem length_dropUntil_le {u v w : V} (p : G.Walk v w) (h : u ∈ p.support) :
    (p.dropUntil u h).length ≤ p.length 
goal: (p.dropUntil u h).length ≤ p.length

full_name: SimpleGraph.Walk.rotate
code: /-- Rotate a loop walk such that it is centered at the given vertex. -/
def rotate {u v : V} (c : G.Walk v v) (h : u ∈ c.support) : G.Walk u u 
goal: G.Walk u u

full_name: SimpleGraph.Walk.support_rotate
code: @[simp]
theorem support_rotate {u v : V} (c : G.Walk v v) (h : u ∈ c.support) :
    (c.rotate h).support.tail ~r c.support.tail 
goal: (c.rotate h).support.tail ~r c.support.tail

full_name: SimpleGraph.Walk.rotate_darts
code: theorem rotate_darts {u v : V} (c : G.Walk v v) (h : u ∈ c.support) :
    (c.rotate h).darts ~r c.darts 
goal: (c.rotate h).darts ~r c.darts

full_name: SimpleGraph.Walk.rotate_edges
code: theorem rotate_edges {u v : V} (c : G.Walk v v) (h : u ∈ c.support) :
    (c.rotate h).edges ~r c.edges 
goal: (c.rotate h).edges ~r c.edges

full_name: SimpleGraph.Walk.exists_boundary_dart
code: /-- Given a set `S` and a walk `w` from `u` to `v` such that `u ∈ S` but `v ∉ S`,
there exists a dart in the walk whose start is in `S` but whose end is not. -/
theorem exists_boundary_dart {u v : V} (p : G.Walk u v) (S : Set V) (uS : u ∈ S) (vS : v ∉ S) :
    ∃ d : G.Dart, d ∈ p.darts ∧ d.fst ∈ S ∧ d.snd ∉ S 
goal: ∃ d ∈ p.darts, d.toProd.1 ∈ S ∧ d.toProd.2 ∉ S

full_name: SimpleGraph.Walk.getVert_tail
code: lemma getVert_tail {u v n} (p : G.Walk u v) (hnp: ¬ p.Nil) :
    (p.tail hnp).getVert n = p.getVert (n + 1) 
goal: (p.tail hnp).getVert n = p.getVert (n + 1)

full_name: SimpleGraph.Walk.cons_sndOfNotNil
code: @[simp]
lemma cons_sndOfNotNil (q : G.Walk v w) (hadj : G.Adj u v) :
    (q.cons hadj).sndOfNotNil not_nil_cons = v 
goal: (SimpleGraph.Walk.cons hadj q).sndOfNotNil ⋯ = v

full_name: SimpleGraph.Walk.getVert_one
code: lemma getVert_one (p : G.Walk u v) (hnp : ¬ p.Nil) : p.getVert 1 = p.sndOfNotNil hnp 
goal: p.getVert 1 = p.sndOfNotNil hnp

full_name: SimpleGraph.Walk.mem_support_iff_exists_getVert
code: /-- Given a walk `w` and a node in the support, there exists a natural `n`, such that given node
is the `n`-th node (zero-indexed) in the walk. In addition, `n` is at most the length of the path.
Due to the definition of `getVert` it would otherwise be legal to return a larger `n` for the last
node. -/
theorem mem_support_iff_exists_getVert {u v w : V} {p : G.Walk v w} :
    u ∈ p.support ↔ ∃ n, p.getVert n = u ∧ n ≤ p.length 
goal: u ∈ p.support ↔ ∃ n, p.getVert n = u ∧ n ≤ p.length

full_name: SimpleGraph.Walk.map
code: /-- Given a graph homomorphism, map walks to walks. -/
protected def map (f : G →g G') {u v : V} : G.Walk u v → G'.Walk (f u) (f v)
  
goal: G.Walk u v → G'.Walk (f u) (f v)

full_name: SimpleGraph.Walk.map_nil
code: @[simp]
theorem map_nil : (nil : G.Walk u u).map f = nil 
goal: SimpleGraph.Walk.map f SimpleGraph.Walk.nil = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.map_cons
code: @[simp]
theorem map_cons {w : V} (h : G.Adj w u) : (cons h p).map f = cons (f.map_adj h) (p.map f) 
goal: SimpleGraph.Walk.map f (SimpleGraph.Walk.cons h p) = SimpleGraph.Walk.cons ⋯ (SimpleGraph.Walk.map f p)

full_name: SimpleGraph.Walk.map_copy
code: @[simp]
theorem map_copy (hu : u = u') (hv : v = v') :
    (p.copy hu hv).map f = (p.map f).copy (hu ▸ rfl) (hv ▸ rfl) 
goal: SimpleGraph.Walk.map f (p.copy hu hv) = (SimpleGraph.Walk.map f p).copy ⋯ ⋯

full_name: SimpleGraph.Walk.map_id
code: @[simp]
theorem map_id (p : G.Walk u v) : p.map Hom.id = p 
goal: ∀ (p : G.Walk u v), SimpleGraph.Walk.map SimpleGraph.Hom.id p = p

full_name: SimpleGraph.Walk.map_map
code: @[simp]
theorem map_map : (p.map f).map f' = p.map (f'.comp f) 
goal: SimpleGraph.Walk.map f' (SimpleGraph.Walk.map f p) = SimpleGraph.Walk.map (f'.comp f) p

full_name: SimpleGraph.Walk.map_eq_of_eq
code: /-- Unlike categories, for graphs vertex equality is an important notion, so needing to be able to
work with equality of graph homomorphisms is a necessary evil. -/
theorem map_eq_of_eq {f : G →g G'} (f' : G →g G') (h : f = f') :
    p.map f = (p.map f').copy (h ▸ rfl) (h ▸ rfl) 
goal: SimpleGraph.Walk.map f p = (SimpleGraph.Walk.map f' p).copy ⋯ ⋯

full_name: SimpleGraph.Walk.map_eq_nil_iff
code: @[simp]
theorem map_eq_nil_iff {p : G.Walk u u} : p.map f = nil ↔ p = nil 
goal: SimpleGraph.Walk.map f p = SimpleGraph.Walk.nil ↔ p = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.length_map
code: @[simp]
theorem length_map : (p.map f).length = p.length 
goal: (SimpleGraph.Walk.map f p).length = p.length

full_name: SimpleGraph.Walk.map_append
code: theorem map_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) :
    (p.append q).map f = (p.map f).append (q.map f) 
goal: SimpleGraph.Walk.map f (p.append q) = (SimpleGraph.Walk.map f p).append (SimpleGraph.Walk.map f q)

full_name: SimpleGraph.Walk.reverse_map
code: @[simp]
theorem reverse_map : (p.map f).reverse = p.reverse.map f 
goal: (SimpleGraph.Walk.map f p).reverse = SimpleGraph.Walk.map f p.reverse

full_name: SimpleGraph.Walk.support_map
code: @[simp]
theorem support_map : (p.map f).support = p.support.map f 
goal: (SimpleGraph.Walk.map f p).support = List.map (⇑f) p.support

full_name: SimpleGraph.Walk.darts_map
code: @[simp]
theorem darts_map : (p.map f).darts = p.darts.map f.mapDart 
goal: (SimpleGraph.Walk.map f p).darts = List.map f.mapDart p.darts

full_name: SimpleGraph.Walk.edges_map
code: @[simp]
theorem edges_map : (p.map f).edges = p.edges.map (Sym2.map f) 
goal: (SimpleGraph.Walk.map f p).edges = List.map (Sym2.map ⇑f) p.edges

full_name: SimpleGraph.Walk.map_injective_of_injective
code: theorem map_injective_of_injective {f : G →g G'} (hinj : Function.Injective f) (u v : V) :
    Function.Injective (Walk.map f : G.Walk u v → G'.Walk (f u) (f v)) 
goal: Function.Injective (SimpleGraph.Walk.map f)

full_name: SimpleGraph.Walk.mapLe
code: /-- The specialization of `SimpleGraph.Walk.map` for mapping walks to supergraphs. -/
abbrev mapLe {G G' : SimpleGraph V} (h : G ≤ G') {u v : V} (p : G.Walk u v) : G'.Walk u v 
goal: G'.Walk u v

full_name: SimpleGraph.Walk.transfer
code: /-- The walk `p` transferred to lie in `H`, given that `H` contains its edges. -/
@[simp]
protected def transfer {u v : V} (p : G.Walk u v)
    (H : SimpleGraph V) (h : ∀ e, e ∈ p.edges → e ∈ H.edgeSet) : H.Walk u v 
goal: H.Walk u v

full_name: SimpleGraph.Walk.transfer_self
code: theorem transfer_self : p.transfer G p.edges_subset_edgeSet = p 
goal: p.transfer G ⋯ = p

full_name: SimpleGraph.Walk.transfer_eq_map_of_le
code: theorem transfer_eq_map_of_le (hp) (GH : G ≤ H) :
    p.transfer H hp = p.map (SimpleGraph.Hom.mapSpanningSubgraphs GH) 
goal: p.transfer H hp = SimpleGraph.Walk.map (SimpleGraph.Hom.mapSpanningSubgraphs GH) p

full_name: SimpleGraph.Walk.edges_transfer
code: @[simp]
theorem edges_transfer (hp) : (p.transfer H hp).edges = p.edges 
goal: (p.transfer H hp).edges = p.edges

full_name: SimpleGraph.Walk.support_transfer
code: @[simp]
theorem support_transfer (hp) : (p.transfer H hp).support = p.support 
goal: (p.transfer H hp).support = p.support

full_name: SimpleGraph.Walk.length_transfer
code: @[simp]
theorem length_transfer (hp) : (p.transfer H hp).length = p.length 
goal: (p.transfer H hp).length = p.length

full_name: SimpleGraph.Walk.transfer_transfer
code: @[simp]
theorem transfer_transfer (hp) {K : SimpleGraph V} (hp') :
    (p.transfer H hp).transfer K hp' = p.transfer K (p.edges_transfer hp ▸ hp') 
goal: (p.transfer H hp).transfer K hp' = p.transfer K ⋯

full_name: SimpleGraph.Walk.transfer_append
code: @[simp]
theorem transfer_append {w : V} (q : G.Walk v w) (hpq) :
    (p.append q).transfer H hpq =
      (p.transfer H fun e he => hpq _ (by simp [he])).append
        (q.transfer H fun e he => hpq _ (by simp [he])) 
goal: (p.append q).transfer H hpq = (p.transfer H ⋯).append (q.transfer H ⋯)

full_name: SimpleGraph.Walk.reverse_transfer
code: @[simp]
theorem reverse_transfer (hp) :
    (p.transfer H hp).reverse =
      p.reverse.transfer H (by simp only [edges_reverse, List.mem_reverse]; exact hp) 
goal: (p.transfer H hp).reverse = p.reverse.transfer H ⋯

full_name: SimpleGraph.Walk.toDeleteEdges
code: /-- Given a walk that avoids a set of edges, produce a walk in the graph
with those edges deleted. -/
abbrev toDeleteEdges (s : Set (Sym2 V)) {v w : V} (p : G.Walk v w)
    (hp : ∀ e, e ∈ p.edges → ¬e ∈ s) : (G.deleteEdges s).Walk v w 
goal: (G.deleteEdges s).Walk v w

full_name: SimpleGraph.Walk.toDeleteEdges_nil
code: @[simp]
theorem toDeleteEdges_nil (s : Set (Sym2 V)) {v : V} (hp) :
    (Walk.nil : G.Walk v v).toDeleteEdges s hp = Walk.nil 
goal: SimpleGraph.Walk.toDeleteEdges s SimpleGraph.Walk.nil hp = SimpleGraph.Walk.nil

full_name: SimpleGraph.Walk.toDeleteEdges_cons
code: @[simp]
theorem toDeleteEdges_cons (s : Set (Sym2 V)) {u v w : V} (h : G.Adj u v) (p : G.Walk v w) (hp) :
    (Walk.cons h p).toDeleteEdges s hp =
      Walk.cons (deleteEdges_adj.mpr ⟨h, hp _ (List.Mem.head _)⟩)
        (p.toDeleteEdges s fun _ he => hp _ <| List.Mem.tail _ he) 
goal: SimpleGraph.Walk.toDeleteEdges s (SimpleGraph.Walk.cons h p) hp =
  SimpleGraph.Walk.cons ⋯ (SimpleGraph.Walk.toDeleteEdges s p ⋯)

full_name: SimpleGraph.Walk.toDeleteEdge
code: /-- Given a walk that avoids an edge, create a walk in the subgraph with that edge deleted.
This is an abbreviation for `SimpleGraph.Walk.toDeleteEdges`. -/
abbrev toDeleteEdge (e : Sym2 V) (p : G.Walk v w) (hp : e ∉ p.edges) :
    (G.deleteEdges {e}).Walk v w 
goal: (G.deleteEdges {e}).Walk v w

full_name: SimpleGraph.Walk.map_toDeleteEdges_eq
code: @[simp]
theorem map_toDeleteEdges_eq (s : Set (Sym2 V)) {p : G.Walk v w} (hp) :
    Walk.map (Hom.mapSpanningSubgraphs (G.deleteEdges_le s)) (p.toDeleteEdges s hp) = p 
goal: SimpleGraph.Walk.map (SimpleGraph.Hom.mapSpanningSubgraphs ⋯) (SimpleGraph.Walk.toDeleteEdges s p hp) = p