l3lab/ntp-mathlib huggingface dataset:
@[reassoc]
theorem additiveObjIsoBiproduct_naturality (F : Mat_ C ⥤ D) [Functor.Additive F] {M N : Mat_ C}
    (f : M ⟶ N) :
    F.map f ≫ (additiveObjIsoBiproduct F N).hom =
      (additiveObjIsoBiproduct F M).hom ≫
        biproduct.matrix fun i j => F.map ((embedding C).map (f i j)) := by
  ext i : 1
  simp only [Category.assoc, additiveObjIsoBiproduct_hom_π, isoBiproductEmbedding_hom,
    embedding_obj_ι, embedding_obj_X, biproduct.lift_π, biproduct.matrix_π,
    ← cancel_epi (additiveObjIsoBiproduct F M).inv, Iso.inv_hom_id_assoc]
  ext j : 1
  simp only [ι_additiveObjIsoBiproduct_inv_assoc, isoBiproductEmbedding_inv,
    biproduct.ι_desc, ← F.map_comp]
  congr 1
  

Proof state:
case w.w.e_a
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : Mat_ C ⥤ D
inst✝ : Functor.Additive F
M N : Mat_ C
f : M ⟶ N
i : N.ι
j : M.ι
⊢ ((fun j_1 k => if h : j = k then eqToHom (_ : X M j = X M k) else 0) ≫
      f ≫ fun j k => if h : j = i then eqToHom (_ : X N j = X N i) else 0) =
    (embedding C).map (f j i)

Next tactic:
funext ⟨⟩ ⟨⟩
@[reassoc]
theorem additiveObjIsoBiproduct_naturality (F : Mat_ C ⥤ D) [Functor.Additive F] {M N : Mat_ C}
    (f : M ⟶ N) :
    F.map f ≫ (additiveObjIsoBiproduct F N).hom =
      (additiveObjIsoBiproduct F M).hom ≫
        biproduct.matrix fun i j => F.map ((embedding C).map (f i j)) := by
  ext i : 1
  simp only [Category.assoc, additiveObjIsoBiproduct_hom_π, isoBiproductEmbedding_hom,
    embedding_obj_ι, embedding_obj_X, biproduct.lift_π, biproduct.matrix_π,
    ← cancel_epi (additiveObjIsoBiproduct F M).inv, Iso.inv_hom_id_assoc]
  ext j : 1
  simp only [ι_additiveObjIsoBiproduct_inv_assoc, isoBiproductEmbedding_inv,
    biproduct.ι_desc, ← F.map_comp]
  congr 1
  funext ⟨⟩ ⟨⟩
  

Proof state:
case w.w.e_a.h.h
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : Mat_ C ⥤ D
inst✝ : Functor.Additive F
M N : Mat_ C
f : M ⟶ N
i : N.ι
j : M.ι
⊢ ((fun j_1 k => if h : j = k then eqToHom (_ : X M j = X M k) else 0) ≫
        f ≫ fun j k => if h : j = i then eqToHom (_ : X N j = X N i) else 0)
      PUnit.unit PUnit.unit =
    (embedding C).map (f j i) PUnit.unit PUnit.unit

Next tactic:
simp [comp_apply, dite_comp, comp_dite]
@[reassoc]
theorem additiveObjIsoBiproduct_naturality' (F : Mat_ C ⥤ D) [Functor.Additive F] {M N : Mat_ C}
    (f : M ⟶ N) :
    (additiveObjIsoBiproduct F M).inv ≫ F.map f =
      biproduct.matrix (fun i j => F.map ((embedding C).map (f i j)) : _) ≫
        (additiveObjIsoBiproduct F N).inv :=
  by 

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : Mat_ C ⥤ D
inst✝ : Functor.Additive F
M N : Mat_ C
f : M ⟶ N
⊢ (additiveObjIsoBiproduct F M).inv ≫ F.map f =
    (biproduct.matrix fun i j => F.map ((embedding C).map (f i j))) ≫ (additiveObjIsoBiproduct F N).inv

Next tactic:
rw [Iso.inv_comp_eq, ← Category.assoc, Iso.eq_comp_inv, additiveObjIsoBiproduct_naturality]
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
⊢ { obj := fun X => ⨁ fun i => F.obj (CategoryTheory.Mat_.X X i),
          map := fun {X Y} f => biproduct.matrix fun i j => F.map (f i j) }.map
      (𝟙 X) =
    𝟙
      ({ obj := fun X => ⨁ fun i => F.obj (CategoryTheory.Mat_.X X i),
            map := fun {X Y} f => biproduct.matrix fun i j => F.map (f i j) }.obj
        X)

