l3lab/ntp-mathlib huggingface dataset:
instance estimator' :
    Estimator (Thunk.mk fun _ => (levenshtein C xs ys, ys.length))
      (LevenshteinEstimator' C xs ys) where
  bound_le e := match e.pre_rev, e.split, e.bound_eq with
  | [], split, eq => by
    simp only [List.reverse_nil, List.nil_append] at split
    rw [e.distances_eq] at eq
    simp only [List.getElem_eq_get] at eq
    rw [split] at eq
    exact eq.le
  | y :: t, split, eq => by
    rw [e.distances_eq] at eq
    simp only at eq
    dsimp [EstimatorData.bound]
    rw [eq]
    simp only [← split]
    constructor
    · simp only [List.minimum_of_length_pos_le_iff]
      exact suffixLevenshtein_minimum_le_levenshtein_append _ _ _
    · exact List.length_le_of_sublist (List.sublist_append_right _ _)
  improve_spec e := by
    dsimp [EstimatorData.improve]
    match e.pre_rev, e.split, e.bound_eq, e.distances_eq with
    | [], split, eq, _ =>
      simp only [List.reverse_nil, List.nil_append] at split
      rw [e.distances_eq] at eq
      simp only [List.getElem_eq_get] at eq
      rw [split] at eq
      exact eq
    | [y], split, b_eq, d_eq =>
      simp only [EstimatorData.bound, Prod.lt_iff, List.reverse_nil, List.nil_append]
      right
      have b_eq : e.bound = (List.minimum_of_length_pos _, List.length e.suff) := by
        simpa using b_eq
      rw [b_eq]
      constructor
      · refine (?_ : _ ≤ _).trans (List.minimum_of_length_pos_le_getElem _)
        simp only [List.minimum_of_length_pos_le_iff, List.coe_minimum_of_length_pos, d_eq]
        apply le_suffixLevenshtein_cons_minimum
      · simp [← split]
    | y₁ :: y₂ :: t, split, b_eq, d_eq =>
      simp only [EstimatorData.bound, Prod.lt_iff]
      right
      have b_eq : e.bound = (List.minimum_of_length_pos _, List.length e.suff) := by
        simpa using b_eq
      rw [b_eq]
      constructor
      · simp only [d_eq, List.minimum_of_length_pos_le_iff, List.coe_minimum_of_length_pos]
        

Proof state:
case h.left
α β δ : Type
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
C : Levenshtein.Cost α β δ
xs : List α
ys : List β
e : LevenshteinEstimator' C xs ys
y₁ y₂ : β
t : List β
split : List.reverse (y₁ :: y₂ :: t) ++ e.suff = ys
b_eq✝ :
  e.bound =
    match y₁ :: y₂ :: t, split with
    | [], split => ((↑e.distances)[0], List.length ys)
    | x, split => (List.minimum_of_length_pos (_ : 0 < List.length ↑e.distances), List.length e.suff)
d_eq : e.distances = suffixLevenshtein C xs e.suff
b_eq : e.bound = (List.minimum_of_length_pos (_ : 0 < List.length ↑e.distances), List.length e.suff)
⊢ List.minimum ↑(suffixLevenshtein C xs e.suff) ≤
    List.minimum ↑(Levenshtein.impl C xs y₁ (suffixLevenshtein C xs e.suff))

Next tactic:
apply le_suffixLevenshtein_cons_minimum
instance estimator' :
    Estimator (Thunk.mk fun _ => (levenshtein C xs ys, ys.length))
      (LevenshteinEstimator' C xs ys) where
  bound_le e := match e.pre_rev, e.split, e.bound_eq with
  | [], split, eq => by
    simp only [List.reverse_nil, List.nil_append] at split
    rw [e.distances_eq] at eq
    simp only [List.getElem_eq_get] at eq
    rw [split] at eq
    exact eq.le
  | y :: t, split, eq => by
    rw [e.distances_eq] at eq
    simp only at eq
    dsimp [EstimatorData.bound]
    rw [eq]
    simp only [← split]
    constructor
    · simp only [List.minimum_of_length_pos_le_iff]
      exact suffixLevenshtein_minimum_le_levenshtein_append _ _ _
    · exact List.length_le_of_sublist (List.sublist_append_right _ _)
  improve_spec e := by
    dsimp [EstimatorData.improve]
    match e.pre_rev, e.split, e.bound_eq, e.distances_eq with
    | [], split, eq, _ =>
      simp only [List.reverse_nil, List.nil_append] at split
      rw [e.distances_eq] at eq
      simp only [List.getElem_eq_get] at eq
      rw [split] at eq
      exact eq
    | [y], split, b_eq, d_eq =>
      simp only [EstimatorData.bound, Prod.lt_iff, List.reverse_nil, List.nil_append]
      right
      have b_eq : e.bound = (List.minimum_of_length_pos _, List.length e.suff) := by
        simpa using b_eq
      rw [b_eq]
      constructor
      · refine (?_ : _ ≤ _).trans (List.minimum_of_length_pos_le_getElem _)
        simp only [List.minimum_of_length_pos_le_iff, List.coe_minimum_of_length_pos, d_eq]
        apply le_suffixLevenshtein_cons_minimum
      · simp [← split]
    | y₁ :: y₂ :: t, split, b_eq, d_eq =>
      simp only [EstimatorData.bound, Prod.lt_iff]
      right
      have b_eq : e.bound = (List.minimum_of_length_pos _, List.length e.suff) := by
        simpa using b_eq
      rw [b_eq]
      constructor
      · simp only [d_eq, List.minimum_of_length_pos_le_iff, List.coe_minimum_of_length_pos]
        apply le_suffixLevenshtein_cons_minimum
      · 

Proof state:
case h.right
α β δ : Type
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
C : Levenshtein.Cost α β δ
xs : List α
ys : List β
e : LevenshteinEstimator' C xs ys
y₁ y₂ : β
t : List β
split : List.reverse (y₁ :: y₂ :: t) ++ e.suff = ys
b_eq✝ :
  e.bound =
    match y₁ :: y₂ :: t, split with
    | [], split => ((↑e.distances)[0], List.length ys)
    | x, split => (List.minimum_of_length_pos (_ : 0 < List.length ↑e.distances), List.length e.suff)
d_eq : e.distances = suffixLevenshtein C xs e.suff
b_eq : e.bound = (List.minimum_of_length_pos (_ : 0 < List.length ↑e.distances), List.length e.suff)
⊢ (List.minimum_of_length_pos (_ : 0 < List.length ↑e.distances), List.length e.suff).2 < Nat.succ (List.length e.suff)

Next tactic:
exact Nat.lt.base _
/-- The initial estimator for Levenshtein distances. -/
instance [CanonicallyLinearOrderedAddCommMonoid δ]
    (C : Levenshtein.Cost α β δ) (xs : List α) (ys : List β) :
    Bot (LevenshteinEstimator C xs ys) where
  bot :=
  { inner :=
    { pre_rev := ys.reverse
      suff := []
      split := by 

Proof state:
α β δ : Type
inst✝¹ : CanonicallyLinearOrderedAddCommMonoid δ
C✝ : Levenshtein.Cost α β δ
xs✝ : List α
ys✝ : List β
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
C : Levenshtein.Cost α β δ
xs : List α
ys : List β
⊢ List.reverse (List.reverse ys) ++ [] = ys

Next tactic:
simp
@[simp]
theorem quot_neg (x) :
    -- Porting note : force Lean to treat `ColimitType F` no as `Quot _`
    (by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
x : ?m.34014
⊢ ColimitType F

Next tactic:
exact Quot.mk Setoid.r (neg x)
@[simp]
theorem quot_neg (x) :
    -- Porting note : force Lean to treat `ColimitType F` no as `Quot _`
    (by exact Quot.mk Setoid.r (neg x) : ColimitType.{w} F) =
      -(by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
x : Prequotient F
⊢ ColimitType F

Next tactic:
exact Quot.mk Setoid.r x
@[simp]
theorem quot_add (x y) :
    (by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
x : ?m.34601
y : ?m.34604
⊢ ColimitType F

Next tactic:
exact Quot.mk Setoid.r (add x y)
@[simp]
theorem quot_add (x y) :
    (by exact Quot.mk Setoid.r (add x y) : ColimitType.{w} F) =
      -- Porting note : force Lean to treat `ColimitType F` no as `Quot _`
      (by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
x y : Prequotient F
⊢ ColimitType F

Next tactic:
exact Quot.mk Setoid.r x
@[simp]
theorem quot_add (x y) :
    (by exact Quot.mk Setoid.r (add x y) : ColimitType.{w} F) =
      -- Porting note : force Lean to treat `ColimitType F` no as `Quot _`
      (by exact Quot.mk Setoid.r x) + (by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
x y : Prequotient F
⊢ ColimitType F

Next tactic:
exact Quot.mk Setoid.r y
/-- The group homomorphism from a given abelian group in the diagram to the colimit abelian
group. -/
def coconeMorphism (j : J) : F.obj j ⟶ colimit.{w} F where
  toFun := coconeFun F j
  map_zero' := by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j : J
⊢ coconeFun F j 0 = 0

Next tactic:
apply Quot.sound
/-- The group homomorphism from a given abelian group in the diagram to the colimit abelian
group. -/
def coconeMorphism (j : J) : F.obj j ⟶ colimit.{w} F where
  toFun := coconeFun F j
  map_zero' := by apply Quot.sound; 

Proof state:
case a
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j : J
⊢ Setoid.r (Prequotient.of j 0) zero

Next tactic:
apply Relation.zero
/-- The group homomorphism from a given abelian group in the diagram to the colimit abelian
group. -/
def coconeMorphism (j : J) : F.obj j ⟶ colimit.{w} F where
  toFun := coconeFun F j
  map_zero' := by apply Quot.sound; apply Relation.zero
  map_add' := by 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j : J
⊢ ∀ (x y : ↑(F.obj j)),
    ZeroHom.toFun
        { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) }
        (x + y) =
      ZeroHom.toFun
          { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) }
          x +
        ZeroHom.toFun
          { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) } y

Next tactic:
intros
/-- The group homomorphism from a given abelian group in the diagram to the colimit abelian
group. -/
def coconeMorphism (j : J) : F.obj j ⟶ colimit.{w} F where
  toFun := coconeFun F j
  map_zero' := by apply Quot.sound; apply Relation.zero
  map_add' := by intros; 

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j : J
x✝ y✝ : ↑(F.obj j)
⊢ ZeroHom.toFun
      { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) }
      (x✝ + y✝) =
    ZeroHom.toFun
        { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) }
        x✝ +
      ZeroHom.toFun
        { toFun := coconeFun F j, map_zero' := (_ : Quot.mk Setoid.r (Prequotient.of j 0) = Quot.mk Setoid.r zero) } y✝

Next tactic:
apply Quot.sound
/-- The group homomorphism from a given abelian group in the diagram to the colimit abelian
group. -/
def coconeMorphism (j : J) : F.obj j ⟶ colimit.{w} F where
  toFun := coconeFun F j
  map_zero' := by apply Quot.sound; apply Relation.zero
  map_add' := by intros; apply Quot.sound; 

Proof state:
case a
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j : J
x✝ y✝ : ↑(F.obj j)
⊢ Setoid.r (Prequotient.of j (x✝ + y✝)) (add (Prequotient.of j x✝) (Prequotient.of j y✝))

Next tactic:
apply Relation.add
@[simp]
theorem cocone_naturality {j j' : J} (f : j ⟶ j') :
    F.map f ≫ coconeMorphism.{w} F j' = coconeMorphism F j := by
  

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j j' : J
f : j ⟶ j'
⊢ F.map f ≫ coconeMorphism F j' = coconeMorphism F j

Next tactic:
ext
@[simp]
theorem cocone_naturality {j j' : J} (f : j ⟶ j') :
    F.map f ≫ coconeMorphism.{w} F j' = coconeMorphism F j := by
  ext
  

Proof state:
case w
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j j' : J
f : j ⟶ j'
x✝ : ↑(F.obj j)
⊢ (F.map f ≫ coconeMorphism F j') x✝ = (coconeMorphism F j) x✝

Next tactic:
apply Quot.sound
@[simp]
theorem cocone_naturality {j j' : J} (f : j ⟶ j') :
    F.map f ≫ coconeMorphism.{w} F j' = coconeMorphism F j := by
  ext
  apply Quot.sound
  

Proof state:
case w.a
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j j' : J
f : j ⟶ j'
x✝ : ↑(F.obj j)
⊢ Setoid.r (Prequotient.of j' ((F.map f) x✝)) (Prequotient.of j x✝)

Next tactic:
apply Relation.map
@[simp]
theorem cocone_naturality_components (j j' : J) (f : j ⟶ j') (x : F.obj j) :
    (coconeMorphism.{w} F j') (F.map f x) = (coconeMorphism F j) x := by
  

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j j' : J
f : j ⟶ j'
x : ↑(F.obj j)
⊢ (coconeMorphism F j') ((F.map f) x) = (coconeMorphism F j) x

Next tactic:
rw [← cocone_naturality F f]
@[simp]
theorem cocone_naturality_components (j j' : J) (f : j ⟶ j') (x : F.obj j) :
    (coconeMorphism.{w} F j') (F.map f x) = (coconeMorphism F j) x := by
  rw [← cocone_naturality F f]
  

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
j j' : J
f : j ⟶ j'
x : ↑(F.obj j)
⊢ (coconeMorphism F j') ((F.map f) x) = (F.map f ≫ coconeMorphism F j') x

Next tactic:
rfl
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  

Proof state:
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
⊢ ColimitType F → ↑s.pt

Next tactic:
fapply Quot.lift
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · 

Proof state:
case f
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
⊢ Prequotient F → ↑s.pt

Next tactic:
exact descFunLift F s
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · 

Proof state:
case a
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
⊢ ∀ (a b : Prequotient F), Setoid.r a b → descFunLift F s a = descFunLift F s b

Next tactic:
intro x y r
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    

Proof state:
case a
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
r : Setoid.r x y
⊢ descFunLift F s x = descFunLift F s y

Next tactic:
induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => simp
    | neg => simp
    | add => simp
    | neg_1 _ _ _ r_ih => dsimp; rw [r_ih]
    | add_1 _ _ _ _ r_ih => dsimp; rw [r_ih]
    | add_2 _ _ _ _ r_ih => dsimp; rw [r_ih]
    | zero_add => dsimp; rw [zero_add]
    | add_zero => dsimp; rw [add_zero]
    | add_left_neg => dsimp; rw [add_left_neg]
    | add_comm => dsimp; rw [add_comm]
    | add_assoc => dsimp; rw [add_assoc]
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    

Proof state:
case a.refl
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝ : Prequotient F
⊢ descFunLift F s x✝ = descFunLift F s x✝

Next tactic:
| refl => rfl
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => 

Proof state:
case a.refl
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝ : Prequotient F
⊢ descFunLift F s x✝ = descFunLift F s x✝

Next tactic:
rfl
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    

Proof state:
case a.symm
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝¹ y✝ : Prequotient F
x✝ : Relation F x✝¹ y✝
r_ih : descFunLift F s x✝¹ = descFunLift F s y✝
⊢ descFunLift F s y✝ = descFunLift F s x✝¹

Next tactic:
| symm _ _ _ r_ih => exact r_ih.symm
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => 

Proof state:
case a.symm
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝¹ y✝ : Prequotient F
x✝ : Relation F x✝¹ y✝
r_ih : descFunLift F s x✝¹ = descFunLift F s y✝
⊢ descFunLift F s y✝ = descFunLift F s x✝¹

Next tactic:
exact r_ih.symm
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    

Proof state:
case a.trans
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝² y✝ z✝ : Prequotient F
x✝¹ : Relation F x✝² y✝
x✝ : Relation F y✝ z✝
r_ih_h : descFunLift F s x✝² = descFunLift F s y✝
r_ih_k : descFunLift F s y✝ = descFunLift F s z✝
⊢ descFunLift F s x✝² = descFunLift F s z✝

Next tactic:
| trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => 

Proof state:
case a.trans
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y x✝² y✝ z✝ : Prequotient F
x✝¹ : Relation F x✝² y✝
x✝ : Relation F y✝ z✝
r_ih_h : descFunLift F s x✝² = descFunLift F s y✝
r_ih_k : descFunLift F s y✝ = descFunLift F s z✝
⊢ descFunLift F s x✝² = descFunLift F s z✝

Next tactic:
exact Eq.trans r_ih_h r_ih_k
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    

Proof state:
case a.map
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x✝ y : Prequotient F
j j' : J
f : j ⟶ j'
x : ↑(F.obj j)
⊢ descFunLift F s (Prequotient.of j' ((F.map f) x)) = descFunLift F s (Prequotient.of j x)

Next tactic:
| map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => 

Proof state:
case a.map
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x✝ y : Prequotient F
j j' : J
f : j ⟶ j'
x : ↑(F.obj j)
⊢ descFunLift F s (Prequotient.of j' ((F.map f) x)) = descFunLift F s (Prequotient.of j x)

Next tactic:
simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    

Proof state:
case a.zero
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
⊢ descFunLift F s (Prequotient.of j✝ 0) = descFunLift F s zero

Next tactic:
| zero => simp
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => 

Proof state:
case a.zero
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
⊢ descFunLift F s (Prequotient.of j✝ 0) = descFunLift F s zero

Next tactic:
simp
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => simp
    

Proof state:
case a.neg
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
x✝ : ↑(F.obj j✝)
⊢ descFunLift F s (Prequotient.of j✝ (-x✝)) = descFunLift F s (neg (Prequotient.of j✝ x✝))

Next tactic:
| neg => simp
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => simp
    | neg => 

Proof state:
case a.neg
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
x✝ : ↑(F.obj j✝)
⊢ descFunLift F s (Prequotient.of j✝ (-x✝)) = descFunLift F s (neg (Prequotient.of j✝ x✝))

Next tactic:
simp
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => simp
    | neg => simp
    

Proof state:
case a.add
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
x✝ y✝ : ↑(F.obj j✝)
⊢ descFunLift F s (Prequotient.of j✝ (x✝ + y✝)) = descFunLift F s (add (Prequotient.of j✝ x✝) (Prequotient.of j✝ y✝))

Next tactic:
| add => simp
/-- The function from the colimit abelian group to the cone point of any other cocone. -/
def descFun (s : Cocone F) : ColimitType.{w} F → s.pt := by
  fapply Quot.lift
  · exact descFunLift F s
  · intro x y r
    induction r with
    | refl => rfl
    | symm _ _ _ r_ih => exact r_ih.symm
    | trans _ _ _ _ _ r_ih_h r_ih_k => exact Eq.trans r_ih_h r_ih_k
    | map j j' f x => simpa only [descFunLift, Functor.const_obj_obj] using
      FunLike.congr_fun (s.ι.naturality f) x
    | zero => simp
    | neg => simp
    | add => 

Proof state:
case a.add
J : Type u
inst✝ : Category.{v, u} J
F : J ⥤ AddCommGroupCat
s : Cocone F
x y : Prequotient F
j✝ : J
x✝ y✝ : ↑(F.obj j✝)
⊢ descFunLift F s (Prequotient.of j✝ (x✝ + y✝)) = descFunLift F s (add (Prequotient.of j✝ x✝) (Prequotient.of j✝ y✝))

Next tactic:
simp