l3lab/ntp-mathlib huggingface dataset:
@[simp] lemma length_tail_add_one {p : G.Walk x y} (hp : ¬ p.Nil) :
    (p.tail hp).length + 1 = p.length := 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
⊢ length (tail p hp) + 1 = length p

Next tactic:
rw [← length_cons, cons_tail_eq]
@[simp] lemma nil_copy {p : G.Walk x y} (hx : x = x') (hy : y = y') :
    (p.copy hx hy).Nil = p.Nil := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
x y x' y' : V
p : Walk G x y
hx : x = x'
hy : y = y'
⊢ Nil (Walk.copy p hx hy) = Nil p

Next tactic:
subst_vars
@[simp] lemma nil_copy {p : G.Walk x y} (hx : x = x') (hy : y = y') :
    (p.copy hx hy).Nil = p.Nil := by
  subst_vars; 

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'
⊢ Nil (Walk.copy p (_ : x' = x') (_ : y' = y')) = Nil p

Next tactic:
rfl
@[simp]
theorem isTrail_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).IsTrail ↔ p.IsTrail := 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'
⊢ IsTrail (Walk.copy p hu hv) ↔ IsTrail p

Next tactic:
subst_vars
@[simp]
theorem isTrail_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).IsTrail ↔ p.IsTrail := 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'
⊢ IsTrail (Walk.copy p (_ : u' = u') (_ : v' = v')) ↔ IsTrail p

Next tactic:
rfl
@[simp]
theorem isPath_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).IsPath ↔ p.IsPath := 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'
⊢ IsPath (Walk.copy p hu hv) ↔ IsPath p

Next tactic:
subst_vars
@[simp]
theorem isPath_copy {u v u' v'} (p : G.Walk u v) (hu : u = u') (hv : v = v') :
    (p.copy hu hv).IsPath ↔ p.IsPath := 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'
⊢ IsPath (Walk.copy p (_ : u' = u') (_ : v' = v')) ↔ IsPath p

Next tactic:
rfl
@[simp]
theorem isCircuit_copy {u u'} (p : G.Walk u u) (hu : u = u') :
    (p.copy hu hu).IsCircuit ↔ p.IsCircuit := by
  

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

Next tactic:
subst_vars
@[simp]
theorem isCircuit_copy {u u'} (p : G.Walk u u) (hu : u = u') :
    (p.copy hu hu).IsCircuit ↔ p.IsCircuit := 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
p : Walk G u' u'
⊢ IsCircuit (Walk.copy p (_ : u' = u') (_ : u' = u')) ↔ IsCircuit p

Next tactic:
rfl
@[simp]
theorem isCycle_copy {u u'} (p : G.Walk u u) (hu : u = u') :
    (p.copy hu hu).IsCycle ↔ p.IsCycle := by
  

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

Next tactic:
subst_vars
@[simp]
theorem isCycle_copy {u u'} (p : G.Walk u u) (hu : u = u') :
    (p.copy hu hu).IsCycle ↔ p.IsCycle := 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
p : Walk G u' u'
⊢ IsCycle (Walk.copy p (_ : u' = u') (_ : u' = u')) ↔ IsCycle p

Next tactic:
rfl
@[simp]
theorem IsTrail.nil {u : V} : (nil : G.Walk u u).IsTrail :=
  ⟨by 

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

Next tactic:
simp [edges]
theorem IsTrail.of_cons {u v w : V} {h : G.Adj u v} {p : G.Walk v w} :
    (cons h p).IsTrail → p.IsTrail := 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
h : Adj G u v
p : Walk G v w
⊢ IsTrail (cons h p) → IsTrail p

Next tactic:
simp [isTrail_def]
@[simp]
theorem cons_isTrail_iff {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).IsTrail ↔ p.IsTrail ∧ ⟦(u, v)⟧ ∉ 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
h : Adj G u v
p : Walk G v w
⊢ IsTrail (cons h p) ↔ IsTrail p ∧ ⟦(u, v)⟧ ∉ edges p

