l3lab/ntp-mathlib huggingface dataset:
theorem Set.star_mem_center (ha : a ∈ Set.center R) : star a ∈ Set.center R where
  comm := by simpa only [star_mul, star_star] using fun g =>
    congr_arg star (((Set.mem_center_iff R).mp ha).comm <| star g).symm
  left_assoc b c := calc
    star a * (b * c) = star a * (star (star b) * star (star c)) := by rw [star_star, star_star]
    _ = star a * star (star c * star b) := by rw [star_mul]
    _ = star ((star c * star b) * a) := by rw [← star_mul]
    _ = star (star c * (star b * a)) := by rw [ha.right_assoc]
    _ = star (star b * a) * c := by rw [star_mul, star_star]
    _ = (star a * b) * c := by rw [star_mul, star_star]
  mid_assoc b c := calc
    b * star a * c = star (star c * star (b * star a)) := by rw [← star_mul, star_star]
    _ = star (star c * (a * star b)) := by rw [star_mul b, star_star]
    _ = star ((star c * a) * star b) := by rw [ha.mid_assoc]
    _ = b * (star a * c) := by rw [star_mul, star_star, star_mul (star c), star_star]
  right_assoc b c := calc
    b * c * star a = star (a * star (b * c)) := by rw [star_mul, star_star]
    _ = star (a * (star c * star b)) := by rw [star_mul b]
    _ = star ((a * star c) * star b) := by rw [ha.left_assoc]
    _ = b * star (a * star c) := by 

Proof state:
R : Type u_1
inst✝¹ : Mul R
inst✝ : StarMul R
a : R
s : Set R
ha : a ∈ center R
b c : R
⊢ star (a * star c * star b) = b * star (a * star c)

Next tactic:
rw [star_mul, star_star]
theorem Set.star_mem_center (ha : a ∈ Set.center R) : star a ∈ Set.center R where
  comm := by simpa only [star_mul, star_star] using fun g =>
    congr_arg star (((Set.mem_center_iff R).mp ha).comm <| star g).symm
  left_assoc b c := calc
    star a * (b * c) = star a * (star (star b) * star (star c)) := by rw [star_star, star_star]
    _ = star a * star (star c * star b) := by rw [star_mul]
    _ = star ((star c * star b) * a) := by rw [← star_mul]
    _ = star (star c * (star b * a)) := by rw [ha.right_assoc]
    _ = star (star b * a) * c := by rw [star_mul, star_star]
    _ = (star a * b) * c := by rw [star_mul, star_star]
  mid_assoc b c := calc
    b * star a * c = star (star c * star (b * star a)) := by rw [← star_mul, star_star]
    _ = star (star c * (a * star b)) := by rw [star_mul b, star_star]
    _ = star ((star c * a) * star b) := by rw [ha.mid_assoc]
    _ = b * (star a * c) := by rw [star_mul, star_star, star_mul (star c), star_star]
  right_assoc b c := calc
    b * c * star a = star (a * star (b * c)) := by rw [star_mul, star_star]
    _ = star (a * (star c * star b)) := by rw [star_mul b]
    _ = star ((a * star c) * star b) := by rw [ha.left_assoc]
    _ = b * star (a * star c) := by rw [star_mul, star_star]
    _ = b * (c * star a) := by 

Proof state:
R : Type u_1
inst✝¹ : Mul R
inst✝ : StarMul R
a : R
s : Set R
ha : a ∈ center R
b c : R
⊢ b * star (a * star c) = b * (c * star a)

Next tactic:
rw [star_mul, star_star]
theorem Set.star_mem_centralizer' (h : ∀ a : R, a ∈ s → star a ∈ s) (ha : a ∈ Set.centralizer s) :
    star a ∈ Set.centralizer s := fun y hy => by 

Proof state:
R : Type u_1
inst✝¹ : Mul R
inst✝ : StarMul R
a : R
s : Set R
h : ∀ a ∈ s, star a ∈ s
ha : a ∈ centralizer s
y : R
hy : y ∈ s
⊢ y * star a = star a * y

