/--
Induce the lawfulness of the monoidal structure along an faithful functor of (plain) categories,
where the operations are already defined on the destination type `D`.

The functor `F` must preserve all the data parts of the monoidal structure between the two
categories.

-/
abbrev induced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    MonoidalCategory.{v₂} D where
  tensorHom_def {X₁ Y₁ X₂ Y₂} f g := F.map_injective <| by
    rw [fData.tensorHom_eq, Functor.map_comp, fData.whiskerRight_eq, fData.whiskerLeft_eq]
    simp only [tensorHom_def, assoc, Iso.hom_inv_id_assoc]
  tensor_id X₁ X₂ := F.map_injective <| by cases fData; aesop_cat
  tensor_comp {X₁ Y₁ Z₁ X₂ Y₂ Z₂} f₁ f₂ g₁ g₂ := F.map_injective <| by cases fData; aesop_cat
  whiskerLeft_id X Y := F.map_injective <| by simp [fData.whiskerLeft_eq]
  id_whiskerRight X Y := F.map_injective <| by simp [fData.whiskerRight_eq]
  triangle X Y := F.map_injective <| by cases fData; aesop_cat
  pentagon W X Y Z := F.map_injective <| by
    simp only [Functor.map_comp, fData.tensorHom_eq, fData.associator_eq, Iso.trans_assoc,
      Iso.trans_hom, Iso.symm_hom, tensorIso_hom, Iso.refl_hom, Functor.map_id, comp_tensor_id,
      associator_conjugation, tensor_id, assoc, id_tensor_comp, Iso.hom_inv_id_assoc,
      tensor_hom_inv_id_assoc, id_comp, hom_inv_id_tensor_assoc, Iso.inv_hom_id_assoc,
      id_tensor_comp_tensor_id_assoc, Iso.cancel_iso_inv_left]
    slice_lhs 6 8 =>
      rw [← id_tensor_comp, hom_inv_id_tensor, tensor_id, comp_id,
        tensor_id]
    simp only [comp_id, assoc, pentagon_assoc, Iso.inv_hom_id_assoc,
      ← associator_naturality_assoc, tensor_id, tensor_id_comp_id_tensor_assoc]
  leftUnitor_naturality {X Y : D} f := F.map_injective <| by
    have := leftUnitor_naturality (F.map f)
    simp only [Functor.map_comp, fData.tensorHom_eq, Functor.map_id, fData.leftUnitor_eq,
      Iso.trans_assoc, Iso.trans_hom, Iso.symm_hom, tensorIso_hom, Iso.refl_hom, assoc,
      Iso.hom_inv_id_assoc, id_tensor_comp_tensor_id_assoc, Iso.cancel_iso_inv_left]
    rw [← this, ← assoc, ← tensor_comp, id_comp, comp_id]
  rightUnitor_naturality {X Y : D} f := F.map_injective <| by
    have := rightUnitor_naturality (F.map f)
    simp only [Functor.map_comp, fData.tensorHom_eq, Functor.map_id, fData.rightUnitor_eq,
      Iso.trans_assoc, Iso.trans_hom, Iso.symm_hom, tensorIso_hom, Iso.refl_hom, assoc,
      Iso.hom_inv_id_assoc, tensor_id_comp_id_tensor_assoc, Iso.cancel_iso_inv_left]
    rw [← this, ← assoc, ← tensor_comp, id_comp, comp_id]
  associator_naturality {X₁ X₂ X₃ Y₁ Y₂ Y₃} f₁ f₂ f₃ := F.map_injective <| by
    have := associator_naturality (F.map f₁) (F.map f₂) (F.map f₃)
    simp [fData.associator_eq, fData.tensorHom_eq]
    simp_rw [← assoc, ← tensor_comp, assoc, Iso.hom_inv_id, ← assoc]
    congr 1
    conv_rhs => rw [← comp_id (F.map f₁), ← id_comp (F.map f₁)]
    

Proof state:
case e_a
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : MonoidalCategory C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
inst✝¹ : MonoidalCategoryStruct D
F : D ⥤ C
inst✝ : Faithful F
fData : InducingFunctorData F
X₁ X₂ X₃ Y₁ Y₂ Y₃ : D
f₁ : X₁ ⟶ Y₁
f₂ : X₂ ⟶ Y₂
f₃ : X₃ ⟶ Y₃
this :
  ((F.map f₁ ⊗ F.map f₂) ⊗ F.map f₃) ≫ (α_ (F.obj Y₁) (F.obj Y₂) (F.obj Y₃)).hom =
    (α_ (F.obj X₁) (F.obj X₂) (F.obj X₃)).hom ≫ (F.map f₁ ⊗ F.map f₂ ⊗ F.map f₃)
⊢ ((((InducingFunctorData.μIso fData X₁ X₂).inv ≫ (F.map f₁ ⊗ F.map f₂)) ≫ 𝟙 (F.obj Y₁ ⊗ F.obj Y₂) ⊗
          F.map f₃ ≫ 𝟙 (F.obj Y₃)) ≫
        (α_ (F.obj Y₁) (F.obj Y₂) (F.obj Y₃)).hom) ≫
      (𝟙 (F.obj Y₁) ⊗ (InducingFunctorData.μIso fData Y₂ Y₃).hom) =
    ((((InducingFunctorData.μIso fData X₁ X₂).inv ⊗ 𝟙 (F.obj X₃)) ≫ (α_ (F.obj X₁) (F.obj X₂) (F.obj X₃)).hom) ≫
        (𝟙 (F.obj X₁) ⊗ (InducingFunctorData.μIso fData X₂ X₃).hom)) ≫
      ((𝟙 (F.obj X₁) ≫ F.map f₁) ≫ 𝟙 (F.obj Y₁) ⊗
        ((InducingFunctorData.μIso fData X₂ X₃).inv ≫ (F.map f₂ ⊗ F.map f₃)) ≫
          (InducingFunctorData.μIso fData Y₂ Y₃).hom)

Next tactic:
simp only [tensor_comp]