l3lab/ntp-mathlib huggingface dataset:
/-- The identity functor induces the identity functor on matrix categories.
-/
@[simps!]
def mapMatId : (𝟭 C).mapMat_ ≅ 𝟭 (Mat_ C) :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
inst✝² : Preadditive C
D : Type u_1
inst✝¹ : Category.{v₁, u_1} D
inst✝ : Preadditive D
M N : Mat_ C
f : M ⟶ N
⊢ (mapMat_ (𝟭 C)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) N).hom =
    ((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) M).hom ≫ (𝟭 (Mat_ C)).map f

Next tactic:
ext
/-- The identity functor induces the identity functor on matrix categories.
-/
@[simps!]
def mapMatId : (𝟭 C).mapMat_ ≅ 𝟭 (Mat_ C) :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    

Proof state:
case H
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
inst✝² : Preadditive C
D : Type u_1
inst✝¹ : Category.{v₁, u_1} D
inst✝ : Preadditive D
M N : Mat_ C
f : M ⟶ N
i✝ : ((mapMat_ (𝟭 C)).obj M).ι
j✝ : ((𝟭 (Mat_ C)).obj N).ι
⊢ ((mapMat_ (𝟭 C)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) N).hom) i✝ j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) M).hom ≫ (𝟭 (Mat_ C)).map f) i✝ j✝

Next tactic:
cases M
/-- The identity functor induces the identity functor on matrix categories.
-/
@[simps!]
def mapMatId : (𝟭 C).mapMat_ ≅ 𝟭 (Mat_ C) :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    cases M; 

Proof state:
case H.mk
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
inst✝² : Preadditive C
D : Type u_1
inst✝¹ : Category.{v₁, u_1} D
inst✝ : Preadditive D
N : Mat_ C
j✝ : ((𝟭 (Mat_ C)).obj N).ι
ι✝ : Type
fintype✝ : Fintype ι✝
X✝ : ι✝ → C
f : Mat_.mk ι✝ X✝ ⟶ N
i✝ : ((mapMat_ (𝟭 C)).obj (Mat_.mk ι✝ X✝)).ι
⊢ ((mapMat_ (𝟭 C)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) N).hom) i✝ j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) (Mat_.mk ι✝ X✝)).hom ≫ (𝟭 (Mat_ C)).map f) i✝
      j✝

Next tactic:
cases N
/-- The identity functor induces the identity functor on matrix categories.
-/
@[simps!]
def mapMatId : (𝟭 C).mapMat_ ≅ 𝟭 (Mat_ C) :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    cases M; cases N
    

Proof state:
case H.mk.mk
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
inst✝² : Preadditive C
D : Type u_1
inst✝¹ : Category.{v₁, u_1} D
inst✝ : Preadditive D
ι✝¹ : Type
fintype✝¹ : Fintype ι✝¹
X✝¹ : ι✝¹ → C
i✝ : ((mapMat_ (𝟭 C)).obj (Mat_.mk ι✝¹ X✝¹)).ι
ι✝ : Type
fintype✝ : Fintype ι✝
X✝ : ι✝ → C
j✝ : ((𝟭 (Mat_ C)).obj (Mat_.mk ι✝ X✝)).ι
f : Mat_.mk ι✝¹ X✝¹ ⟶ Mat_.mk ι✝ X✝
⊢ ((mapMat_ (𝟭 C)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) (Mat_.mk ι✝ X✝)).hom) i✝
      j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (𝟭 C)).obj M = (𝟭 (Mat_ C)).obj M)) (Mat_.mk ι✝¹ X✝¹)).hom ≫ (𝟭 (Mat_ C)).map f)
      i✝ j✝

Next tactic:
simp [comp_dite, dite_comp]
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by 

