l3lab/ntp-mathlib huggingface dataset:
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => 

Proof state:
case a.a.a
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X Y Z : C
| (G.map (μ F X Y) ⊗ 𝟙 (G.obj (F.obj Z))) ≫ μ G (F.obj (X ⊗ Y)) (F.obj Z)
case a.a.a
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X Y Z : C
| G.map (μ F (X ⊗ Y) Z)
case a.a
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X Y Z : C
| G.map (F.map (α_ X Y Z).hom)
case a
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X Y Z : C
| μ G (F.obj X) (F.obj Y) ⊗ 𝟙 (G.obj (F.obj Z))

Next tactic:
rw [← G.toFunctor.map_id, G.μ_natural]
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X Y Z : C
⊢ (μ G (F.obj X) (F.obj Y) ⊗ 𝟙 (G.obj (F.obj Z))) ≫
      ((μ G (F.obj X ⊗ F.obj Y) (F.obj Z) ≫ G.map (μ F X Y ⊗ 𝟙 (F.obj Z))) ≫ G.map (μ F (X ⊗ Y) Z)) ≫
        G.map (F.map (α_ X Y Z).hom) =
    (((μ G (F.obj X) (F.obj Y) ⊗ 𝟙 (G.obj (F.obj Z))) ≫
          μ G (F.obj X ⊗ F.obj Y) (F.obj Z) ≫ G.map (α_ (F.obj X) (F.obj Y) (F.obj Z)).hom) ≫
        G.map (𝟙 (F.obj X) ⊗ μ F Y Z)) ≫
      G.map (μ F X (Y ⊗ Z))