Next tactic:
dsimp
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    dsimp
    

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
⊢ (biproduct.matrix fun i j => F.map (𝟙 X i j)) = 𝟙 (⨁ fun i => F.obj (CategoryTheory.Mat_.X X i))

Next tactic:
ext i j
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    dsimp
    ext i j
    

Proof state:
case w.w
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
i j : X.ι
⊢ biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      (biproduct.matrix fun i j => F.map (𝟙 X i j)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i =
    biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      𝟙 (⨁ fun i => F.obj (CategoryTheory.Mat_.X X i)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i

Next tactic:
by_cases h : j = i
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    dsimp
    ext i j
    by_cases h : j = i
    · 

Proof state:
case pos
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
i j : X.ι
h : j = i
⊢ biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      (biproduct.matrix fun i j => F.map (𝟙 X i j)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i =
    biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      𝟙 (⨁ fun i => F.obj (CategoryTheory.Mat_.X X i)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i

Next tactic:
subst h
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    dsimp
    ext i j
    by_cases h : j = i
    · subst h; 

Proof state:
case pos
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
j : X.ι
⊢ biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      (biproduct.matrix fun i j => F.map (𝟙 X i j)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) j =
    biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      𝟙 (⨁ fun i => F.obj (CategoryTheory.Mat_.X X i)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) j

Next tactic:
simp
/-- Any additive functor `C ⥤ D` to a category `D` with finite biproducts extends to
a functor `Mat_ C ⥤ D`. -/
@[simps]
def lift (F : C ⥤ D) [Functor.Additive F] : Mat_ C ⥤ D where
  obj X := ⨁ fun i => F.obj (X.X i)
  map f := biproduct.matrix fun i j => F.map (f i j)
  map_id X := by
    dsimp
    ext i j
    by_cases h : j = i
    · subst h; simp
    · 

Proof state:
case neg
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Preadditive C
D : Type u₁
inst✝³ : Category.{v₁, u₁} D
inst✝² : Preadditive D
inst✝¹ : HasFiniteBiproducts D
F : C ⥤ D
inst✝ : Functor.Additive F
X : Mat_ C
i j : X.ι
h : ¬j = i
⊢ biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      (biproduct.matrix fun i j => F.map (𝟙 X i j)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i =
    biproduct.ι (fun i => F.obj (CategoryTheory.Mat_.X X i)) j ≫
      𝟙 (⨁ fun i => F.obj (CategoryTheory.Mat_.X X i)) ≫ biproduct.π (fun i => F.obj (CategoryTheory.Mat_.X X i)) i

Next tactic:
simp [h]
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ L.map f ≫
      ((fun M =>
            additiveObjIsoBiproduct L M ≪≫
              (biproduct.mapIso fun i => α.app (X M i)) ≪≫
                (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (X M i)) ≪≫
                  (additiveObjIsoBiproduct (lift F) M).symm)
          Y✝).hom =
    ((fun M =>
            additiveObjIsoBiproduct L M ≪≫
              (biproduct.mapIso fun i => α.app (X M i)) ≪≫
                (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (X M i)) ≪≫
                  (additiveObjIsoBiproduct (lift F) M).symm)
          X✝).hom ≫
      (lift F).map f

Next tactic:
dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ L.map f ≫
      (additiveObjIsoBiproduct L Y✝).hom ≫
        (biproduct.map fun b => (α.app (X Y✝ b)).hom) ≫
          (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X Y✝ b)).hom) ≫
            (additiveObjIsoBiproduct (lift F) Y✝).inv =
    ((additiveObjIsoBiproduct L X✝).hom ≫
        (biproduct.map fun b => (α.app (X X✝ b)).hom) ≫
          (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X X✝ b)).hom) ≫
            (additiveObjIsoBiproduct (lift F) X✝).inv) ≫
      (lift F).map f

Next tactic:
simp only [additiveObjIsoBiproduct_naturality_assoc]
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.matrix fun i j => L.map ((embedding C).map (f i j))) ≫
        (biproduct.map fun b => (α.app (X Y✝ b)).hom) ≫
          (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X Y✝ b)).hom) ≫
            (additiveObjIsoBiproduct (lift F) Y✝).inv =
    ((additiveObjIsoBiproduct L X✝).hom ≫
        (biproduct.map fun b => (α.app (X X✝ b)).hom) ≫
          (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X X✝ b)).hom) ≫
            (additiveObjIsoBiproduct (lift F) X✝).inv) ≫
      (lift F).map f