Proof state:
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
M : Mat_ C
⊢ (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M

Next tactic:
cases M
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; 

Proof state:
case mk
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
ι✝ : Type
fintype✝ : Fintype ι✝
X✝ : ι✝ → C
⊢ (mapMat_ (F ⋙ G)).obj (Mat_.mk ι✝ X✝) = (mapMat_ F ⋙ mapMat_ G).obj (Mat_.mk ι✝ X✝)

Next tactic:
rfl
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    

Proof state:
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
M N : Mat_ C
f : M ⟶ N
⊢ (mapMat_ (F ⋙ G)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) N).hom =
    ((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) M).hom ≫
      (mapMat_ F ⋙ mapMat_ G).map f

Next tactic:
ext
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    

Proof state:
case H
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
M N : Mat_ C
f : M ⟶ N
i✝ : ((mapMat_ (F ⋙ G)).obj M).ι
j✝ : ((mapMat_ F ⋙ mapMat_ G).obj N).ι
⊢ ((mapMat_ (F ⋙ G)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) N).hom)
      i✝ j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) M).hom ≫
        (mapMat_ F ⋙ mapMat_ G).map f)
      i✝ j✝

Next tactic:
cases M
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    cases M; 

Proof state:
case H.mk
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
N : Mat_ C
j✝ : ((mapMat_ F ⋙ mapMat_ G).obj N).ι
ι✝ : Type
fintype✝ : Fintype ι✝
X✝ : ι✝ → C
f : Mat_.mk ι✝ X✝ ⟶ N
i✝ : ((mapMat_ (F ⋙ G)).obj (Mat_.mk ι✝ X✝)).ι
⊢ ((mapMat_ (F ⋙ G)).map f ≫ ((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) N).hom)
      i✝ j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) (Mat_.mk ι✝ X✝)).hom ≫
        (mapMat_ F ⋙ mapMat_ G).map f)
      i✝ j✝

Next tactic:
cases N
/-- Composite functors induce composite functors on matrix categories.
-/
@[simps!]
def mapMatComp {E : Type*} [Category.{v₁} E] [Preadditive E] (F : C ⥤ D) [Functor.Additive F]
    (G : D ⥤ E) [Functor.Additive G] : (F ⋙ G).mapMat_ ≅ F.mapMat_ ⋙ G.mapMat_ :=
  NatIso.ofComponents (fun M => eqToIso (by cases M; rfl)) fun {M N} f => by
    ext
    cases M; cases N
    

Proof state:
case H.mk.mk
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
inst✝⁶ : Preadditive C
D : Type u_1
inst✝⁵ : Category.{v₁, u_1} D
inst✝⁴ : Preadditive D
E : Type u_2
inst✝³ : Category.{v₁, u_2} E
inst✝² : Preadditive E
F : C ⥤ D
inst✝¹ : Additive F
G : D ⥤ E
inst✝ : Additive G
ι✝¹ : Type
fintype✝¹ : Fintype ι✝¹
X✝¹ : ι✝¹ → C
i✝ : ((mapMat_ (F ⋙ G)).obj (Mat_.mk ι✝¹ X✝¹)).ι
ι✝ : Type
fintype✝ : Fintype ι✝
X✝ : ι✝ → C
j✝ : ((mapMat_ F ⋙ mapMat_ G).obj (Mat_.mk ι✝ X✝)).ι
f : Mat_.mk ι✝¹ X✝¹ ⟶ Mat_.mk ι✝ X✝
⊢ ((mapMat_ (F ⋙ G)).map f ≫
        ((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) (Mat_.mk ι✝ X✝)).hom)
      i✝ j✝ =
    (((fun M => eqToIso (_ : (mapMat_ (F ⋙ G)).obj M = (mapMat_ F ⋙ mapMat_ G).obj M)) (Mat_.mk ι✝¹ X✝¹)).hom ≫
        (mapMat_ F ⋙ mapMat_ G).map f)
      i✝ j✝

Next tactic:
simp [comp_dite, dite_comp]
/-- The embedding of `C` into `Mat_ C` as one-by-one matrices.
(We index the summands by `punit`.) -/
@[simps]
def embedding : C ⥤ Mat_ C where
  obj X := ⟨PUnit, fun _ => X⟩
  map f _ _ := f
  map_id _ := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
