l3lab/ntp-mathlib huggingface dataset:
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => 

Proof state:
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| ((𝟙 R.X ⊗ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))) ⊗ 𝟙 T.X) ≫
    (α_ R.X (coequalizer (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))) T.X).hom
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| 𝟙 R.X ⊗ actRight P Q
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| actLeft P Q

Next tactic:
erw [associator_naturality]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
⊢ ((α_ R.X P.X Q.X).inv ⊗ 𝟙 T.X) ≫
      (α_ (R.X ⊗ P.X) Q.X T.X).hom ≫
        (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) =
    (((α_ R.X (P.X ⊗ Q.X) T.X).hom ≫
          (𝟙 R.X ⊗ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) ⊗ 𝟙 T.X)) ≫
        (𝟙 R.X ⊗ actRight P Q)) ≫
      actLeft P Q

Next tactic:
slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => 

Proof state:
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (𝟙 R.X ⊗ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) ⊗ 𝟙 T.X) ≫
    (𝟙 R.X ⊗ actRight P Q)
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| actLeft P Q
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (α_ R.X (P.X ⊗ Q.X) T.X).hom

Next tactic:
rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
⊢ ((α_ R.X P.X Q.X).inv ⊗ 𝟙 T.X) ≫
      (α_ (R.X ⊗ P.X) Q.X T.X).hom ≫
        (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) =
    (α_ R.X (P.X ⊗ Q.X) T.X).hom ≫
      ((𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom) ≫
          (𝟙 R.X ⊗ 𝟙 P.X ⊗ Q.actRight) ≫
            (𝟙 R.X ⊗ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)))) ≫
        actLeft P Q

Next tactic:
slice_rhs 4 5 => rw [id_tensor_π_actLeft]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => 

Proof state:
case a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (𝟙 R.X ⊗ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))) ≫ actLeft P Q
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (α_ R.X (P.X ⊗ Q.X) T.X).hom
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| 𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom
case a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| 𝟙 R.X ⊗ 𝟙 P.X ⊗ Q.actRight

Next tactic:
rw [id_tensor_π_actLeft]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => rw [id_tensor_π_actLeft]
  

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
⊢ ((α_ R.X P.X Q.X).inv ⊗ 𝟙 T.X) ≫
      (α_ (R.X ⊗ P.X) Q.X T.X).hom ≫
        (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) =
    (α_ R.X (P.X ⊗ Q.X) T.X).hom ≫
      (𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom) ≫
        (𝟙 R.X ⊗ 𝟙 P.X ⊗ Q.actRight) ≫
          (α_ R.X P.X Q.X).inv ≫
            (P.actLeft ⊗ 𝟙 Q.X) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))

Next tactic:
slice_rhs 3 4 => rw [associator_inv_naturality]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => rw [id_tensor_π_actLeft]
  slice_rhs 3 4 => 

Proof state:
case a.a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (𝟙 R.X ⊗ 𝟙 P.X ⊗ Q.actRight) ≫ (α_ R.X P.X Q.X).inv
case a.a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| P.actLeft ⊗ 𝟙 Q.X
case a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (α_ R.X (P.X ⊗ Q.X) T.X).hom
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| 𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom

Next tactic:
rw [associator_inv_naturality]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => rw [id_tensor_π_actLeft]
  slice_rhs 3 4 => rw [associator_inv_naturality]
  

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
⊢ ((α_ R.X P.X Q.X).inv ⊗ 𝟙 T.X) ≫
      (α_ (R.X ⊗ P.X) Q.X T.X).hom ≫
        (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) =
    (α_ R.X (P.X ⊗ Q.X) T.X).hom ≫
      (𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom) ≫
        (((α_ R.X P.X (Q.X ⊗ T.X)).inv ≫ ((𝟙 R.X ⊗ 𝟙 P.X) ⊗ Q.actRight)) ≫ (P.actLeft ⊗ 𝟙 Q.X)) ≫
          coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))

Next tactic:
slice_rhs 4 5 => rw [MonoidalCategory.tensor_id, id_tensor_comp_tensor_id]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => rw [id_tensor_π_actLeft]
  slice_rhs 3 4 => rw [associator_inv_naturality]
  slice_rhs 4 5 => 