Next tactic:
simp [isTrail_def, and_comm]
theorem IsTrail.reverse {u v : V} (p : G.Walk u v) (h : p.IsTrail) : p.reverse.IsTrail := 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 : IsTrail p
⊢ IsTrail (Walk.reverse p)

Next tactic:
simpa [isTrail_def] using h
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := 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
⊢ IsTrail (reverse p) ↔ IsTrail p

Next tactic:
constructor
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · 

Proof state:
case mp
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
⊢ IsTrail (reverse p) → IsTrail p

Next tactic:
intro h
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      

Proof state:
case mp
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 : IsTrail (reverse p)
⊢ IsTrail p

Next tactic:
convert h.reverse _
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      convert h.reverse _
      

Proof state:
case h.e'_5
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 : IsTrail (reverse p)
⊢ p = reverse (reverse p)

Next tactic:
try rw [reverse_reverse]
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      convert h.reverse _
      try 

Proof state:
case h.e'_5
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 : IsTrail (reverse p)
⊢ p = reverse (reverse p)

Next tactic:
rw [reverse_reverse]
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · 

Proof state:
case mpr
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
⊢ IsTrail p → IsTrail (reverse p)

Next tactic:
intro h
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      

Proof state:
case mpr
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 : IsTrail p
⊢ IsTrail (reverse p)

Next tactic:
convert h.reverse _
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      convert h.reverse _
      

Proof state:

Next tactic:
try rw [reverse_reverse]
@[simp]
theorem reverse_isTrail_iff {u v : V} (p : G.Walk u v) : p.reverse.IsTrail ↔ p.IsTrail := by
  constructor <;>
    · intro h
      convert h.reverse _
      try 

Proof state:

Next tactic:
rw [reverse_reverse]
theorem IsTrail.of_append_left {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsTrail) : p.IsTrail := 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
q : Walk G v w
h : IsTrail (append p q)
⊢ IsTrail p

Next tactic:
rw [isTrail_def, edges_append, List.nodup_append] at h
theorem IsTrail.of_append_left {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsTrail) : p.IsTrail := by
  rw [isTrail_def, edges_append, List.nodup_append] at h
  

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
q : Walk G v w
h : List.Nodup (edges p) ∧ List.Nodup (edges q) ∧ List.Disjoint (edges p) (edges q)
⊢ IsTrail p

Next tactic:
exact ⟨h.1⟩
theorem IsTrail.of_append_right {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsTrail) : q.IsTrail := 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
q : Walk G v w
h : IsTrail (append p q)
⊢ IsTrail q

Next tactic:
rw [isTrail_def, edges_append, List.nodup_append] at h
theorem IsTrail.of_append_right {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsTrail) : q.IsTrail := by
  rw [isTrail_def, edges_append, List.nodup_append] at h
  

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
q : Walk G v w
h : List.Nodup (edges p) ∧ List.Nodup (edges q) ∧ List.Disjoint (edges p) (edges q)
⊢ IsTrail q

Next tactic:
exact ⟨h.2.1⟩
theorem IsPath.nil {u : V} : (nil : G.Walk u u).IsPath := by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u : V
⊢ IsPath Walk.nil

Next tactic:
constructor
theorem IsPath.nil {u : V} : (nil : G.Walk u u).IsPath := by constructor <;> 

Proof state:
case toIsTrail
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u : V
⊢ IsTrail Walk.nil

Next tactic:
simp
theorem IsPath.nil {u : V} : (nil : G.Walk u u).IsPath := by constructor <;> 

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

Next tactic:
simp
theorem IsPath.of_cons {u v w : V} {h : G.Adj u v} {p : G.Walk v w} :
    (cons h p).IsPath → p.IsPath := 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
h : Adj G u v
p : Walk G v w
⊢ IsPath (cons h p) → IsPath p

