l3lab/ntp-mathlib huggingface dataset:
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by 

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
⊢ Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]

Next tactic:
decide
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
⊢ ¬IsSolvable (Perm (Fin 5))

Next tactic:
have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by 

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
⊢ x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹

Next tactic:
decide
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
⊢ ¬IsSolvable (Perm (Fin 5))

Next tactic:
refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => _
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by 

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
⊢ x ≠ 1

Next tactic:
decide
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => _
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
n : ℕ
⊢ x ∈ derivedSeries (Perm (Fin 5)) n

Next tactic:
induction' n with n ih
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => _
  induction' n with n ih
  · 

Proof state:
case zero
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
⊢ x ∈ derivedSeries (Perm (Fin 5)) Nat.zero

Next tactic:
exact mem_top x
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => _
  induction' n with n ih
  · exact mem_top x
  · 

Proof state:
case succ
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
n : ℕ
ih : x ∈ derivedSeries (Perm (Fin 5)) n
⊢ x ∈ derivedSeries (Perm (Fin 5)) (Nat.succ n)

Next tactic:
rw [key, (derivedSeries_normal _ _).mem_comm_iff, inv_mul_cancel_left]
theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by
  let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩
  let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩
  let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩
  have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by decide
  refine' not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => _
  induction' n with n ih
  · exact mem_top x
  · rw [key, (derivedSeries_normal _ _).mem_comm_iff, inv_mul_cancel_left]
    

Proof state:
case succ
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
x : Perm (Fin 5) :=
  { toFun := ![1, 2, 0, 3, 4], invFun := ![2, 0, 1, 3, 4],
    left_inv := (_ : Function.LeftInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]),
    right_inv := (_ : Function.RightInverse ![2, 0, 1, 3, 4] ![1, 2, 0, 3, 4]) }
y : Perm (Fin 5) :=
  { toFun := ![3, 4, 2, 0, 1], invFun := ![3, 4, 2, 0, 1],
    left_inv := (_ : Function.LeftInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]),
    right_inv := (_ : Function.RightInverse ![3, 4, 2, 0, 1] ![3, 4, 2, 0, 1]) }
z : Perm (Fin 5) :=
  { toFun := ![0, 3, 2, 1, 4], invFun := ![0, 3, 2, 1, 4],
    left_inv := (_ : Function.LeftInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]),
    right_inv := (_ : Function.RightInverse ![0, 3, 2, 1, 4] ![0, 3, 2, 1, 4]) }
key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹
n : ℕ
ih : x ∈ derivedSeries (Perm (Fin 5)) n
⊢ ⁅x, y * x * y⁻¹⁆ ∈ derivedSeries (Perm (Fin 5)) (Nat.succ n)

Next tactic:
exact commutator_mem_commutator ih ((derivedSeries_normal _ _).conj_mem _ ih _)
theorem Equiv.Perm.not_solvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) :
    ¬IsSolvable (Equiv.Perm X) := by
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
X : Type u_3
hX : 5 ≤ Cardinal.mk X
⊢ ¬IsSolvable (Perm X)

Next tactic:
intro h
theorem Equiv.Perm.not_solvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) :
    ¬IsSolvable (Equiv.Perm X) := by
  intro h
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
X : Type u_3
hX : 5 ≤ Cardinal.mk X
h : IsSolvable (Perm X)
⊢ False

Next tactic:
have key : Nonempty (Fin 5 ↪ X) := by
    rwa [← Cardinal.lift_mk_le, Cardinal.mk_fin, Cardinal.lift_natCast, Cardinal.lift_id]
theorem Equiv.Perm.not_solvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) :
    ¬IsSolvable (Equiv.Perm X) := by
  intro h
  have key : Nonempty (Fin 5 ↪ X) := by
    

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
X : Type u_3
hX : 5 ≤ Cardinal.mk X
h : IsSolvable (Perm X)
⊢ Nonempty (Fin 5 ↪ X)

Next tactic:
rwa [← Cardinal.lift_mk_le, Cardinal.mk_fin, Cardinal.lift_natCast, Cardinal.lift_id]
theorem Equiv.Perm.not_solvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) :
    ¬IsSolvable (Equiv.Perm X) := by
  intro h
  have key : Nonempty (Fin 5 ↪ X) := by
    rwa [← Cardinal.lift_mk_le, Cardinal.mk_fin, Cardinal.lift_natCast, Cardinal.lift_id]
  

Proof state:
G : Type u_1
G' : Type u_2
inst✝¹ : Group G
inst✝ : Group G'
f : G →* G'
X : Type u_3
hX : 5 ≤ Cardinal.mk X
h : IsSolvable (Perm X)
key : Nonempty (Fin 5 ↪ X)
⊢ False

Next tactic:
exact
    Equiv.Perm.fin_5_not_solvable
      (solvable_of_solvable_injective (Equiv.Perm.viaEmbeddingHom_injective (Nonempty.some key)))