Next tactic:
simpa using congr_arg star (ha _ (h _ hy)).symm
theorem eq_zero [HasZeroMorphisms C] (o : HomOrthogonal s) {i j : ι} (w : i ≠ j) (f : s i ⟶ s j) :
    f = 0 := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝ : HasZeroMorphisms C
o : HomOrthogonal s
i j : ι
w : i ≠ j
f : s i ⟶ s j
⊢ f = 0

Next tactic:
haveI := o i j w
theorem eq_zero [HasZeroMorphisms C] (o : HomOrthogonal s) {i j : ι} (w : i ≠ j) (f : s i ⟶ s j) :
    f = 0 := by
  haveI := o i j w
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝ : HasZeroMorphisms C
o : HomOrthogonal s
i j : ι
w : i ≠ j
f : s i ⟶ s j
this : Subsingleton (s i ⟶ s j)
⊢ f = 0

Next tactic:
apply Subsingleton.elim
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
i : ι
j : ↑(g ⁻¹' {i})
k : ↑(f ⁻¹' {i})
⊢ s i = s (f ↑k)

Next tactic:
rcases k with ⟨k, ⟨⟩⟩
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          

Proof state:
case mk.refl
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
k : α
j : ↑(g ⁻¹' {f k})
⊢ s (f k) = s (f ↑{ val := k, property := (_ : f k = f k) })

Next tactic:
simp
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
i : ι
j : ↑(g ⁻¹' {i})
k : ↑(f ⁻¹' {i})
⊢ s (g ↑j) = s i

Next tactic:
rcases j with ⟨j, ⟨⟩⟩
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            

Proof state:
case mk.refl
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : ↑(f ⁻¹' {g j})
⊢ s (g ↑{ val := j, property := (_ : g j = g j) }) = s (g j)

Next tactic:
simp
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (i : ι) → Matrix (↑(g ⁻¹' {i})) (↑(f ⁻¹' {i})) (End (s i))
j : α
k : β
h : f j = g k
⊢ k ∈ g ⁻¹' {f j}

Next tactic:
simp [h]
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (i : ι) → Matrix (↑(g ⁻¹' {i})) (↑(f ⁻¹' {i})) (End (s i))
j : α
k : β
h : f j = g k
⊢ j ∈ f ⁻¹' {f j}

Next tactic:
simp
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (i : ι) → Matrix (↑(g ⁻¹' {i})) (↑(f ⁻¹' {i})) (End (s i))
j : α
k : β
h : f j = g k
⊢ s (f j) = s (g k)

Next tactic:
simp [h]
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
⊢ (fun z =>
        biproduct.matrix fun j k =>
          if h : f j = g k then
            z (f j) { val := k, property := (_ : k ∈ g ⁻¹' {f j}) } { val := j, property := (_ : j ∈ f ⁻¹' {f j}) } ≫
              eqToHom (_ : s (f j) = s (g k))
          else 0)
      ((fun z i j k => eqToHom (_ : s i = s (f ↑k)) ≫ biproduct.components z ↑k ↑j ≫ eqToHom (_ : s (g ↑j) = s i)) z) =
    z

Next tactic:
ext j k
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    

Proof state:
case w.w
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
⊢ biproduct.ι (fun a => s (f a)) k ≫
      (fun z =>
            biproduct.matrix fun j k =>
              if h : f j = g k then
                z (f j) { val := k, property := (_ : k ∈ g ⁻¹' {f j}) }
                    { val := j, property := (_ : j ∈ f ⁻¹' {f j}) } ≫
                  eqToHom (_ : s (f j) = s (g k))
              else 0)
          ((fun z i j k => eqToHom (_ : s i = s (f ↑k)) ≫ biproduct.components z ↑k ↑j ≫ eqToHom (_ : s (g ↑j) = s i))
            z) ≫
        biproduct.π (fun b => s (g b)) j =
    biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j

Next tactic:
simp only [biproduct.matrix_π, biproduct.ι_desc]
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    

Proof state:
case w.w
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
⊢ (if h : f k = g j then
      (eqToHom (_ : s (f k) = s (f ↑{ val := k, property := (_ : k ∈ f ⁻¹' {f k}) })) ≫
          biproduct.components z k j ≫ eqToHom (_ : s (g ↑{ val := j, property := (_ : j ∈ g ⁻¹' {f k}) }) = s (f k))) ≫
        eqToHom (_ : s (f k) = s (g j))
    else 0) =
    biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j

Next tactic:
split_ifs with h
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    split_ifs with h
    · 

Proof state:
case pos
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
h : f k = g j
⊢ (eqToHom (_ : s (f k) = s (f ↑{ val := k, property := (_ : k ∈ f ⁻¹' {f k}) })) ≫
        biproduct.components z k j ≫ eqToHom (_ : s (g ↑{ val := j, property := (_ : j ∈ g ⁻¹' {f k}) }) = s (f k))) ≫
      eqToHom (_ : s (f k) = s (g j)) =
    biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j

Next tactic:
simp
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    split_ifs with h
    · simp
      

Proof state:
case pos
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
h : f k = g j
⊢ biproduct.components z k j = biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j

Next tactic:
rfl
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    split_ifs with h
    · simp
      rfl
    · 

Proof state:
case neg
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
h : ¬f k = g j
⊢ 0 = biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j

Next tactic:
symm
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    split_ifs with h
    · simp
      rfl
    · symm
      

Proof state:
case neg
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)
j : β
k : α
h : ¬f k = g j
⊢ biproduct.ι (fun a => s (f a)) k ≫ z ≫ biproduct.π (fun b => s (g b)) j = 0

Next tactic:
apply o.eq_zero h
/-- Morphisms between two direct sums over a hom orthogonal family `s : ι → C`
are equivalent to block diagonal matrices,
with blocks indexed by `ι`,
and matrix entries in `i`-th block living in the endomorphisms of `s i`. -/
@[simps]
noncomputable def matrixDecomposition (o : HomOrthogonal s) {α β : Type} [Fintype α] [Fintype β]
    {f : α → ι} {g : β → ι} :
    ((⨁ fun a => s (f a)) ⟶ ⨁ fun b => s (g b)) ≃
      ∀ i : ι, Matrix (g ⁻¹' {i}) (f ⁻¹' {i}) (End (s i)) where
  toFun z i j k :=
    eqToHom
        (by
          rcases k with ⟨k, ⟨⟩⟩
          simp) ≫
      biproduct.components z k j ≫
        eqToHom
          (by
            rcases j with ⟨j, ⟨⟩⟩
            simp)
  invFun z :=
    biproduct.matrix fun j k =>
      if h : f j = g k then z (f j) ⟨k, by simp [h]⟩ ⟨j, by simp⟩ ≫ eqToHom (by simp [h]) else 0
  left_inv z := by
    ext j k
    simp only [biproduct.matrix_π, biproduct.ι_desc]
    split_ifs with h
    · simp
      rfl
    · symm
      apply o.eq_zero h
  right_inv z := by
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
ι : Type u_1
s : ι → C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteBiproducts C
o : HomOrthogonal s
α β : Type
inst✝¹ : Fintype α
inst✝ : Fintype β
f : α → ι
g : β → ι
z : (i : ι) → Matrix (↑(g ⁻¹' {i})) (↑(f ⁻¹' {i})) (End (s i))
⊢ (fun z i j k => eqToHom (_ : s i = s (f ↑k)) ≫ biproduct.components z ↑k ↑j ≫ eqToHom (_ : s (g ↑j) = s i))
      ((fun z =>
          biproduct.matrix fun j k =>
            if h : f j = g k then
              z (f j) { val := k, property := (_ : k ∈ g ⁻¹' {f j}) } { val := j, property := (_ : j ∈ f ⁻¹' {f j}) } ≫
                eqToHom (_ : s (f j) = s (g k))
            else 0)
        z) =
    z

Next tactic:
ext i ⟨j, w⟩ ⟨k, ⟨⟩⟩