Proof state:
case a.a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| ((𝟙 R.X ⊗ 𝟙 P.X) ⊗ Q.actRight) ≫ (P.actLeft ⊗ 𝟙 Q.X)
case a.a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (α_ R.X (P.X ⊗ Q.X) T.X).hom
case a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| 𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom
case a.a.a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
| (α_ R.X P.X (Q.X ⊗ T.X)).inv

Next tactic:
rw [MonoidalCategory.tensor_id, id_tensor_comp_tensor_id]
theorem middle_assoc' :
    (actLeft P Q ⊗ 𝟙 T.X) ≫ actRight P Q =
      (α_ R.X _ T.X).hom ≫ (𝟙 R.X ⊗ actRight P Q) ≫ actLeft P Q := by
  refine' (cancel_epi ((tensorLeft _ ⋙ tensorRight _).map (coequalizer.π _ _))).1 _
  dsimp [X]
  slice_lhs 1 2 => rw [← comp_tensor_id, id_tensor_π_actLeft, comp_tensor_id, comp_tensor_id]
  slice_lhs 3 4 => rw [π_tensor_id_actRight]
  slice_lhs 2 3 => rw [associator_naturality]
  slice_lhs 3 4 => rw [MonoidalCategory.tensor_id, tensor_id_comp_id_tensor]
  -- porting note: had to replace `rw` by `erw`
  slice_rhs 1 2 => erw [associator_naturality]
  slice_rhs 2 3 => rw [← id_tensor_comp, π_tensor_id_actRight, id_tensor_comp, id_tensor_comp]
  slice_rhs 4 5 => rw [id_tensor_π_actLeft]
  slice_rhs 3 4 => rw [associator_inv_naturality]
  slice_rhs 4 5 => rw [MonoidalCategory.tensor_id, id_tensor_comp_tensor_id]
  

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
R S T : Mon_ C
P : Bimod R S
Q : Bimod S T
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
⊢ ((α_ R.X P.X Q.X).inv ⊗ 𝟙 T.X) ≫
      (α_ (R.X ⊗ P.X) Q.X T.X).hom ≫
        (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft)) =
    (α_ R.X (P.X ⊗ Q.X) T.X).hom ≫
      (𝟙 R.X ⊗ (α_ P.X Q.X T.X).hom) ≫
        (α_ R.X P.X (Q.X ⊗ T.X)).inv ≫
          (P.actLeft ⊗ Q.actRight) ≫ coequalizer.π (P.actRight ⊗ 𝟙 Q.X) ((α_ P.X S.X Q.X).hom ≫ (𝟙 P.X ⊗ Q.actLeft))

Next tactic:
coherence
/-- Tensor product of two morphisms of bimodule objects. -/
@[simps]
noncomputable def tensorHom {X Y Z : Mon_ C} {M₁ M₂ : Bimod X Y} {N₁ N₂ : Bimod Y Z} (f : M₁ ⟶ M₂)
    (g : N₁ ⟶ N₂) : M₁.tensorBimod N₁ ⟶ M₂.tensorBimod N₂ where
  hom :=
    colimMap
      (parallelPairHom _ _ _ _ ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) (f.hom ⊗ g.hom)
        (by
          

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
X Y Z : Mon_ C
M₁ M₂ : Bimod X Y
N₁ N₂ : Bimod Y Z
f : M₁ ⟶ M₂
g : N₁ ⟶ N₂
⊢ (M₁.actRight ⊗ 𝟙 N₁.X) ≫ (f.hom ⊗ g.hom) = ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) ≫ (M₂.actRight ⊗ 𝟙 N₂.X)

