l3lab/ntp-mathlib huggingface dataset:
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
⊢ {p | Walk.length p = Nat.succ n} = ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
ext p
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  

Proof state:
case h
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
p : Walk G u v
⊢ p ∈ {p | Walk.length p = Nat.succ n} ↔ p ∈ ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
cases' p with _ _ w _ huw pwv
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · 

Proof state:
case h.nil
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u : V
n : ℕ
⊢ Walk.nil ∈ {p | Walk.length p = Nat.succ n} ↔
    Walk.nil ∈ ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
simp [eq_comm]
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · 

Proof state:
case h.cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
w : V
huw : Adj G u w
pwv : Walk G w v
⊢ Walk.cons huw pwv ∈ {p | Walk.length p = Nat.succ n} ↔
    Walk.cons huw pwv ∈ ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
    

Proof state:
case h.cons
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
w : V
huw : Adj G u w
pwv : Walk G w v
⊢ Walk.length pwv = n ↔ ∃ i, ∃ (h : Adj G u i), ∃ x, Walk.length x = n ∧ Walk.cons (_ : Adj G u i) x = Walk.cons huw pwv

Next tactic:
constructor
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
    constructor
    · 

Proof state:
case h.cons.mp
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
w : V
huw : Adj G u w
pwv : Walk G w v
⊢ Walk.length pwv = n → ∃ i, ∃ (h : Adj G u i), ∃ x, Walk.length x = n ∧ Walk.cons (_ : Adj G u i) x = Walk.cons huw pwv

Next tactic:
rintro rfl
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
    constructor
    · rintro rfl
      

Proof state:
case h.cons.mp
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
huw : Adj G u w
pwv : Walk G w v
⊢ ∃ i, ∃ (h : Adj G u i), ∃ x, Walk.length x = Walk.length pwv ∧ Walk.cons (_ : Adj G u i) x = Walk.cons huw pwv

Next tactic:
exact ⟨w, huw, pwv, rfl, rfl⟩
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
    constructor
    · rintro rfl
      exact ⟨w, huw, pwv, rfl, rfl⟩
    · 

Proof state:
case h.cons.mpr
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v : V
n : ℕ
w : V
huw : Adj G u w
pwv : Walk G w v
⊢ (∃ i, ∃ (h : Adj G u i), ∃ x, Walk.length x = n ∧ Walk.cons (_ : Adj G u i) x = Walk.cons huw pwv) →
    Walk.length pwv = n

Next tactic:
rintro ⟨w, huw, pwv, rfl, rfl, rfl⟩
theorem set_walk_length_succ_eq (u v : V) (n : ℕ) :
    {p : G.Walk u v | p.length = n.succ} =
      ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by
  ext p
  cases' p with _ _ w _ huw pwv
  · simp [eq_comm]
  · simp only [Nat.succ_eq_add_one, Set.mem_setOf_eq, Walk.length_cons, add_left_inj,
      Set.mem_iUnion, Set.mem_image, exists_prop]
    constructor
    · rintro rfl
      exact ⟨w, huw, pwv, rfl, rfl⟩
    · rintro ⟨w, huw, pwv, rfl, rfl, rfl⟩
      

Proof state:
case h.cons.mpr.intro.intro.intro.intro.refl
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
u v w : V
huw✝ : Adj G u w
pwv : Walk G w v
huw : Adj G u w
⊢ Walk.length pwv = Walk.length pwv