Next tactic:
rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (λ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom =
    (G.ε ≫ G.map F.ε ⊗ 𝟙 ((Functor.mk src✝.toPrefunctor).obj X)) ≫
      (fun X Y => μ G (F.obj X) (F.obj Y) ≫ G.map (μ F X Y)) (𝟙_ C) X ≫ (Functor.mk src✝.toPrefunctor).map (λ_ X).hom

Next tactic:
dsimp
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (λ_ (G.obj (F.obj X))).hom =
    (G.ε ≫ G.map F.ε ⊗ 𝟙 (G.obj (F.obj X))) ≫
      (μ G (F.obj (𝟙_ C)) (F.obj X) ≫ G.map (μ F (𝟙_ C) X)) ≫ G.map (F.map (λ_ X).hom)

Next tactic:
rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (G.ε ⊗ 𝟙 (G.obj (F.obj X))) ≫ μ G (𝟙_ D) (F.obj X) ≫ G.map (λ_ (F.obj X)).hom =
    (G.ε ⊗ 𝟙 (G.obj (F.obj X))) ≫
      (G.map F.ε ⊗ 𝟙 (G.obj (F.obj X))) ≫ μ G (F.obj (𝟙_ C)) (F.obj X) ≫ G.map (μ F (𝟙_ C) X) ≫ G.map (F.map (λ_ X).hom)

Next tactic:
apply congr_arg
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      apply congr_arg
      

Proof state:
case h
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ μ G (𝟙_ D) (F.obj X) ≫ G.map (λ_ (F.obj X)).hom =
    (G.map F.ε ⊗ 𝟙 (G.obj (F.obj X))) ≫ μ G (F.obj (𝟙_ C)) (F.obj X) ≫ G.map (μ F (𝟙_ C) X) ≫ G.map (F.map (λ_ X).hom)

Next tactic:
rw [F.left_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      apply congr_arg
      rw [F.left_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
    right_unitality := fun X => by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (ρ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom =
    (𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ G.ε ≫ G.map F.ε) ≫
      (fun X Y => μ G (F.obj X) (F.obj Y) ≫ G.map (μ F X Y)) X (𝟙_ C) ≫ (Functor.mk src✝.toPrefunctor).map (ρ_ X).hom

Next tactic:
dsimp
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      apply congr_arg
      rw [F.left_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
    right_unitality := fun X => by
      dsimp
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (ρ_ (G.obj (F.obj X))).hom =
    (𝟙 (G.obj (F.obj X)) ⊗ G.ε ≫ G.map F.ε) ≫
      (μ G (F.obj X) (F.obj (𝟙_ C)) ≫ G.map (μ F X (𝟙_ C))) ≫ G.map (F.map (ρ_ X).hom)

Next tactic:
rw [G.right_unitality, id_tensor_comp, Category.assoc, Category.assoc]
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      apply congr_arg
      rw [F.left_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
    right_unitality := fun X => by
      dsimp
      rw [G.right_unitality, id_tensor_comp, Category.assoc, Category.assoc]
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ (𝟙 (G.obj (F.obj X)) ⊗ G.ε) ≫ μ G (F.obj X) (𝟙_ D) ≫ G.map (ρ_ (F.obj X)).hom =
    (𝟙 (G.obj (F.obj X)) ⊗ G.ε) ≫
      (𝟙 (G.obj (F.obj X)) ⊗ G.map F.ε) ≫ μ G (F.obj X) (F.obj (𝟙_ C)) ≫ G.map (μ F X (𝟙_ C)) ≫ G.map (F.map (ρ_ X).hom)

Next tactic:
apply congr_arg
/-- The composition of two lax monoidal functors is again lax monoidal. -/
@[simps]
def comp : LaxMonoidalFunctor.{v₁, v₃} C E :=
  { F.toFunctor ⋙ G.toFunctor with
    ε := G.ε ≫ G.map F.ε
    μ := fun X Y => G.μ (F.obj X) (F.obj Y) ≫ G.map (F.μ X Y)
    μ_natural := @fun _ _ _ _ f g => by
      simp only [Functor.comp_map, assoc]
      rw [← Category.assoc, LaxMonoidalFunctor.μ_natural, Category.assoc, ← map_comp, ← map_comp,
        ← LaxMonoidalFunctor.μ_natural]
    associativity := fun X Y Z => by
      dsimp
      rw [id_tensor_comp]
      slice_rhs 3 4 => rw [← G.toFunctor.map_id, G.μ_natural]
      slice_rhs 1 3 => rw [← G.associativity]
      rw [comp_tensor_id]
      slice_lhs 2 3 => rw [← G.toFunctor.map_id, G.μ_natural]
      rw [Category.assoc, Category.assoc, Category.assoc, Category.assoc, Category.assoc, ←
        G.toFunctor.map_comp, ← G.toFunctor.map_comp, ← G.toFunctor.map_comp, ←
        G.toFunctor.map_comp, F.associativity]
    left_unitality := fun X => by
      dsimp
      rw [G.left_unitality, comp_tensor_id, Category.assoc, Category.assoc]
      apply congr_arg
      rw [F.left_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
    right_unitality := fun X => by
      dsimp
      rw [G.right_unitality, id_tensor_comp, Category.assoc, Category.assoc]
      apply congr_arg
      

Proof state:
case h
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor D E
src✝ : C ⥤ E := F.toFunctor ⋙ G.toFunctor
X : C
⊢ μ G (F.obj X) (𝟙_ D) ≫ G.map (ρ_ (F.obj X)).hom =
    (𝟙 (G.obj (F.obj X)) ⊗ G.map F.ε) ≫ μ G (F.obj X) (F.obj (𝟙_ C)) ≫ G.map (μ F X (𝟙_ C)) ≫ G.map (F.map (ρ_ X).hom)

Next tactic:
rw [F.right_unitality, map_comp, ← NatTrans.id_app, ← Category.assoc, ←
        LaxMonoidalFunctor.μ_natural, NatTrans.id_app, map_id, ← Category.assoc, map_comp]
@[simp]
theorem prod'_ε : (F.prod' G).ε = (F.ε, G.ε) := by
  

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor C E
⊢ (prod' F G).ε = (F.ε, G.ε)

Next tactic:
dsimp [prod']
@[simp]
theorem prod'_ε : (F.prod' G).ε = (F.ε, G.ε) := by
  dsimp [prod']
  

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor C E
⊢ (F.ε ≫ F.map (𝟙 (𝟙_ C)), G.ε ≫ G.map (𝟙 (𝟙_ C))) = (F.ε, G.ε)

Next tactic:
simp
@[simp]
theorem prod'_μ (X Y : C) : (F.prod' G).μ X Y = (F.μ X Y, G.μ X Y) := by
  

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor C E
X Y : C
⊢ μ (prod' F G) X Y = (μ F X Y, μ G X Y)

Next tactic:
dsimp [prod']
@[simp]
theorem prod'_μ (X Y : C) : (F.prod' G).μ X Y = (F.μ X Y, G.μ X Y) := by
  dsimp [prod']
  

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : LaxMonoidalFunctor C D
G : LaxMonoidalFunctor C E
X Y : C
⊢ (μ F X Y ≫ F.map (𝟙 (X ⊗ Y)), μ G X Y ≫ G.map (𝟙 (X ⊗ Y))) = (μ F X Y, μ G X Y)

Next tactic:
simp
/-- The composition of two monoidal functors is again monoidal. -/
@[simps]
def comp : MonoidalFunctor.{v₁, v₃} C E :=
  {
    F.toLaxMonoidalFunctor.comp
      G.toLaxMonoidalFunctor with
    ε_isIso := by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : MonoidalFunctor C D
G : MonoidalFunctor D E
src✝ : LaxMonoidalFunctor C E := F.toLaxMonoidalFunctor ⊗⋙ G.toLaxMonoidalFunctor
⊢ IsIso (LaxMonoidalFunctor.mk src✝.toFunctor src✝.ε src✝.μ).ε

Next tactic:
dsimp
/-- The composition of two monoidal functors is again monoidal. -/
@[simps]
def comp : MonoidalFunctor.{v₁, v₃} C E :=
  {
    F.toLaxMonoidalFunctor.comp
      G.toLaxMonoidalFunctor with
    ε_isIso := by
      dsimp
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : MonoidalFunctor C D
G : MonoidalFunctor D E
src✝ : LaxMonoidalFunctor C E := F.toLaxMonoidalFunctor ⊗⋙ G.toLaxMonoidalFunctor
⊢ IsIso (G.ε ≫ G.map F.ε)

Next tactic:
infer_instance
/-- The composition of two monoidal functors is again monoidal. -/
@[simps]
def comp : MonoidalFunctor.{v₁, v₃} C E :=
  {
    F.toLaxMonoidalFunctor.comp
      G.toLaxMonoidalFunctor with
    ε_isIso := by
      dsimp
      infer_instance
    μ_isIso := by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : MonoidalFunctor C D
G : MonoidalFunctor D E
src✝ : LaxMonoidalFunctor C E := F.toLaxMonoidalFunctor ⊗⋙ G.toLaxMonoidalFunctor
⊢ ∀ (X Y : C), IsIso (LaxMonoidalFunctor.μ (LaxMonoidalFunctor.mk src✝.toFunctor src✝.ε src✝.μ) X Y)

Next tactic:
dsimp
/-- The composition of two monoidal functors is again monoidal. -/
@[simps]
def comp : MonoidalFunctor.{v₁, v₃} C E :=
  {
    F.toLaxMonoidalFunctor.comp
      G.toLaxMonoidalFunctor with
    ε_isIso := by
      dsimp
      infer_instance
    μ_isIso := by
      dsimp
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : MonoidalCategory C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
inst✝² : MonoidalCategory D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
inst✝ : MonoidalCategory E
F : MonoidalFunctor C D
G : MonoidalFunctor D E
src✝ : LaxMonoidalFunctor C E := F.toLaxMonoidalFunctor ⊗⋙ G.toLaxMonoidalFunctor
⊢ ∀ (X Y : C),
    IsIso
      (LaxMonoidalFunctor.μ G.toLaxMonoidalFunctor (F.obj X) (F.obj Y) ≫
        G.map (LaxMonoidalFunctor.μ F.toLaxMonoidalFunctor X Y))

Next tactic:
infer_instance