instance (X Y : WalkingCospan) : Subsingleton (X ⟶ Y) := by
  

Proof state:
X Y : WalkingCospan
⊢ Subsingleton (X ⟶ Y)

Next tactic:
constructor
instance (X Y : WalkingCospan) : Subsingleton (X ⟶ Y) := by
  constructor; 

Proof state:
case allEq
X Y : WalkingCospan
⊢ ∀ (a b : X ⟶ Y), a = b

Next tactic:
intros
instance (X Y : WalkingCospan) : Subsingleton (X ⟶ Y) := by
  constructor; intros; 

Proof state:
case allEq
X Y : WalkingCospan
a✝ b✝ : X ⟶ Y
⊢ a✝ = b✝

Next tactic:
simp [eq_iff_true_of_subsingleton]
instance (X Y : WalkingSpan) : Subsingleton (X ⟶ Y) := by
  

Proof state:
X Y : WalkingSpan
⊢ Subsingleton (X ⟶ Y)

Next tactic:
constructor
instance (X Y : WalkingSpan) : Subsingleton (X ⟶ Y) := by
  constructor; 

Proof state:
case allEq
X Y : WalkingSpan
⊢ ∀ (a b : X ⟶ Y), a = b

Next tactic:
intros a b
instance (X Y : WalkingSpan) : Subsingleton (X ⟶ Y) := by
  constructor; intros a b; 

Proof state:
case allEq
X Y : WalkingSpan
a b : X ⟶ Y
⊢ a = b

Next tactic:
simp [eq_iff_true_of_subsingleton]
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
⊢ s ≅ t

Next tactic:
apply Cones.ext i _
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
⊢ ∀ (j : WalkingCospan), s.π.app j = i.hom ≫ t.π.app j

Next tactic:
rintro (⟨⟩ | ⟨⟨⟩⟩)
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · 

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
have h₁ := s.π.naturality WalkingCospan.Hom.inl
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : ((Functor.const WalkingCospan).obj s.pt).map inl ≫ s.π.app one = s.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
dsimp at h₁
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : 𝟙 s.pt ≫ s.π.app one = s.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
simp only [Category.id_comp] at h₁
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    simp only [Category.id_comp] at h₁
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : s.π.app one = s.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
have h₂ := t.π.naturality WalkingCospan.Hom.inl
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    simp only [Category.id_comp] at h₁
    have h₂ := t.π.naturality WalkingCospan.Hom.inl
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : s.π.app one = s.π.app left ≫ F.map inl
h₂ : ((Functor.const WalkingCospan).obj t.pt).map inl ≫ t.π.app one = t.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
dsimp at h₂
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    simp only [Category.id_comp] at h₁
    have h₂ := t.π.naturality WalkingCospan.Hom.inl
    dsimp at h₂
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : s.π.app one = s.π.app left ≫ F.map inl
h₂ : 𝟙 t.pt ≫ t.π.app one = t.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
simp only [Category.id_comp] at h₂
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    simp only [Category.id_comp] at h₁
    have h₂ := t.π.naturality WalkingCospan.Hom.inl
    dsimp at h₂
    simp only [Category.id_comp] at h₂
    

Proof state:
case none
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
h₁ : s.π.app one = s.π.app left ≫ F.map inl
h₂ : t.π.app one = t.π.app left ≫ F.map inl
⊢ s.π.app none = i.hom ≫ t.π.app none

Next tactic:
simp_rw [h₂, ← Category.assoc, ← w₁, ← h₁]
/-- To construct an isomorphism of cones over the walking cospan,
it suffices to construct an isomorphism
of the cone points and check it commutes with the legs to `left` and `right`. -/
def WalkingCospan.ext {F : WalkingCospan ⥤ C} {s t : Cone F} (i : s.pt ≅ t.pt)
    (w₁ : s.π.app WalkingCospan.left = i.hom ≫ t.π.app WalkingCospan.left)
    (w₂ : s.π.app WalkingCospan.right = i.hom ≫ t.π.app WalkingCospan.right) : s ≅ t := by
  apply Cones.ext i _
  rintro (⟨⟩ | ⟨⟨⟩⟩)
  · have h₁ := s.π.naturality WalkingCospan.Hom.inl
    dsimp at h₁
    simp only [Category.id_comp] at h₁
    have h₂ := t.π.naturality WalkingCospan.Hom.inl
    dsimp at h₂
    simp only [Category.id_comp] at h₂
    simp_rw [h₂, ← Category.assoc, ← w₁, ← h₁]
  · 

Proof state:
case some.left
C : Type u
inst✝ : Category.{v, u} C
F : WalkingCospan ⥤ C
s t : Cone F
i : s.pt ≅ t.pt
w₁ : s.π.app left = i.hom ≫ t.π.app left
w₂ : s.π.app right = i.hom ≫ t.π.app right
⊢ s.π.app (some WalkingPair.left) = i.hom ≫ t.π.app (some WalkingPair.left)

Next tactic:
exact w₁