Next tactic:
simp [isPath_def]
@[simp]
theorem cons_isPath_iff {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).IsPath ↔ p.IsPath ∧ u ∉ 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 w : V
h : Adj G u v
p : Walk G v w
⊢ IsPath (cons h p) ↔ IsPath p ∧ u ∉ support p

Next tactic:
constructor
@[simp]
theorem cons_isPath_iff {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).IsPath ↔ p.IsPath ∧ u ∉ p.support := by
  constructor <;> 

Proof state:
case mp
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
h : Adj G u v
p : Walk G v w
⊢ IsPath (cons h p) → IsPath p ∧ u ∉ support p

Next tactic:
simp (config := { contextual := true }) [isPath_def]
@[simp]
theorem cons_isPath_iff {u v w : V} (h : G.Adj u v) (p : G.Walk v w) :
    (cons h p).IsPath ↔ p.IsPath ∧ u ∉ p.support := by
  constructor <;> 

Proof state:
case mpr
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
h : Adj G u v
p : Walk G v w
⊢ IsPath p ∧ u ∉ support p → IsPath (cons h p)

Next tactic:
simp (config := { contextual := true }) [isPath_def]
@[simp]
theorem isPath_iff_eq_nil {u : V} (p : G.Walk u u) : p.IsPath ↔ p = nil := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u : V
p : Walk G u u
⊢ IsPath p ↔ p = nil

Next tactic:
cases p
@[simp]
theorem isPath_iff_eq_nil {u : V} (p : G.Walk u u) : p.IsPath ↔ p = nil := 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''
u : V
⊢ IsPath nil ↔ nil = nil

Next tactic:
simp [IsPath.nil]
@[simp]
theorem isPath_iff_eq_nil {u : V} (p : G.Walk u u) : p.IsPath ↔ p = nil := 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''
u v✝ : V
h✝ : Adj G u v✝
p✝ : Walk G v✝ u
⊢ IsPath (cons h✝ p✝) ↔ cons h✝ p✝ = nil

Next tactic:
simp [IsPath.nil]
theorem IsPath.reverse {u v : V} {p : G.Walk u v} (h : p.IsPath) : p.reverse.IsPath := 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 : IsPath p
⊢ IsPath (Walk.reverse p)

Next tactic:
simpa [isPath_def] using h
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := 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
⊢ IsPath (reverse p) ↔ IsPath p

Next tactic:
constructor
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := by
  constructor <;> 

Proof state:
case mp
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
⊢ IsPath (reverse p) → IsPath p

Next tactic:
intro h
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := by
  constructor <;> 

Proof state:
case mpr
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
⊢ IsPath p → IsPath (reverse p)

Next tactic:
intro h
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := by
  constructor <;> intro h <;> 

Proof state:
case mp
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 : IsPath (reverse p)
⊢ IsPath p

Next tactic:
convert h.reverse
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := by
  constructor <;> intro h <;> 

Proof state:
case mpr
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 : IsPath p
⊢ IsPath (reverse p)

Next tactic:
convert h.reverse
@[simp]
theorem isPath_reverse_iff {u v : V} (p : G.Walk u v) : p.reverse.IsPath ↔ p.IsPath := by
  constructor <;> intro h <;> convert h.reverse; 

Proof state:
case h.e'_5
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 : IsPath (reverse p)
⊢ p = reverse (reverse p)

Next tactic:
simp
theorem IsPath.of_append_left {u v w : V} {p : G.Walk u v} {q : G.Walk v w} :
    (p.append q).IsPath → p.IsPath := 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
q : Walk G v w
⊢ IsPath (append p q) → IsPath p

Next tactic:
simp only [isPath_def, support_append]
theorem IsPath.of_append_left {u v w : V} {p : G.Walk u v} {q : G.Walk v w} :
    (p.append q).IsPath → p.IsPath := by
  simp only [isPath_def, support_append]
  

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
q : Walk G v w
⊢ List.Nodup (support p ++ List.tail (support q)) → List.Nodup (support p)