Next tactic:
rfl
/-- Walks of length two from `u` to `v` correspond bijectively to common neighbours of `u` and `v`.
Note that `u` and `v` may be the same. -/
@[simps]
def walkLengthTwoEquivCommonNeighbors (u v : V) :
    {p : G.Walk u v // p.length = 2} ≃ G.commonNeighbors u v where
  toFun p := ⟨p.val.getVert 1, match p with
    | ⟨.cons _ (.cons _ .nil), hp⟩ => ⟨‹G.Adj u _›, ‹G.Adj _ v›.symm⟩⟩
  invFun w := ⟨w.prop.1.toWalk.concat w.prop.2.symm, rfl⟩
  left_inv | ⟨.cons _ (.cons _ .nil), hp⟩ => 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✝ : V
h✝¹ : Adj G u v✝
h✝ : Adj G v✝ v
hp : Walk.length (Walk.cons h✝¹ (Walk.cons h✝ Walk.nil)) = 2
⊢ (fun w =>
        { val := Walk.concat (Adj.toWalk (_ : ↑w ∈ neighborSet G u)) (_ : Adj G (↑w) v),
          property :=
            (_ :
              Walk.length (Walk.concat (Adj.toWalk (_ : ↑w ∈ neighborSet G u)) (_ : Adj G (↑w) v)) =
                Walk.length (Walk.concat (Adj.toWalk (_ : ↑w ∈ neighborSet G u)) (_ : Adj G (↑w) v))) })
      ((fun p => { val := Walk.getVert (↑p) 1, property := (_ : Walk.getVert (↑p) 1 ∈ commonNeighbors G u v) })
        { val := Walk.cons h✝¹ (Walk.cons h✝ Walk.nil), property := hp }) =
    { val := Walk.cons h✝¹ (Walk.cons h✝ Walk.nil), property := hp }

Next tactic:
rfl
/-- The `Finset` of length-`n` walks from `u` to `v`.
This is used to give `{p : G.walk u v | p.length = n}` a `Fintype` instance, and it
can also be useful as a recursive description of this set when `V` is finite.

See `SimpleGraph.coe_finsetWalkLength_eq` for the relationship between this `Finset` and
the set of length-`n` walks. -/
def finsetWalkLength (n : ℕ) (u v : V) : Finset (G.Walk u v) :=
  match n with
  | 0 =>
    if h : u = v 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
inst✝ : LocallyFinite G
n : ℕ
u v : V
h : u = v
⊢ Finset (Walk G u v)

Next tactic:
subst u
/-- The `Finset` of length-`n` walks from `u` to `v`.
This is used to give `{p : G.walk u v | p.length = n}` a `Fintype` instance, and it
can also be useful as a recursive description of this set when `V` is finite.

See `SimpleGraph.coe_finsetWalkLength_eq` for the relationship between this `Finset` and
the set of length-`n` walks. -/
def finsetWalkLength (n : ℕ) (u v : V) : Finset (G.Walk u v) :=
  match n with
  | 0 =>
    if h : u = v 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
inst✝ : LocallyFinite G
n : ℕ
v : V
⊢ Finset (Walk G v v)

Next tactic:
exact {Walk.nil}
/-- The `Finset` of length-`n` walks from `u` to `v`.
This is used to give `{p : G.walk u v | p.length = n}` a `Fintype` instance, and it
can also be useful as a recursive description of this set when `V` is finite.

See `SimpleGraph.coe_finsetWalkLength_eq` for the relationship between this `Finset` and
the set of length-`n` walks. -/
def finsetWalkLength (n : ℕ) (u v : V) : Finset (G.Walk u v) :=
  match n with
  | 0 =>
    if h : u = v then by
      subst u
      exact {Walk.nil}
    else ∅
  | n + 1 =>
    Finset.univ.biUnion fun (w : G.neighborSet u) =>
      (finsetWalkLength n w v).map ⟨fun p => Walk.cons w.property p, fun _ _ => by 

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n✝ : ℕ
u v : V
n : ℕ
w : ↑(neighborSet G u)
x✝¹ x✝ : Walk G (↑w) v
⊢ (fun p => Walk.cons (_ : ↑w ∈ neighborSet G u) p) x✝¹ = (fun p => Walk.cons (_ : ↑w ∈ neighborSet G u) p) x✝ →
    x✝¹ = x✝

Next tactic:
simp
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
u v : V
⊢ ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}

Next tactic:
induction' n with n ih generalizing u v
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · 

Proof state:
case zero
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
u v : V
⊢ ↑(finsetWalkLength G Nat.zero u v) = {p | Walk.length p = Nat.zero}

Next tactic:
obtain rfl | huv := eq_or_ne u v
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> 

Proof state:
case zero.inl
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
u : V
⊢ ↑(finsetWalkLength G Nat.zero u u) = {p | Walk.length p = Nat.zero}

Next tactic:
simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> 

Proof state:
case zero.inr
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
u v : V
huv : u ≠ v
⊢ ↑(finsetWalkLength G Nat.zero u v) = {p | Walk.length p = Nat.zero}

