l3lab/ntp-mathlib huggingface dataset:
instance : HasShift (DifferentialObject S C) S :=
  hasShiftMk _ _
    { F := shiftFunctor C
      zero := shiftZero C
      add := shiftFunctorAdd C
      assoc_hom_app := fun m₁ m₂ m₃ X => by
        ext1
        convert shiftFunctorAdd_assoc_hom_app m₁ m₂ m₃ X.obj
        dsimp [shiftFunctorAdd']
        simp
      zero_add_hom_app := fun n X => by
        ext1
        

Proof state:
case w
S : Type u_1
inst✝³ : AddCommGroupWithOne S
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasShift C S
n : S
X : DifferentialObject S C
⊢ autoParam
    (((shiftFunctorAdd C 0 n).hom.app X).f =
      (eqToHom (_ : (shiftFunctor C (0 + n)).obj X = (shiftFunctor C n).obj ((𝟭 (DifferentialObject S C)).obj X)) ≫
          (shiftFunctor C n).map ((shiftZero C).inv.app X)).f)
    _auto✝

Next tactic:
convert shiftFunctorAdd_zero_add_hom_app n X.obj
instance : HasShift (DifferentialObject S C) S :=
  hasShiftMk _ _
    { F := shiftFunctor C
      zero := shiftZero C
      add := shiftFunctorAdd C
      assoc_hom_app := fun m₁ m₂ m₃ X => by
        ext1
        convert shiftFunctorAdd_assoc_hom_app m₁ m₂ m₃ X.obj
        dsimp [shiftFunctorAdd']
        simp
      zero_add_hom_app := fun n X => by
        ext1
        convert shiftFunctorAdd_zero_add_hom_app n X.obj
        

Proof state:
case h.e'_3.h
S : Type u_1
inst✝³ : AddCommGroupWithOne S
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasShift C S
n : S
X : DifferentialObject S C
e_1✝ :
  (((shiftFunctor C (0 + n)).obj X).obj ⟶ ((shiftFunctor C 0 ⋙ shiftFunctor C n).obj X).obj) =
    ((CategoryTheory.shiftFunctor C (0 + n)).obj X.obj ⟶
      (CategoryTheory.shiftFunctor C 0 ⋙ CategoryTheory.shiftFunctor C n).obj X.obj)
⊢ (eqToHom (_ : (shiftFunctor C (0 + n)).obj X = (shiftFunctor C n).obj ((𝟭 (DifferentialObject S C)).obj X)) ≫
        (shiftFunctor C n).map ((shiftZero C).inv.app X)).f =
    eqToHom
        (_ :
          (CategoryTheory.shiftFunctor C (0 + n)).obj X.obj = (CategoryTheory.shiftFunctor C n).obj ((𝟭 C).obj X.obj)) ≫
      (CategoryTheory.shiftFunctor C n).map ((shiftFunctorZero C S).inv.app X.obj)

Next tactic:
simp
instance : HasShift (DifferentialObject S C) S :=
  hasShiftMk _ _
    { F := shiftFunctor C
      zero := shiftZero C
      add := shiftFunctorAdd C
      assoc_hom_app := fun m₁ m₂ m₃ X => by
        ext1
        convert shiftFunctorAdd_assoc_hom_app m₁ m₂ m₃ X.obj
        dsimp [shiftFunctorAdd']
        simp
      zero_add_hom_app := fun n X => by
        ext1
        convert shiftFunctorAdd_zero_add_hom_app n X.obj
        simp
      add_zero_hom_app := fun n X => by
        

Proof state:
S : Type u_1
inst✝³ : AddCommGroupWithOne S
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasShift C S
n : S
X : DifferentialObject S C
⊢ (shiftFunctorAdd C n 0).hom.app X =
    eqToHom (_ : (shiftFunctor C (n + 0)).obj X = (𝟭 (DifferentialObject S C)).obj ((shiftFunctor C n).obj X)) ≫
      (shiftZero C).inv.app ((shiftFunctor C n).obj X)

Next tactic:
ext1
instance : HasShift (DifferentialObject S C) S :=
  hasShiftMk _ _
    { F := shiftFunctor C
      zero := shiftZero C
      add := shiftFunctorAdd C
      assoc_hom_app := fun m₁ m₂ m₃ X => by
        ext1
        convert shiftFunctorAdd_assoc_hom_app m₁ m₂ m₃ X.obj
        dsimp [shiftFunctorAdd']
        simp
      zero_add_hom_app := fun n X => by
        ext1
        convert shiftFunctorAdd_zero_add_hom_app n X.obj
        simp
      add_zero_hom_app := fun n X => by
        ext1
        

Proof state:
case w
S : Type u_1
inst✝³ : AddCommGroupWithOne S
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasShift C S
n : S
X : DifferentialObject S C
⊢ autoParam
    (((shiftFunctorAdd C n 0).hom.app X).f =
      (eqToHom (_ : (shiftFunctor C (n + 0)).obj X = (𝟭 (DifferentialObject S C)).obj ((shiftFunctor C n).obj X)) ≫
          (shiftZero C).inv.app ((shiftFunctor C n).obj X)).f)
    _auto✝

Next tactic:
convert shiftFunctorAdd_add_zero_hom_app n X.obj
instance : HasShift (DifferentialObject S C) S :=
  hasShiftMk _ _
    { F := shiftFunctor C
      zero := shiftZero C
      add := shiftFunctorAdd C
      assoc_hom_app := fun m₁ m₂ m₃ X => by
        ext1
        convert shiftFunctorAdd_assoc_hom_app m₁ m₂ m₃ X.obj
        dsimp [shiftFunctorAdd']
        simp
      zero_add_hom_app := fun n X => by
        ext1
        convert shiftFunctorAdd_zero_add_hom_app n X.obj
        simp
      add_zero_hom_app := fun n X => by
        ext1
        convert shiftFunctorAdd_add_zero_hom_app n X.obj
        

Proof state:
case h.e'_3.h
S : Type u_1
inst✝³ : AddCommGroupWithOne S
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasShift C S
n : S
X : DifferentialObject S C
e_1✝ :
  (((shiftFunctor C (n + 0)).obj X).obj ⟶ ((shiftFunctor C n ⋙ shiftFunctor C 0).obj X).obj) =
    ((CategoryTheory.shiftFunctor C (n + 0)).obj X.obj ⟶
      (CategoryTheory.shiftFunctor C n ⋙ CategoryTheory.shiftFunctor C 0).obj X.obj)
⊢ (eqToHom (_ : (shiftFunctor C (n + 0)).obj X = (𝟭 (DifferentialObject S C)).obj ((shiftFunctor C n).obj X)) ≫
        (shiftZero C).inv.app ((shiftFunctor C n).obj X)).f =
    eqToHom
        (_ :
          (CategoryTheory.shiftFunctor C (n + 0)).obj X.obj = (𝟭 C).obj ((CategoryTheory.shiftFunctor C n).obj X.obj)) ≫
      (shiftFunctorZero C S).inv.app ((CategoryTheory.shiftFunctor C n).obj X.obj)

Next tactic:
simp
/-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an
object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module
structure, see `preadditiveYonedaObj`.
-/
@[simps]
def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGroupCat.{v} where
  obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _
  map f :=
    { app := fun X =>
        { toFun := fun g => g ≫ f
          map_zero' := Limits.zero_comp
          map_add' := fun g g' => add_comp _ _ _ _ _ _ }
      naturality := fun X X' g => AddCommGroupCat.ext fun x => Category.assoc _ _ _ }
  map_id _ := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝ : C
⊢ { obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
          map := fun {X Y} f =>
            NatTrans.mk fun X_1 =>
              { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                map_add' :=
                  (_ :
                    ∀
                      (g g' :
                        ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj X_1)),
                      (g + g') ≫ f = g ≫ f + g' ≫ f) } }.map
      (𝟙 x✝) =
    𝟙
      ({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
            map := fun {X Y} f =>
              NatTrans.mk fun X_1 =>
                { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                  map_add' :=
                    (_ :
                      ∀
                        (g g' :
                          ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                              X_1)),
                        (g + g') ≫ f = g ≫ f + g' ≫ f) } }.obj
        x✝)

Next tactic:
ext
/-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an
object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module
structure, see `preadditiveYonedaObj`.
-/
@[simps]
def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGroupCat.{v} where
  obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _
  map f :=
    { app := fun X =>
        { toFun := fun g => g ≫ f
          map_zero' := Limits.zero_comp
          map_add' := fun g g' => add_comp _ _ _ _ _ _ }
      naturality := fun X X' g => AddCommGroupCat.ext fun x => Category.assoc _ _ _ }
  map_id _ := by ext; 

Proof state:
case w.h.w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝² : C
x✝¹ : Cᵒᵖ
x✝ :
  ↑(({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
              map := fun {X Y} f =>
                NatTrans.mk fun X_1 =>
                  { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                    map_add' :=
                      (_ :
                        ∀
                          (g g' :
                            ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                                X_1)),
                          (g + g') ≫ f = g ≫ f + g' ≫ f) } }.obj
          x✝²).obj
      x✝¹)
⊢ (({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
                map := fun {X Y} f =>
                  NatTrans.mk fun X_1 =>
                    { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                      map_add' :=
                        (_ :
                          ∀
                            (g g' :
                              ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                                  X_1)),
                            (g + g') ≫ f = g ≫ f + g' ≫ f) } }.map
            (𝟙 x✝²)).app
        x✝¹)
      x✝ =
    ((𝟙
            ({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
                  map := fun {X Y} f =>
                    NatTrans.mk fun X_1 =>
                      { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                        map_add' :=
                          (_ :
                            ∀
                              (g g' :
                                ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat)
                                        X).obj
                                    X_1)),
                              (g + g') ≫ f = g ≫ f + g' ≫ f) } }.obj
              x✝²)).app
        x✝¹)
      x✝

Next tactic:
dsimp
/-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an
object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module
structure, see `preadditiveYonedaObj`.
-/
@[simps]
def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGroupCat.{v} where
  obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _
  map f :=
    { app := fun X =>
        { toFun := fun g => g ≫ f
          map_zero' := Limits.zero_comp
          map_add' := fun g g' => add_comp _ _ _ _ _ _ }
      naturality := fun X X' g => AddCommGroupCat.ext fun x => Category.assoc _ _ _ }
  map_id _ := by ext; dsimp; 

Proof state:
case w.h.w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝² : C
x✝¹ : Cᵒᵖ
x✝ :
  ↑(({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
              map := fun {X Y} f =>
                NatTrans.mk fun X_1 =>
                  { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                    map_add' :=
                      (_ :
                        ∀
                          (g g' :
                            ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                                X_1)),
                          (g + g') ≫ f = g ≫ f + g' ≫ f) } }.obj
          x✝²).obj
      x✝¹)
⊢ x✝ ≫ 𝟙 x✝² = x✝

Next tactic:
simp
/-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an
object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module
structure, see `preadditiveYonedaObj`.
-/
@[simps]
def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGroupCat.{v} where
  obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _
  map f :=
    { app := fun X =>
        { toFun := fun g => g ≫ f
          map_zero' := Limits.zero_comp
          map_add' := fun g g' => add_comp _ _ _ _ _ _ }
      naturality := fun X X' g => AddCommGroupCat.ext fun x => Category.assoc _ _ _ }
  map_id _ := by ext; dsimp; simp
  map_comp f g := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X✝ Y✝ Z✝ : C
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
⊢ { obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
          map := fun {X Y} f =>
            NatTrans.mk fun X_1 =>
              { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                map_add' :=
                  (_ :
                    ∀
                      (g g' :
                        ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj X_1)),
                      (g + g') ≫ f = g ≫ f + g' ≫ f) } }.map
      (f ≫ g) =
    { obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
            map := fun {X Y} f =>
              NatTrans.mk fun X_1 =>
                { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                  map_add' :=
                    (_ :
                      ∀
                        (g g' :
                          ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                              X_1)),
                        (g + g') ≫ f = g ≫ f + g' ≫ f) } }.map
        f ≫
      { obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
            map := fun {X Y} f =>
              NatTrans.mk fun X_1 =>
                { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                  map_add' :=
                    (_ :
                      ∀
                        (g g' :
                          ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                              X_1)),
                        (g + g') ≫ f = g ≫ f + g' ≫ f) } }.map
        g

Next tactic:
ext
/-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an
object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module
structure, see `preadditiveYonedaObj`.
-/
@[simps]
def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGroupCat.{v} where
  obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _
  map f :=
    { app := fun X =>
        { toFun := fun g => g ≫ f
          map_zero' := Limits.zero_comp
          map_add' := fun g g' => add_comp _ _ _ _ _ _ }
      naturality := fun X X' g => AddCommGroupCat.ext fun x => Category.assoc _ _ _ }
  map_id _ := by ext; dsimp; simp
  map_comp f g := by ext; dsimp; 

Proof state:
case w.h.w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X✝ Y✝ Z✝ : C
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
x✝¹ : Cᵒᵖ
x✝ :
  ↑(({ obj := fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat,
              map := fun {X Y} f =>
                NatTrans.mk fun X_1 =>
                  { toZeroHom := { toFun := fun g => g ≫ f, map_zero' := (_ : 0 ≫ f = 0) },
                    map_add' :=
                      (_ :
                        ∀
                          (g g' :
                            ↑(((fun Y => preadditiveYonedaObj Y ⋙ forget₂ (ModuleCat (End Y)) AddCommGroupCat) X).obj
                                X_1)),
                          (g + g') ≫ f = g ≫ f + g' ≫ f) } }.obj
          X✝).obj
      x✝¹)
⊢ x✝ ≫ f ≫ g = (x✝ ≫ f) ≫ g

Next tactic:
simp
/-- The Yoneda embedding for preadditive categories sends an object `X` to the copresheaf sending an
object `Y` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End X`-module
structure, see `preadditiveCoyonedaObj`.
-/
@[simps]
def preadditiveCoyoneda : Cᵒᵖ ⥤ C ⥤ AddCommGroupCat.{v} where
  obj X := preadditiveCoyonedaObj X ⋙ forget₂ _ _
  map f :=
    { app := fun Y =>
        { toFun := fun g => f.unop ≫ g
          map_zero' := Limits.comp_zero
          map_add' := fun g g' => comp_add _ _ _ _ _ _ }
      naturality := fun Y Y' g =>
        AddCommGroupCat.ext fun x => Eq.symm <| Category.assoc _ _ _ }
  map_id _ := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝ : Cᵒᵖ
⊢ { obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
          map := fun {X Y} f =>
            NatTrans.mk fun Y_1 =>
              { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                map_add' :=
                  (_ :
                    ∀
                      (g g' :
                        ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat) X).obj
                            Y_1)),
                      f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.map
      (𝟙 x✝) =
    𝟙
      ({ obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
            map := fun {X Y} f =>
              NatTrans.mk fun Y_1 =>
                { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                  map_add' :=
                    (_ :
                      ∀
                        (g g' :
                          ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat) X).obj
                              Y_1)),
                        f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.obj
        x✝)

Next tactic:
ext
/-- The Yoneda embedding for preadditive categories sends an object `X` to the copresheaf sending an
object `Y` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End X`-module
structure, see `preadditiveCoyonedaObj`.
-/
@[simps]
def preadditiveCoyoneda : Cᵒᵖ ⥤ C ⥤ AddCommGroupCat.{v} where
  obj X := preadditiveCoyonedaObj X ⋙ forget₂ _ _
  map f :=
    { app := fun Y =>
        { toFun := fun g => f.unop ≫ g
          map_zero' := Limits.comp_zero
          map_add' := fun g g' => comp_add _ _ _ _ _ _ }
      naturality := fun Y Y' g =>
        AddCommGroupCat.ext fun x => Eq.symm <| Category.assoc _ _ _ }
  map_id _ := by ext; 

Proof state:
case w.h.w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝² : Cᵒᵖ
x✝¹ : C
x✝ :
  ↑(({ obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
              map := fun {X Y} f =>
                NatTrans.mk fun Y_1 =>
                  { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                    map_add' :=
                      (_ :
                        ∀
                          (g g' :
                            ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat) X).obj
                                Y_1)),
                          f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.obj
          x✝²).obj
      x✝¹)
⊢ (({ obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
                map := fun {X Y} f =>
                  NatTrans.mk fun Y_1 =>
                    { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                      map_add' :=
                        (_ :
                          ∀
                            (g g' :
                              ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat)
                                      X).obj
                                  Y_1)),
                            f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.map
            (𝟙 x✝²)).app
        x✝¹)
      x✝ =
    ((𝟙
            ({ obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
                  map := fun {X Y} f =>
                    NatTrans.mk fun Y_1 =>
                      { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                        map_add' :=
                          (_ :
                            ∀
                              (g g' :
                                ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat)
                                        X).obj
                                    Y_1)),
                              f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.obj
              x✝²)).app
        x✝¹)
      x✝

Next tactic:
dsimp
/-- The Yoneda embedding for preadditive categories sends an object `X` to the copresheaf sending an
object `Y` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End X`-module
structure, see `preadditiveCoyonedaObj`.
-/
@[simps]
def preadditiveCoyoneda : Cᵒᵖ ⥤ C ⥤ AddCommGroupCat.{v} where
  obj X := preadditiveCoyonedaObj X ⋙ forget₂ _ _
  map f :=
    { app := fun Y =>
        { toFun := fun g => f.unop ≫ g
          map_zero' := Limits.comp_zero
          map_add' := fun g g' => comp_add _ _ _ _ _ _ }
      naturality := fun Y Y' g =>
        AddCommGroupCat.ext fun x => Eq.symm <| Category.assoc _ _ _ }
  map_id _ := by ext; dsimp; 

Proof state:
case w.h.w
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
x✝² : Cᵒᵖ
x✝¹ : C
x✝ :
  ↑(({ obj := fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat,
              map := fun {X Y} f =>
                NatTrans.mk fun Y_1 =>
                  { toZeroHom := { toFun := fun g => f.unop ≫ g, map_zero' := (_ : f.unop ≫ 0 = 0) },
                    map_add' :=
                      (_ :
                        ∀
                          (g g' :
                            ↑(((fun X => preadditiveCoyonedaObj X ⋙ forget₂ (ModuleCat (End X)) AddCommGroupCat) X).obj
                                Y_1)),
                          f.unop ≫ (g + g') = f.unop ≫ g + f.unop ≫ g') } }.obj
          x✝²).obj
      x✝¹)
⊢ 𝟙 x✝².unop ≫ x✝ = x✝

Next tactic:
simp