Next tactic:
exact List.Nodup.of_append_left
theorem IsPath.of_append_right {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsPath) : q.IsPath := 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
q : Walk G v w
h : IsPath (append p q)
⊢ IsPath q

Next tactic:
rw [← isPath_reverse_iff] at h ⊢
theorem IsPath.of_append_right {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsPath) : q.IsPath := by
  rw [← isPath_reverse_iff] at h ⊢
  

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
q : Walk G v w
h : IsPath (Walk.reverse (append p q))
⊢ IsPath (Walk.reverse q)

Next tactic:
rw [reverse_append] at h
theorem IsPath.of_append_right {u v w : V} {p : G.Walk u v} {q : G.Walk v w}
    (h : (p.append q).IsPath) : q.IsPath := by
  rw [← isPath_reverse_iff] at h ⊢
  rw [reverse_append] at h
  

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
q : Walk G v w
h : IsPath (append (Walk.reverse q) (Walk.reverse p))
⊢ IsPath (Walk.reverse q)

Next tactic:
apply h.of_append_left
lemma IsCycle.ne_bot : ∀ {p : G.Walk u u}, p.IsCycle → G ≠ ⊥
  | nil, hp => by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u : V
hp : IsCycle nil
⊢ G ≠ ⊥

Next tactic:
cases hp.ne_nil rfl
lemma IsCycle.ne_bot : ∀ {p : G.Walk u u}, p.IsCycle → G ≠ ⊥
  | nil, hp => by cases hp.ne_nil rfl
  | cons h _, hp => by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v✝ : V
h : Adj G u v✝
p✝ : Walk G v✝ u
hp : IsCycle (cons h p✝)
⊢ G ≠ ⊥

Next tactic:
rintro rfl
lemma IsCycle.ne_bot : ∀ {p : G.Walk u u}, p.IsCycle → G ≠ ⊥
  | nil, hp => by cases hp.ne_nil rfl
  | cons h _, hp => by rintro rfl; 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v✝ : V
h : Adj ⊥ u v✝
p✝ : Walk ⊥ v✝ u
hp : IsCycle (cons h p✝)
⊢ False

Next tactic:
exact h
theorem cons_isCycle_iff {u v : V} (p : G.Walk v u) (h : G.Adj u v) :
    (Walk.cons h p).IsCycle ↔ p.IsPath ∧ ¬⟦(u, v)⟧ ∈ 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 : V
p : Walk G v u
h : Adj G u v
⊢ IsCycle (cons h p) ↔ IsPath p ∧ ⟦(u, v)⟧ ∉ edges p

Next tactic:
simp only [Walk.isCycle_def, Walk.isPath_def, Walk.isTrail_def, edges_cons, List.nodup_cons,
    support_cons, List.tail_cons]
theorem cons_isCycle_iff {u v : V} (p : G.Walk v u) (h : G.Adj u v) :
    (Walk.cons h p).IsCycle ↔ p.IsPath ∧ ¬⟦(u, v)⟧ ∈ p.edges := by
  simp only [Walk.isCycle_def, Walk.isPath_def, Walk.isTrail_def, edges_cons, List.nodup_cons,
    support_cons, List.tail_cons]
  

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 v u
h : Adj G u v
⊢ (⟦(u, v)⟧ ∉ edges p ∧ List.Nodup (edges p)) ∧ cons h p ≠ nil ∧ List.Nodup (support p) ↔
    List.Nodup (support p) ∧ ⟦(u, v)⟧ ∉ edges p

