/-- We now prove that `Mat_ C` has finite biproducts.

Be warned, however, that `Mat_ C` is not necessarily Krull-Schmidt,
and so the internal indexing of a biproduct may have nothing to do with the external indexing,
even though the construction we give uses a sigma type.
See however `isoBiproductEmbedding`.
-/
instance hasFiniteBiproducts : HasFiniteBiproducts (Mat_ C) where
  out n :=
    { has_biproduct := fun f =>
        hasBiproduct_of_total
          { pt := ⟨Σ j, (f j).ι, fun p => (f p.1).X p.2⟩
            π := fun j x y => by
              refine' if h : x.1 = j then _ else 0
              refine' if h' : @Eq.ndrec (Fin n) x.1 (fun j => (f j).ι) x.2 _ h = y then _ else 0
              apply eqToHom
              substs h h'
              rfl
            -- Notice we were careful not to use `subst` until we had a goal in `Prop`.
            ι := fun j x y => by
              refine' if h : y.1 = j then _ else 0
              refine' if h' : @Eq.ndrec _ y.1 (fun j => (f j).ι) y.2 _ h = x then _ else 0
              apply eqToHom
              substs h h'
              rfl
            ι_π := fun j j' => by
              ext x y
              dsimp
              simp_rw [dite_comp, comp_dite]
              simp only [ite_self, dite_eq_ite, dif_ctx_congr, Limits.comp_zero, Limits.zero_comp,
                eqToHom_trans, Finset.sum_congr]
              erw [Finset.sum_sigma]
              dsimp
              simp only [if_congr, if_true, dif_ctx_congr, Finset.sum_dite_irrel, Finset.mem_univ,
                Finset.sum_const_zero, Finset.sum_congr, Finset.sum_dite_eq']
              split_ifs with h h'
              · substs h h'
                simp only [CategoryTheory.eqToHom_refl, CategoryTheory.Mat_.id_apply_self]
              · subst h
                rw [eqToHom_refl, id_apply_of_ne _ _ _ h']
              · rfl }
          (by
            

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
n : ℕ
f : Fin n → Mat_ C
⊢ ∑ j : Fin n,
      Bicone.π
          (Bicone.mk (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd)
            (fun j x y =>
              if h : x.fst = j then
                if h' : h ▸ x.snd = y then
                  eqToHom (_ : X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) x = X (f j) y)
                else 0
              else 0)
            fun j x y =>
            if h : y.fst = j then
              if h' : h ▸ y.snd = x then
                eqToHom (_ : X (f j) x = X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) y)
              else 0
            else 0)
          j ≫
        Bicone.ι
          (Bicone.mk (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd)
            (fun j x y =>
              if h : x.fst = j then
                if h' : h ▸ x.snd = y then
                  eqToHom (_ : X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) x = X (f j) y)
                else 0
              else 0)
            fun j x y =>
            if h : y.fst = j then
              if h' : h ▸ y.snd = x then
                eqToHom (_ : X (f j) x = X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) y)
              else 0
            else 0)
          j =
    𝟙
      (Bicone.mk (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd)
          (fun j x y =>
            if h : x.fst = j then
              if h' : h ▸ x.snd = y then
                eqToHom (_ : X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) x = X (f j) y)
              else 0
            else 0)
          fun j x y =>
          if h : y.fst = j then
            if h' : h ▸ y.snd = x then
              eqToHom (_ : X (f j) x = X (mk ((j : Fin n) × (f j).ι) fun p => X (f p.fst) p.snd) y)
            else 0
          else 0).pt

Next tactic:
dsimp