l3lab/ntp-mathlib huggingface dataset:
@[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 := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : ∀ (p' : Walk G w✝ w), darts (append p✝ p') = darts p✝ ++ darts p'
p' : Walk G w✝ w
⊢ darts (append (cons h✝ p✝) p') = darts (cons h✝ p✝) ++ darts p'

Next tactic:
simp [*]
@[simp]
theorem darts_reverse {u v : V} (p : G.Walk u v) :
    p.reverse.darts = (p.darts.map Dart.symm).reverse := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ darts (reverse p) = List.reverse (List.map Dart.symm (darts p))

Next tactic:
induction p
@[simp]
theorem darts_reverse {u v : V} (p : G.Walk u v) :
    p.reverse.darts = (p.darts.map Dart.symm).reverse := by
  induction p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
⊢ darts (reverse nil) = List.reverse (List.map Dart.symm (darts nil))

Next tactic:
simp [*, Sym2.eq_swap]
@[simp]
theorem darts_reverse {u v : V} (p : G.Walk u v) :
    p.reverse.darts = (p.darts.map Dart.symm).reverse := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : darts (reverse p✝) = List.reverse (List.map Dart.symm (darts p✝))
⊢ darts (reverse (cons h✝ p✝)) = List.reverse (List.map Dart.symm (darts (cons h✝ p✝)))

Next tactic:
simp [*, Sym2.eq_swap]
theorem mem_darts_reverse {u v : V} {d : G.Dart} {p : G.Walk u v} :
    d ∈ p.reverse.darts ↔ d.symm ∈ p.darts := by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
d : Dart G
p : Walk G u v
⊢ d ∈ darts (reverse p) ↔ Dart.symm d ∈ darts p

Next tactic:
simp
theorem cons_map_snd_darts {u v : V} (p : G.Walk u v) : (u :: p.darts.map (·.snd)) = p.support := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ u :: List.map (fun x => x.toProd.2) (darts p) = support p

Next tactic:
induction p
theorem cons_map_snd_darts {u v : V} (p : G.Walk u v) : (u :: p.darts.map (·.snd)) = p.support := by
  induction p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
⊢ u✝ :: List.map (fun x => x.toProd.2) (darts nil) = support nil

Next tactic:
simp! [*]
theorem cons_map_snd_darts {u v : V} (p : G.Walk u v) : (u :: p.darts.map (·.snd)) = p.support := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : v✝ :: List.map (fun x => x.toProd.2) (darts p✝) = support p✝
⊢ u✝ :: List.map (fun x => x.toProd.2) (darts (cons h✝ p✝)) = support (cons h✝ p✝)

Next tactic:
simp! [*]
theorem map_snd_darts {u v : V} (p : G.Walk u v) : p.darts.map (·.snd) = p.support.tail := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.map (fun x => x.toProd.2) (darts p) = List.tail (support p)

Next tactic:
simpa using congr_arg List.tail (cons_map_snd_darts p)
theorem map_fst_darts_append {u v : V} (p : G.Walk u v) :
    p.darts.map (·.fst) ++ [v] = p.support := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.map (fun x => x.toProd.1) (darts p) ++ [v] = support p

Next tactic:
induction p
theorem map_fst_darts_append {u v : V} (p : G.Walk u v) :
    p.darts.map (·.fst) ++ [v] = p.support := by
  induction p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
⊢ List.map (fun x => x.toProd.1) (darts nil) ++ [u✝] = support nil

Next tactic:
simp! [*]
theorem map_fst_darts_append {u v : V} (p : G.Walk u v) :
    p.darts.map (·.fst) ++ [v] = p.support := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : List.map (fun x => x.toProd.1) (darts p✝) ++ [w✝] = support p✝
⊢ List.map (fun x => x.toProd.1) (darts (cons h✝ p✝)) ++ [w✝] = support (cons h✝ p✝)

Next tactic:
simp! [*]
theorem map_fst_darts {u v : V} (p : G.Walk u v) : p.darts.map (·.fst) = p.support.dropLast := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.map (fun x => x.toProd.1) (darts p) = List.dropLast (support p)

Next tactic:
simpa! using congr_arg List.dropLast (map_fst_darts_append p)
@[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 ⟦(v, w)⟧ := by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
p : Walk G u v
h : Adj G v w
⊢ edges (concat p h) = List.concat (edges p) ⟦(v, w)⟧

Next tactic:
simp [edges]
@[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 := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u' v' : V
p : Walk G u v
hu : u = u'
hv : v = v'
⊢ edges (Walk.copy p hu hv) = edges p

Next tactic:
subst_vars
@[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 := by
  subst_vars
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u' v' : V
p : Walk G u' v'
⊢ edges (Walk.copy p (_ : u' = u') (_ : v' = v')) = edges p

Next tactic:
rfl
@[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 := by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
p : Walk G u v
p' : Walk G v w
⊢ edges (append p p') = edges p ++ edges p'

Next tactic:
simp [edges]
@[simp]
theorem edges_reverse {u v : V} (p : G.Walk u v) : p.reverse.edges = p.edges.reverse := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ edges (reverse p) = List.reverse (edges p)

Next tactic:
simp [edges, List.map_reverse]
@[simp]
theorem length_support {u v : V} (p : G.Walk u v) : p.support.length = p.length + 1 := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.length (support p) = length p + 1

Next tactic:
induction p
@[simp]
theorem length_support {u v : V} (p : G.Walk u v) : p.support.length = p.length + 1 := by
  induction p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
⊢ List.length (support nil) = length nil + 1

Next tactic:
simp [*]
@[simp]
theorem length_support {u v : V} (p : G.Walk u v) : p.support.length = p.length + 1 := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : List.length (support p✝) = length p✝ + 1
⊢ List.length (support (cons h✝ p✝)) = length (cons h✝ p✝) + 1

Next tactic:
simp [*]
@[simp]
theorem length_darts {u v : V} (p : G.Walk u v) : p.darts.length = p.length := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.length (darts p) = length p

Next tactic:
induction p
@[simp]
theorem length_darts {u v : V} (p : G.Walk u v) : p.darts.length = p.length := by
  induction p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
⊢ List.length (darts nil) = length nil

Next tactic:
simp [*]
@[simp]
theorem length_darts {u v : V} (p : G.Walk u v) : p.darts.length = p.length := by
  induction p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p✝ : Walk G v✝ w✝
p_ih✝ : List.length (darts p✝) = length p✝
⊢ List.length (darts (cons h✝ p✝)) = length (cons h✝ p✝)

Next tactic:
simp [*]
@[simp]
theorem length_edges {u v : V} (p : G.Walk u v) : p.edges.length = p.length := by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
⊢ List.length (edges p) = length p

Next tactic:
simp [edges]
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
  | cons h p', d, hd => by
    

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v v✝ : V
h : Adj G u v✝
p' : Walk G v✝ v
d : Dart G
hd : d ∈ darts (cons h p')
⊢ d.toProd.1 ∈ support (cons h p')

Next tactic:
simp only [support_cons, darts_cons, List.mem_cons] at hd ⊢
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
  | cons h p', d, hd => by
    simp only [support_cons, darts_cons, List.mem_cons] at hd ⊢
    

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v v✝ : V
h : Adj G u v✝
p' : Walk G v✝ v
d : Dart G
hd : d = { toProd := (u, v✝), is_adj := h } ∨ d ∈ darts p'
⊢ d.toProd.1 = u ∨ d.toProd.1 ∈ support p'

Next tactic:
rcases hd with (rfl | hd)
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
  | cons h p', d, hd => by
    simp only [support_cons, darts_cons, List.mem_cons] at hd ⊢
    rcases hd with (rfl | hd)
    · 

Proof state:
case inl
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v v✝ : V
h : Adj G u v✝
p' : Walk G v✝ v
⊢ { toProd := (u, v✝), is_adj := h }.toProd.1 = u ∨ { toProd := (u, v✝), is_adj := h }.toProd.1 ∈ support p'

Next tactic:
exact Or.inl rfl
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
  | cons h p', d, hd => by
    simp only [support_cons, darts_cons, List.mem_cons] at hd ⊢
    rcases hd with (rfl | hd)
    · exact Or.inl rfl
    · 

Proof state:
case inr
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v v✝ : V
h : Adj G u v✝
p' : Walk G v✝ v
d : Dart G
hd : d ∈ darts p'
⊢ d.toProd.1 = u ∨ d.toProd.1 ∈ support p'

Next tactic:
exact Or.inr (dart_fst_mem_support_of_mem_darts _ hd)
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 := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
d : Dart G
h : d ∈ darts p
⊢ d.toProd.2 ∈ support p

Next tactic:
simpa using p.reverse.dart_fst_mem_support_of_mem_darts (by simp [h] : d.symm ∈ p.reverse.darts)
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 := by
  simpa using p.reverse.dart_fst_mem_support_of_mem_darts (by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
d : Dart G
h : d ∈ darts p
⊢ Dart.symm d ∈ darts (reverse p)

Next tactic:
simp [h]
theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    t ∈ p.support := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
t u v w : V
p : Walk G v w
he : ⟦(t, u)⟧ ∈ edges p
⊢ t ∈ support p

Next tactic:
obtain ⟨d, hd, he⟩ := List.mem_map.mp he
theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    t ∈ p.support := by
  obtain ⟨d, hd, he⟩ := List.mem_map.mp he
  

Proof state:
case intro.intro
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
t u v w : V
p : Walk G v w
he✝ : ⟦(t, u)⟧ ∈ edges p
d : Dart G
hd : d ∈ darts p
he : Dart.edge d = ⟦(t, u)⟧
⊢ t ∈ support p

Next tactic:
rw [dart_edge_eq_mk'_iff'] at he
theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    t ∈ p.support := by
  obtain ⟨d, hd, he⟩ := List.mem_map.mp he
  rw [dart_edge_eq_mk'_iff'] at he
  

Proof state:
case intro.intro
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
t u v w : V
p : Walk G v w
he✝ : ⟦(t, u)⟧ ∈ edges p
d : Dart G
hd : d ∈ darts p
he : d.toProd.1 = t ∧ d.toProd.2 = u ∨ d.toProd.1 = u ∧ d.toProd.2 = t
⊢ t ∈ support p

Next tactic:
rcases he with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    t ∈ p.support := by
  obtain ⟨d, hd, he⟩ := List.mem_map.mp he
  rw [dart_edge_eq_mk'_iff'] at he
  rcases he with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
  · 

Proof state:
case intro.intro.inl.intro
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w : V
p : Walk G v w
d : Dart G
hd : d ∈ darts p
he : ⟦(d.toProd.1, d.toProd.2)⟧ ∈ edges p
⊢ d.toProd.1 ∈ support p

Next tactic:
exact dart_fst_mem_support_of_mem_darts _ hd
theorem fst_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    t ∈ p.support := by
  obtain ⟨d, hd, he⟩ := List.mem_map.mp he
  rw [dart_edge_eq_mk'_iff'] at he
  rcases he with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
  · exact dart_fst_mem_support_of_mem_darts _ hd
  · 

Proof state:
case intro.intro.inr.intro
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w : V
p : Walk G v w
d : Dart G
hd : d ∈ darts p
he : ⟦(d.toProd.2, d.toProd.1)⟧ ∈ edges p
⊢ d.toProd.2 ∈ support p

Next tactic:
exact dart_snd_mem_support_of_mem_darts _ hd
theorem snd_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    u ∈ p.support := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
t u v w : V
p : Walk G v w
he : ⟦(t, u)⟧ ∈ edges p
⊢ u ∈ support p

Next tactic:
rw [Sym2.eq_swap] at he
theorem snd_mem_support_of_mem_edges {t u v w : V} (p : G.Walk v w) (he : ⟦(t, u)⟧ ∈ p.edges) :
    u ∈ p.support := by
  rw [Sym2.eq_swap] at he
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
t u v w : V
p : Walk G v w
he : ⟦(u, t)⟧ ∈ edges p
⊢ u ∈ support p

Next tactic:
exact p.fst_mem_support_of_mem_edges he
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
h : List.Nodup (support p)
⊢ List.Nodup (darts p)

Next tactic:
induction p with
  | nil => simp
  | cons _ p' ih =>
    simp only [darts_cons, support_cons, List.nodup_cons] at h ⊢
    exact ⟨fun h' => h.1 (dart_fst_mem_support_of_mem_darts p' h'), ih h.2⟩
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  induction p with
  

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
h : List.Nodup (support nil)
⊢ List.Nodup (darts nil)

Next tactic:
| nil => simp
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  induction p with
  | nil => 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
h : List.Nodup (support nil)
⊢ List.Nodup (darts nil)

Next tactic:
simp
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  induction p with
  | nil => simp
  

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (darts p')
h : List.Nodup (support (cons h✝ p'))
⊢ List.Nodup (darts (cons h✝ p'))

Next tactic:
| cons _ p' ih =>
    simp only [darts_cons, support_cons, List.nodup_cons] at h ⊢
    exact ⟨fun h' => h.1 (dart_fst_mem_support_of_mem_darts p' h'), ih h.2⟩
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  induction p with
  | nil => simp
  | cons _ p' ih =>
    

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (darts p')
h : List.Nodup (support (cons h✝ p'))
⊢ List.Nodup (darts (cons h✝ p'))

Next tactic:
simp only [darts_cons, support_cons, List.nodup_cons] at h ⊢
theorem darts_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.darts.Nodup := by
  induction p with
  | nil => simp
  | cons _ p' ih =>
    simp only [darts_cons, support_cons, List.nodup_cons] at h ⊢
    

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (darts p')
h : u✝ ∉ support p' ∧ List.Nodup (support p')
⊢ { toProd := (u✝, v✝), is_adj := h✝ } ∉ darts p' ∧ List.Nodup (darts p')

Next tactic:
exact ⟨fun h' => h.1 (dart_fst_mem_support_of_mem_darts p' h'), ih h.2⟩
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
p : Walk G u v
h : List.Nodup (support p)
⊢ List.Nodup (edges p)

Next tactic:
induction p with
  | nil => simp
  | cons _ p' ih =>
    simp only [edges_cons, support_cons, List.nodup_cons] at h ⊢
    exact ⟨fun h' => h.1 (fst_mem_support_of_mem_edges p' h'), ih h.2⟩
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  induction p with
  

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
h : List.Nodup (support nil)
⊢ List.Nodup (edges nil)

Next tactic:
| nil => simp
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  induction p with
  | nil => 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ : V
h : List.Nodup (support nil)
⊢ List.Nodup (edges nil)

Next tactic:
simp
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  induction p with
  | nil => simp
  

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (edges p')
h : List.Nodup (support (cons h✝ p'))
⊢ List.Nodup (edges (cons h✝ p'))

Next tactic:
| cons _ p' ih =>
    simp only [edges_cons, support_cons, List.nodup_cons] at h ⊢
    exact ⟨fun h' => h.1 (fst_mem_support_of_mem_edges p' h'), ih h.2⟩
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  induction p with
  | nil => simp
  | cons _ p' ih =>
    

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (edges p')
h : List.Nodup (support (cons h✝ p'))
⊢ List.Nodup (edges (cons h✝ p'))

Next tactic:
simp only [edges_cons, support_cons, List.nodup_cons] at h ⊢
theorem edges_nodup_of_support_nodup {u v : V} {p : G.Walk u v} (h : p.support.Nodup) :
    p.edges.Nodup := by
  induction p with
  | nil => simp
  | cons _ p' ih =>
    simp only [edges_cons, support_cons, List.nodup_cons] at h ⊢
    

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v u✝ v✝ w✝ : V
h✝ : Adj G u✝ v✝
p' : Walk G v✝ w✝
ih : List.Nodup (support p') → List.Nodup (edges p')
h : u✝ ∉ support p' ∧ List.Nodup (support p')
⊢ ⟦(u✝, v✝)⟧ ∉ edges p' ∧ List.Nodup (edges p')

Next tactic:
exact ⟨fun h' => h.1 (fst_mem_support_of_mem_edges p' h'), ih h.2⟩
lemma nil_iff_support_eq {p : G.Walk v w} : p.Nil ↔ p.support = [v] := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w : V
p : Walk G v w
⊢ Nil p ↔ support p = [v]

Next tactic:
cases p
lemma nil_iff_support_eq {p : G.Walk v w} : p.Nil ↔ p.support = [v] := by
  cases p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v : V
⊢ Nil nil ↔ support nil = [v]

Next tactic:
simp
lemma nil_iff_support_eq {p : G.Walk v w} : p.Nil ↔ p.support = [v] := by
  cases p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w v✝ : V
h✝ : Adj G v v✝
p✝ : Walk G v✝ w
⊢ Nil (cons h✝ p✝) ↔ support (cons h✝ p✝) = [v]

Next tactic:
simp
lemma nil_iff_length_eq {p : G.Walk v w} : p.Nil ↔ p.length = 0 := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w : V
p : Walk G v w
⊢ Nil p ↔ length p = 0

Next tactic:
cases p
lemma nil_iff_length_eq {p : G.Walk v w} : p.Nil ↔ p.length = 0 := by
  cases p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v : V
⊢ Nil nil ↔ length nil = 0

Next tactic:
simp
lemma nil_iff_length_eq {p : G.Walk v w} : p.Nil ↔ p.length = 0 := by
  cases p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w v✝ : V
h✝ : Adj G v v✝
p✝ : Walk G v✝ w
⊢ Nil (cons h✝ p✝) ↔ length (cons h✝ p✝) = 0

Next tactic:
simp
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 := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w : V
p : Walk G v w
⊢ ¬Nil p ↔ ∃ u, ∃ (h : Adj G v u), ∃ q, p = cons h q

Next tactic:
cases p
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 := by
  cases p <;> 

Proof state:
case nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v : V
⊢ ¬Nil nil ↔ ∃ u, ∃ (h : Adj G v u), ∃ q, nil = cons h q

Next tactic:
simp [*]
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 := by
  cases p <;> 

Proof state:
case cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
v w v✝ : V
h✝ : Adj G v v✝
p✝ : Walk G v✝ w
⊢ ¬Nil (cons h✝ p✝) ↔ ∃ u, ∃ (h : Adj G v u), ∃ q, cons h✝ p✝ = cons h q

Next tactic:
simp [*]
@[simp] lemma cons_support_tail (p : G.Walk x y) (hp : ¬ p.Nil) :
    x :: (p.tail hp).support = p.support := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
x y : V
p : Walk G x y
hp : ¬Nil p
⊢ x :: support (tail p hp) = support p

Next tactic:
rw [← support_cons, cons_tail_eq]