x✝ : C
⊢ { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map (𝟙 x✝) =
    𝟙 ({ obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.obj x✝)

Next tactic:
ext ⟨⟩
/-- The embedding of `C` into `Mat_ C` as one-by-one matrices.
(We index the summands by `punit`.) -/
@[simps]
def embedding : C ⥤ Mat_ C where
  obj X := ⟨PUnit, fun _ => X⟩
  map f _ _ := f
  map_id _ := by ext ⟨⟩; 

Proof state:
case H.unit
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
x✝ : C
j✝ : ({ obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.obj x✝).ι
⊢ { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map (𝟙 x✝) PUnit.unit j✝ =
    𝟙 ({ obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.obj x✝) PUnit.unit j✝

Next tactic:
simp
/-- The embedding of `C` into `Mat_ C` as one-by-one matrices.
(We index the summands by `punit`.) -/
@[simps]
def embedding : C ⥤ Mat_ C where
  obj X := ⟨PUnit, fun _ => X⟩
  map f _ _ := f
  map_id _ := by ext ⟨⟩; simp
  map_comp _ _ := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
X✝ Y✝ Z✝ : C
x✝¹ : X✝ ⟶ Y✝
x✝ : Y✝ ⟶ Z✝
⊢ { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map (x✝¹ ≫ x✝) =
    { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map x✝¹ ≫
      { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map x✝

Next tactic:
ext ⟨⟩
/-- The embedding of `C` into `Mat_ C` as one-by-one matrices.
(We index the summands by `punit`.) -/
@[simps]
def embedding : C ⥤ Mat_ C where
  obj X := ⟨PUnit, fun _ => X⟩
  map f _ _ := f
  map_id _ := by ext ⟨⟩; simp
  map_comp _ _ := by ext ⟨⟩; 

Proof state:
case H.unit
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
X✝ Y✝ Z✝ : C
x✝¹ : X✝ ⟶ Y✝
x✝ : Y✝ ⟶ Z✝
j✝ : ({ obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.obj Z✝).ι
⊢ { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map (x✝¹ ≫ x✝) PUnit.unit j✝ =
    ({ obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map x✝¹ ≫
        { obj := fun X => mk PUnit.{1} fun x => X, map := fun {X Y} f x x => f }.map x✝)
      PUnit.unit j✝

Next tactic:
simp
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
⊢ ((biproduct.lift fun i j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫
      biproduct.desc fun i j k => if h : i = k then eqToHom (_ : X M i = X M k) else 0) =
    𝟙 M

Next tactic:
simp only [biproduct.lift_desc]
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
⊢ (∑ j : M.ι,
      (fun j_1 k => if h : j_1 = j then eqToHom (_ : X M j_1 = X M j) else 0) ≫ fun j_1 k =>
        if h : j = k then eqToHom (_ : X M j = X M k) else 0) =
    𝟙 M

Next tactic:
funext i j
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    

Proof state:
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ Finset.sum Finset.univ
      (fun j =>
        (fun j_1 k => if h : j_1 = j then eqToHom (_ : X M j_1 = X M j) else 0) ≫ fun j_1 k =>
          if h : j = k then eqToHom (_ : X M j = X M k) else 0)
      i j =
    𝟙 M i j

Next tactic:
dsimp [id_def]
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    

Proof state:
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ Finset.sum Finset.univ
      (fun j =>
        (fun j_1 k => if h : j_1 = j then eqToHom (_ : X M j_1 = X M j) else 0) ≫ fun j_1 k =>
          if h : j = k then eqToHom (_ : X M j = X M k) else 0)
      i j =
    if h : i = j then eqToHom (_ : X M i = X M j) else 0

Next tactic:
rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; 

Proof state:
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ ((fun j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫ fun j k =>
        if h : i = k then eqToHom (_ : X M i = X M k) else 0)
      i j =
    if h : i = j then eqToHom (_ : X M i = X M j) else 0
case h.h.h₀
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ ∀ b ∈ Finset.univ,
    b ≠ i →
      ((fun j k => if h : j = b then eqToHom (_ : X M j = X M b) else 0) ≫ fun j k =>
            if h : b = k then eqToHom (_ : X M b = X M k) else 0)
          i j =
        0
case h.h.h₁
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ i ∉ Finset.univ →
    ((fun j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫ fun j k =>
          if h : i = k then eqToHom (_ : X M i = X M k) else 0)
        i j =
      0

Next tactic:
rotate_left
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · 

Proof state:
case h.h.h₀
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ ∀ b ∈ Finset.univ,
    b ≠ i →
      ((fun j k => if h : j = b then eqToHom (_ : X M j = X M b) else 0) ≫ fun j k =>
            if h : b = k then eqToHom (_ : X M b = X M k) else 0)
          i j =
        0

Next tactic:
intro b _ hb
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      

Proof state:
case h.h.h₀
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j b : M.ι
a✝ : b ∈ Finset.univ
hb : b ≠ i
⊢ ((fun j k => if h : j = b then eqToHom (_ : X M j = X M b) else 0) ≫ fun j k =>
        if h : b = k then eqToHom (_ : X M b = X M k) else 0)
      i j =
    0

Next tactic:
dsimp
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      

Proof state:
case h.h.h₀
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j b : M.ι
a✝ : b ∈ Finset.univ
hb : b ≠ i
⊢ (∑ j_1 in {PUnit.unit},
      (if h : i = b then eqToHom (_ : X M i = X M b) else 0) ≫ if h : b = j then eqToHom (_ : X M b = X M j) else 0) =
    0

Next tactic:
simp only [Finset.sum_const, Finset.card_singleton, one_smul]
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      simp only [Finset.sum_const, Finset.card_singleton, one_smul]
      

Proof state:
case h.h.h₀
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j b : M.ι
a✝ : b ∈ Finset.univ
hb : b ≠ i
⊢ ((if h : i = b then eqToHom (_ : X M i = X M b) else 0) ≫ if h : b = j then eqToHom (_ : X M b = X M j) else 0) = 0

Next tactic:
rw [dif_neg hb.symm, zero_comp]
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      simp only [Finset.sum_const, Finset.card_singleton, one_smul]
      rw [dif_neg hb.symm, zero_comp]
    · 

Proof state:
case h.h.h₁
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ i ∉ Finset.univ →
    ((fun j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫ fun j k =>
          if h : i = k then eqToHom (_ : X M i = X M k) else 0)
        i j =
      0

Next tactic:
intro h
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      simp only [Finset.sum_const, Finset.card_singleton, one_smul]
      rw [dif_neg hb.symm, zero_comp]
    · intro h
      

Proof state:
case h.h.h₁
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
h : i ∉ Finset.univ
⊢ ((fun j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫ fun j k =>
        if h : i = k then eqToHom (_ : X M i = X M k) else 0)
      i j =
    0

Next tactic:
simp at h
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      simp only [Finset.sum_const, Finset.card_singleton, one_smul]
      rw [dif_neg hb.symm, zero_comp]
    · intro h
      simp at h
    

Proof state:
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
i j : M.ι
⊢ ((fun j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) ≫ fun j k =>
        if h : i = k then eqToHom (_ : X M i = X M k) else 0)
      i j =
    if h : i = j then eqToHom (_ : X M i = X M j) else 0

Next tactic:
simp
/-- Every object in `Mat_ C` is isomorphic to the biproduct of its summands.
-/
@[simps]
def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where
  hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0
  inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0
  hom_inv_id := by
    simp only [biproduct.lift_desc]
    funext i j
    dsimp [id_def]
    rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left
    · intro b _ hb
      dsimp
      simp only [Finset.sum_const, Finset.card_singleton, one_smul]
      rw [dif_neg hb.symm, zero_comp]
    · intro h
      simp at h
    simp
  inv_hom_id := by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
M : Mat_ C
⊢ ((biproduct.desc fun i j k => if h : i = k then eqToHom (_ : X M i = X M k) else 0) ≫
      biproduct.lift fun i j k => if h : j = i then eqToHom (_ : X M j = X M i) else 0) =
    𝟙 (⨁ fun i => (embedding C).obj (X M i))

Next tactic:
apply biproduct.hom_ext