Next tactic:
have : p.support.Nodup → p.edges.Nodup := edges_nodup_of_support_nodup
theorem cons_isCycle_iff {u v : V} (p : G.Walk v u) (h : G.Adj u v) :
    (Walk.cons h p).IsCycle ↔ p.IsPath ∧ ¬⟦(u, v)⟧ ∈ p.edges := by
  simp only [Walk.isCycle_def, Walk.isPath_def, Walk.isTrail_def, edges_cons, List.nodup_cons,
    support_cons, List.tail_cons]
  have : p.support.Nodup → p.edges.Nodup := edges_nodup_of_support_nodup
  

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 v u
h : Adj G u v
this : List.Nodup (support p) → List.Nodup (edges p)
⊢ (⟦(u, v)⟧ ∉ edges p ∧ List.Nodup (edges p)) ∧ cons h p ≠ nil ∧ List.Nodup (support p) ↔
    List.Nodup (support p) ∧ ⟦(u, v)⟧ ∉ edges p

Next tactic:
tauto
lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) (hp' : ¬ p.Nil) : (p.tail hp').IsPath := 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
hp : IsPath p
hp' : ¬Nil p
⊢ IsPath (Walk.tail p hp')

Next tactic:
rw [Walk.isPath_def] at hp ⊢
lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) (hp' : ¬ p.Nil) : (p.tail hp').IsPath := by
  rw [Walk.isPath_def] at hp ⊢
  

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
hp : List.Nodup (support p)
hp' : ¬Nil p
⊢ List.Nodup (support (Walk.tail p hp'))

Next tactic:
rw [← cons_support_tail _ hp', List.nodup_cons] at hp
lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) (hp' : ¬ p.Nil) : (p.tail hp').IsPath := by
  rw [Walk.isPath_def] at hp ⊢
  rw [← cons_support_tail _ hp', List.nodup_cons] at hp
  

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
hp' : ¬Nil p
hp : u ∉ support (Walk.tail p hp') ∧ List.Nodup (support (Walk.tail p hp'))
⊢ List.Nodup (support (Walk.tail p hp'))

Next tactic:
exact hp.2
instance [DecidableEq V] {u v : V} (p : G.Walk u v) : Decidable p.IsPath := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : DecidableEq V
u v : V
p : Walk G u v
⊢ Decidable (IsPath p)

Next tactic:
rw [isPath_def]
instance [DecidableEq V] {u v : V} (p : G.Walk u v) : Decidable p.IsPath := by
  rw [isPath_def]
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : DecidableEq V
u v : V
p : Walk G u v
⊢ Decidable (List.Nodup (support p))

Next tactic:
infer_instance
theorem IsPath.length_lt [Fintype V] {u v : V} {p : G.Walk u v} (hp : p.IsPath) :
    p.length < Fintype.card V := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : Fintype V
u v : V
p : Walk G u v
hp : IsPath p
⊢ length p < Fintype.card V

Next tactic:
rw [Nat.lt_iff_add_one_le, ← length_support]
theorem IsPath.length_lt [Fintype V] {u v : V} {p : G.Walk u v} (hp : p.IsPath) :
    p.length < Fintype.card V := by
  rw [Nat.lt_iff_add_one_le, ← length_support]
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : Fintype V
u v : V
p : Walk G u v
hp : IsPath p
⊢ List.length (support p) ≤ Fintype.card V

Next tactic:
exact hp.support_nodup.length_le_card
/-- 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
  | nil, u, h => by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : DecidableEq V
v w u : V
h : u ∈ support nil
⊢ Walk G v u

Next tactic:
rw [mem_support_nil_iff.mp h]
/-- 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
  | nil, u, h => by rw [mem_support_nil_iff.mp h]
  | cons r p, u, h =>
    if hx : v = u then
      by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : DecidableEq V
v w✝ w v✝ : V
r : Adj G v v✝
p : Walk G v✝ w
u : V
h : u ∈ support (cons r p)
hx : v = u
⊢ Walk G v u

Next tactic:
subst u
/-- 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
  | nil, u, h => by rw [mem_support_nil_iff.mp h]
  | cons r p, u, h =>
    if hx : v = u then
      by subst u; 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝ : DecidableEq V
v w✝ w v✝ : V
r : Adj G v v✝
p : Walk G v✝ w
h : v ∈ support (cons r p)
⊢ Walk G v v

Next tactic:
exact Walk.nil