Next tactic:
simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · 

Proof state:
case succ
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
⊢ ↑(finsetWalkLength G (Nat.succ n) u v) = {p | Walk.length p = Nat.succ n}

Next tactic:
simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    

Proof state:
case succ
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
⊢ ⋃ x,
      ↑(Finset.map
          { toFun := fun p => Walk.cons (_ : ↑x ∈ neighborSet G u) p,
            inj' :=
              (_ :
                ∀ (x_1 x_2 : Walk G (↑x) v),
                  Walk.cons (_ : ↑x ∈ neighborSet G u) x_1 = Walk.cons (_ : ↑x ∈ neighborSet G u) x_2 → x_1 = x_2) }
          (finsetWalkLength G n (↑x) v)) =
    ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
ext p
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    

Proof state:
case succ.h
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
⊢ p ∈
      ⋃ x,
        ↑(Finset.map
            { toFun := fun p => Walk.cons (_ : ↑x ∈ neighborSet G u) p,
              inj' :=
                (_ :
                  ∀ (x_1 x_2 : Walk G (↑x) v),
                    Walk.cons (_ : ↑x ∈ neighborSet G u) x_1 = Walk.cons (_ : ↑x ∈ neighborSet G u) x_2 → x_1 = x_2) }
            (finsetWalkLength G n (↑x) v)) ↔
    p ∈ ⋃ w, ⋃ (h : Adj G u w), Walk.cons h '' {p' | Walk.length p' = n}

Next tactic:
simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
    

Proof state:
case succ.h
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
⊢ (∃ i,
      ∃ (h : Adj G u i),
        ∃ x ∈ finsetWalkLength G n i v,
          Walk.cons (_ : ↑{ val := i, property := (_ : i ∈ neighborSet G u) } ∈ neighborSet G u) x = p) ↔
    ∃ i, ∃ (h : Adj G u i), ∃ x, Walk.length x = n ∧ Walk.cons (_ : Adj G u i) x = p

Next tactic:
congr!
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
    congr!
    

Proof state:
case succ.h.a.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_1.a
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
x✝² : V
x✝¹ : Adj G u x✝²
x✝ : Walk G x✝² v
⊢ x✝ ∈ finsetWalkLength G n x✝² v ↔ Walk.length x✝ = n

Next tactic:
rename_i w _ q
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
    congr!
    rename_i w _ q
    

Proof state:
case succ.h.a.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_1.a
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
w : V
x✝ : Adj G u w
q : Walk G w v
⊢ q ∈ finsetWalkLength G n w v ↔ Walk.length q = n

Next tactic:
have := Set.ext_iff.mp (ih w v) q
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
    congr!
    rename_i w _ q
    have := Set.ext_iff.mp (ih w v) q
    

Proof state:
case succ.h.a.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_1.a
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
w : V
x✝ : Adj G u w
q : Walk G w v
this : q ∈ ↑(finsetWalkLength G n w v) ↔ q ∈ {p | Walk.length p = n}
⊢ q ∈ finsetWalkLength G n w v ↔ Walk.length q = n

