-- Lean 4 proof step from Mathlib.Algebra.Category.Grp.AB (goal)
Goal:
J : Type u
inst : SmallCategory J
inst_1 : IsFiltered J
X Y : Discrete J ⥤ AddCommGrpCat
f : X ⟶ Y
iX : limit X ≅ AddCommGrpCat.of ((i : J) → (↑(X.obj { as := i }) : Type u)) :=
  Iso.trans (Y := ∏ᶜ fun (j : J) ↦ X.obj { as := j }) (Iso.symm (Pi.isoLimit X))
    (IsLimit.conePointUniqueUpToIso (limit.isLimit (Discrete.functor fun (j : J) ↦ X.obj { as := j }))
      (LimitCone.isLimit (AddCommGrpCat.HasLimit.productLimitCone fun (j : J) ↦ X.obj { as := j })))
iY : limit Y ≅ AddCommGrpCat.of ((i : J) → (↑(Y.obj { as := i }) : Type u)) :=
  Iso.trans (Y := ∏ᶜ fun (j : J) ↦ Y.obj { as := j }) (Iso.symm (Pi.isoLimit Y))
    (IsLimit.conePointUniqueUpToIso (limit.isLimit (Discrete.functor fun (j : J) ↦ Y.obj { as := j }))
      (LimitCone.isLimit (AddCommGrpCat.HasLimit.productLimitCone fun (j : J) ↦ Y.obj { as := j })))
this :
  Eq (α := ((i : J) → (↑(X.obj { as := i }) : Type u)) → (i : J) → (↑(Y.obj { as := i }) : Type u))
    (Pi.map (α := fun (i : J) ↦ (↑(X.obj { as := i }) : Type u)) (β := fun (i : J) ↦ (↑(Y.obj { as := i }) : Type u))
      fun (i : J) ↦
      (⇑(ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
            AddCommGrpCat.carrier) (X := X.obj { as := i }) (f.app { as := i })) :
        (a : (↑(X.obj { as := i }) : Type u)) → (↑(Y.obj { as := i }) : Type u)))
    (⇑(ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
          AddCommGrpCat.carrier) (Y := AddCommGrpCat.of ((i : J) → (↑(Y.obj { as := i }) : Type u)))
          (iX.inv ≫ CategoryTheory.Functor.map lim f ≫ iY.hom)) :
      (a : (↑(AddCommGrpCat.of ((i : J) → (↑(X.obj { as := i }) : Type u))) : Type u)) →
        (↑(AddCommGrpCat.of ((i : J) → (↑(Y.obj { as := i }) : Type u))) : Type u))
hf :
  ∀ (k : Discrete J),
    Function.Surjective (α := (↑(X.obj k) : Type u)) (β := (↑(Y.obj k) : Type u))
      (⇑(ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
            AddCommGrpCat.carrier) (f.app k)) :
        (a : (↑(X.obj k) : Type u)) → (↑(Y.obj k) : Type u))
b : (↑(AddCommGrpCat.of ((i : J) → (↑(Y.obj { as := i }) : Type u))) : Type u)
⊢ (Pi.map (α := fun (i : J) ↦ (↑(X.obj { as := i }) : Type u)) (β := fun (i : J) ↦ (↑(Y.obj { as := i }) : Type u))
      (fun (i : J) ↦
        (⇑(ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
              AddCommGrpCat.carrier) (X := X.obj { as := i }) (f.app { as := i })) :
          (a : (↑(X.obj { as := i }) : Type u)) → (↑(Y.obj { as := i }) : Type u)))
      fun (i : J) ↦
      ⋯.choose (p := fun (a : (↑(X.obj { as := i }) : Type u)) ↦
        (ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
                AddCommGrpCat.carrier) (X := X.obj { as := i }) (f.app { as := i }) :
              (a : (↑(X.obj { as := i }) : Type u)) → (↑(Y.obj { as := i }) : Type u))
            a =
          b i)) =
    b
have h : ∀ (i : J),
  Pi.map (α := fun (i : J) ↦ (↑(X.obj { as := i }) : Type u)) (β := fun (i : J) ↦ (↑(Y.obj { as := i }) : Type u))
      (fun (i : J) ↦
        (⇑(ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
              AddCommGrpCat.carrier) (X := X.obj { as := i }) (f.app { as := i })) :
          (a : (↑(X.obj { as := i }) : Type u)) → (↑(Y.obj { as := i }) : Type u)))
      (fun (i : J) ↦
        sorry.choose (p := fun (a : (↑(X.obj { as := i }) : Type u)) ↦
          (ConcreteCategory.hom (FC := fun (x1 x2 : AddCommGrpCat.{u}) ↦ (↑x1 : Type u) →+ (↑x2 : Type u)) (CC :=
                  AddCommGrpCat.carrier) (X := X.obj { as := i }) (f.app { as := i }) :
                (a : (↑(X.obj { as := i }) : Type u)) → (↑(Y.obj { as := i }) : Type u))
              a =
            b i))
      i =
    b i
Tactic: funext i