Next tactic:
rw [← tensor_comp, ← tensor_comp, Hom.right_act_hom, Category.id_comp, Category.comp_id]
/-- Tensor product of two morphisms of bimodule objects. -/
@[simps]
noncomputable def tensorHom {X Y Z : Mon_ C} {M₁ M₂ : Bimod X Y} {N₁ N₂ : Bimod Y Z} (f : M₁ ⟶ M₂)
    (g : N₁ ⟶ N₂) : M₁.tensorBimod N₁ ⟶ M₂.tensorBimod N₂ where
  hom :=
    colimMap
      (parallelPairHom _ _ _ _ ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) (f.hom ⊗ g.hom)
        (by
          rw [← tensor_comp, ← tensor_comp, Hom.right_act_hom, Category.id_comp, Category.comp_id])
        (by
          

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
X Y Z : Mon_ C
M₁ M₂ : Bimod X Y
N₁ N₂ : Bimod Y Z
f : M₁ ⟶ M₂
g : N₁ ⟶ N₂
⊢ ((α_ M₁.X Y.X N₁.X).hom ≫ (𝟙 M₁.X ⊗ N₁.actLeft)) ≫ (f.hom ⊗ g.hom) =
    ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) ≫ (α_ M₂.X Y.X N₂.X).hom ≫ (𝟙 M₂.X ⊗ N₂.actLeft)

Next tactic:
slice_lhs 2 3 => rw [← tensor_comp, Hom.left_act_hom, Category.id_comp]
/-- Tensor product of two morphisms of bimodule objects. -/
@[simps]
noncomputable def tensorHom {X Y Z : Mon_ C} {M₁ M₂ : Bimod X Y} {N₁ N₂ : Bimod Y Z} (f : M₁ ⟶ M₂)
    (g : N₁ ⟶ N₂) : M₁.tensorBimod N₁ ⟶ M₂.tensorBimod N₂ where
  hom :=
    colimMap
      (parallelPairHom _ _ _ _ ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) (f.hom ⊗ g.hom)
        (by
          rw [← tensor_comp, ← tensor_comp, Hom.right_act_hom, Category.id_comp, Category.comp_id])
        (by
          slice_lhs 2 3 => 

Proof state:
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
X Y Z : Mon_ C
M₁ M₂ : Bimod X Y
N₁ N₂ : Bimod Y Z
f : M₁ ⟶ M₂
g : N₁ ⟶ N₂
| (𝟙 M₁.X ⊗ N₁.actLeft) ≫ (f.hom ⊗ g.hom)
case a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
X Y Z : Mon_ C
M₁ M₂ : Bimod X Y
N₁ N₂ : Bimod Y Z
f : M₁ ⟶ M₂
g : N₁ ⟶ N₂
| (α_ M₁.X Y.X N₁.X).hom

Next tactic:
rw [← tensor_comp, Hom.left_act_hom, Category.id_comp]
/-- Tensor product of two morphisms of bimodule objects. -/
@[simps]
noncomputable def tensorHom {X Y Z : Mon_ C} {M₁ M₂ : Bimod X Y} {N₁ N₂ : Bimod Y Z} (f : M₁ ⟶ M₂)
    (g : N₁ ⟶ N₂) : M₁.tensorBimod N₁ ⟶ M₂.tensorBimod N₂ where
  hom :=
    colimMap
      (parallelPairHom _ _ _ _ ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) (f.hom ⊗ g.hom)
        (by
          rw [← tensor_comp, ← tensor_comp, Hom.right_act_hom, Category.id_comp, Category.comp_id])
        (by
          slice_lhs 2 3 => rw [← tensor_comp, Hom.left_act_hom, Category.id_comp]
          

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
A B : Mon_ C
M : Bimod A B
inst✝² : HasCoequalizers C
inst✝¹ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorLeft X)
inst✝ : (X : C) → PreservesColimitsOfSize.{0, 0, v₁, v₁, u₁, u₁} (tensorRight X)
X Y Z : Mon_ C
M₁ M₂ : Bimod X Y
N₁ N₂ : Bimod Y Z
f : M₁ ⟶ M₂
g : N₁ ⟶ N₂
⊢ (α_ M₁.X Y.X N₁.X).hom ≫ (f.hom ⊗ (𝟙 Y.X ⊗ g.hom) ≫ N₂.actLeft) =
    ((f.hom ⊗ 𝟙 Y.X) ⊗ g.hom) ≫ (α_ M₂.X Y.X N₂.X).hom ≫ (𝟙 M₂.X ⊗ N₂.actLeft)

Next tactic:
slice_rhs 1 2 => rw [associator_naturality]