Next tactic:
simp only [biproduct.matrix_map_assoc, Category.assoc]
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.matrix fun j k =>
          L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) ≫
        (additiveObjIsoBiproduct (lift F) Y✝).inv =
    (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.map fun b => (α.app (X X✝ b)).hom) ≫
        (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X X✝ b)).hom) ≫
          (additiveObjIsoBiproduct (lift F) X✝).inv ≫ (lift F).map f

Next tactic:
simp only [additiveObjIsoBiproduct_naturality']
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.matrix fun j k =>
          L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) ≫
        (additiveObjIsoBiproduct (lift F) Y✝).inv =
    (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.map fun b => (α.app (X X✝ b)).hom) ≫
        (biproduct.map fun b => ((embeddingLiftIso F).symm.app (X X✝ b)).hom) ≫
          (biproduct.matrix fun i j => (lift F).map ((embedding C).map (f i j))) ≫
            (additiveObjIsoBiproduct (lift F) Y✝).inv

Next tactic:
simp only [biproduct.map_matrix_assoc, Category.assoc]
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.matrix fun j k =>
          L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) ≫
        (additiveObjIsoBiproduct (lift F) Y✝).inv =
    (additiveObjIsoBiproduct L X✝).hom ≫
      (biproduct.matrix fun j k =>
          (α.app (X X✝ j)).hom ≫
            ((embeddingLiftIso F).symm.app (X X✝ j)).hom ≫ (lift F).map ((embedding C).map (f j k))) ≫
        (additiveObjIsoBiproduct (lift F) Y✝).inv

Next tactic:
congr 3
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      congr 3
      

Proof state:
case e_a.e_a.e_m
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
⊢ (fun j k => L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) =
    fun j k =>
    (α.app (X X✝ j)).hom ≫ ((embeddingLiftIso F).symm.app (X X✝ j)).hom ≫ (lift F).map ((embedding C).map (f j k))

Next tactic:
ext j k
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      congr 3
      ext j k
      

Proof state:
case e_a.e_a.e_m.h.h
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
j : X✝.ι
k : Y✝.ι
⊢ L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom =
    (α.app (X X✝ j)).hom ≫ ((embeddingLiftIso F).symm.app (X X✝ j)).hom ≫ (lift F).map ((embedding C).map (f j k))

Next tactic:
apply biproduct.hom_ext
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      congr 3
      ext j k
      apply biproduct.hom_ext
      

Proof state:
case e_a.e_a.e_m.h.h.w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
j : X✝.ι
k : Y✝.ι
⊢ ∀ (j_1 : ((embedding C).obj (X Y✝ k)).ι),
    (L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) ≫
        biproduct.π (fun i => F.obj (X ((embedding C).obj (X Y✝ k)) i)) j_1 =
      ((α.app (X X✝ j)).hom ≫ ((embeddingLiftIso F).symm.app (X X✝ j)).hom ≫ (lift F).map ((embedding C).map (f j k))) ≫
        biproduct.π (fun i => F.obj (X ((embedding C).obj (X Y✝ k)) i)) j_1

Next tactic:
rintro ⟨⟩
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      congr 3
      ext j k
      apply biproduct.hom_ext
      rintro ⟨⟩
      

Proof state:
case e_a.e_a.e_m.h.h.w.unit
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
j : X✝.ι
k : Y✝.ι
⊢ (L.map ((embedding C).map (f j k)) ≫ (α.app (X Y✝ k)).hom ≫ ((embeddingLiftIso F).symm.app (X Y✝ k)).hom) ≫
      biproduct.π (fun i => F.obj (X ((embedding C).obj (X Y✝ k)) i)) PUnit.unit =
    ((α.app (X X✝ j)).hom ≫ ((embeddingLiftIso F).symm.app (X X✝ j)).hom ≫ (lift F).map ((embedding C).map (f j k))) ≫
      biproduct.π (fun i => F.obj (X ((embedding C).obj (X Y✝ k)) i)) PUnit.unit

Next tactic:
dsimp