Next tactic:
simp only [Finset.mem_coe, Set.mem_setOf_eq] at this
theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) :
    (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by
  induction' n with n ih generalizing u v
  · obtain rfl | huv := eq_or_ne u v <;> simp [finsetWalkLength, set_walk_length_zero_eq_of_ne, *]
  · simp only [finsetWalkLength, set_walk_length_succ_eq, Finset.coe_biUnion, Finset.mem_coe,
      Finset.mem_univ, Set.iUnion_true]
    ext p
    simp only [mem_neighborSet, Finset.coe_map, Embedding.coeFn_mk, Set.iUnion_coe_set,
      Set.mem_iUnion, Set.mem_image, Finset.mem_coe, Set.mem_setOf_eq]
    congr!
    rename_i w _ q
    have := Set.ext_iff.mp (ih w v) q
    simp only [Finset.mem_coe, Set.mem_setOf_eq] at this
    

Proof state:
case succ.h.a.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_1.a
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
ih : ∀ (u v : V), ↑(finsetWalkLength G n u v) = {p | Walk.length p = n}
u v : V
p : Walk G u v
w : V
x✝ : Adj G u w
q : Walk G w v
this : q ∈ finsetWalkLength G n w v ↔ Walk.length q = n
⊢ q ∈ finsetWalkLength G n w v ↔ Walk.length q = n

Next tactic:
rw [← this]
instance fintypeSetWalkLength (u v : V) (n : ℕ) : Fintype {p : G.Walk u v | p.length = n} :=
  Fintype.ofFinset (G.finsetWalkLength n u v) fun p => by
    

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
u v : V
n : ℕ
p : Walk G u v
⊢ p ∈ finsetWalkLength G n u v ↔ p ∈ {p | Walk.length p = n}

Next tactic:
rw [← Finset.mem_coe, coe_finsetWalkLength_eq]
theorem set_walk_length_toFinset_eq (n : ℕ) (u v : V) :
    {p : G.Walk u v | p.length = n}.toFinset = G.finsetWalkLength n u v := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
u v : V
⊢ Set.toFinset {p | Walk.length p = n} = finsetWalkLength G n u v

Next tactic:
ext p
theorem set_walk_length_toFinset_eq (n : ℕ) (u v : V) :
    {p : G.Walk u v | p.length = n}.toFinset = G.finsetWalkLength n u v := by
  ext p
  

Proof state:
case a
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
n : ℕ
u v : V
p : Walk G u v
⊢ p ∈ Set.toFinset {p | Walk.length p = n} ↔ p ∈ finsetWalkLength G n u v

Next tactic:
simp [← coe_finsetWalkLength_eq]
theorem card_set_walk_length_eq (u v : V) (n : ℕ) :
    Fintype.card {p : G.Walk u v | p.length = n} = (G.finsetWalkLength n u v).card :=
  Fintype.card_ofFinset (G.finsetWalkLength n u v) fun p => by
    

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝¹ : DecidableEq V
inst✝ : LocallyFinite G
u v : V
n : ℕ
p : Walk G u v
⊢ p ∈ finsetWalkLength G n u v ↔ p ∈ {p | Walk.length p = n}

Next tactic:
rw [← Finset.mem_coe, coe_finsetWalkLength_eq]
instance fintypeSetPathLength (u v : V) (n : ℕ) :
    Fintype {p : G.Walk u v | p.IsPath ∧ p.length = n} :=
  Fintype.ofFinset ((G.finsetWalkLength n u v).filter Walk.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
inst✝ : LocallyFinite G
u v : V
n : ℕ
⊢ ∀ (x : Walk G u v),
    x ∈ Finset.filter Walk.IsPath (finsetWalkLength G n u v) ↔ x ∈ {p | Walk.IsPath p ∧ Walk.length p = n}

Next tactic:
simp [Walk.mem_finsetWalkLength_iff_length_eq, and_comm]
theorem reachable_iff_exists_finsetWalkLength_nonempty (u v : V) :
    G.Reachable u v ↔ ∃ n : Fin (Fintype.card V), (G.finsetWalkLength n u v).Nonempty := by
  

Proof state:
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
⊢ Reachable G u v ↔ ∃ n, Finset.Nonempty (finsetWalkLength G (↑n) u v)

Next tactic:
constructor
theorem reachable_iff_exists_finsetWalkLength_nonempty (u v : V) :
    G.Reachable u v ↔ ∃ n : Fin (Fintype.card V), (G.finsetWalkLength n u v).Nonempty := by
  constructor
  · 

Proof state:
case mp
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
⊢ Reachable G u v → ∃ n, Finset.Nonempty (finsetWalkLength G (↑n) u v)

Next tactic:
intro r
theorem reachable_iff_exists_finsetWalkLength_nonempty (u v : V) :
    G.Reachable u v ↔ ∃ n : Fin (Fintype.card V), (G.finsetWalkLength n u v).Nonempty := by
  constructor
  · intro r
    

Proof state:
case mp
V : Type u
V' : Type v
V'' : Type w
G : SimpleGraph V
G' : SimpleGraph V'
G'' : SimpleGraph V''
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
r : Reachable G u v
⊢ ∃ n, Finset.Nonempty (finsetWalkLength G (↑n) u v)

Next tactic:
refine r.elim_path fun p => ?_