l3lab/ntp-mathlib huggingface dataset:
/--
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 

Proof state:
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 Y : D
⊢ F.map ((α_ X (𝟙_ D) Y).hom ≫ (𝟙 X ⊗ (λ_ Y).hom)) = F.map ((ρ_ X).hom ⊗ 𝟙 Y)

Next tactic:
cases fData
/--
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; 

Proof state:
case mk
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
X Y : D
μIso✝ : (X Y : D) → F.obj X ⊗ F.obj Y ≅ F.obj (X ⊗ Y)
whiskerLeft_eq✝ :
  ∀ (X : D) {Y₁ Y₂ : D} (f : Y₁ ⟶ Y₂), F.map (X ◁ f) = (μIso✝ X Y₁).inv ≫ F.obj X ◁ F.map f ≫ (μIso✝ X Y₂).hom
whiskerRight_eq✝ :
  ∀ {X₁ X₂ : D} (f : X₁ ⟶ X₂) (Y : D), F.map (f ▷ Y) = (μIso✝ X₁ Y).inv ≫ F.map f ▷ F.obj Y ≫ (μIso✝ X₂ Y).hom
tensorHom_eq✝ :
  ∀ {X₁ Y₁ X₂ Y₂ : D} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂),
    F.map (f ⊗ g) = (μIso✝ X₁ X₂).inv ≫ (F.map f ⊗ F.map g) ≫ (μIso✝ Y₁ Y₂).hom
εIso✝ : 𝟙_ C ≅ F.obj (𝟙_ D)
associator_eq✝ :
  ∀ (X Y Z : D),
    F.map (α_ X Y Z).hom =
      (((μIso✝ (X ⊗ Y) Z).symm ≪≫ ((μIso✝ X Y).symm ⊗ Iso.refl (F.obj Z))) ≪≫
          α_ (F.obj X) (F.obj Y) (F.obj Z) ≪≫ (Iso.refl (F.obj X) ⊗ μIso✝ Y Z) ≪≫ μIso✝ X (Y ⊗ Z)).hom
leftUnitor_eq✝ :
  ∀ (X : D), F.map (λ_ X).hom = (((μIso✝ (𝟙_ D) X).symm ≪≫ (εIso✝.symm ⊗ Iso.refl (F.obj X))) ≪≫ λ_ (F.obj X)).hom
rightUnitor_eq✝ :
  ∀ (X : D), F.map (ρ_ X).hom = (((μIso✝ X (𝟙_ D)).symm ≪≫ (Iso.refl (F.obj X) ⊗ εIso✝.symm)) ≪≫ ρ_ (F.obj X)).hom
⊢ F.map ((α_ X (𝟙_ D) Y).hom ≫ (𝟙 X ⊗ (λ_ Y).hom)) = F.map ((ρ_ X).hom ⊗ 𝟙 Y)

Next tactic:
aesop_cat
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by 

Proof state:
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
this : MonoidalCategory D := induced F fData
⊢ ∀ {X Y X' Y' : D} (f : X ⟶ Y) (g : X' ⟶ Y'),
    (F.map f ⊗ F.map g) ≫ (fun X Y => (InducingFunctorData.μIso fData X Y).hom) Y Y' =
      (fun X Y => (InducingFunctorData.μIso fData X Y).hom) X X' ≫ F.map (f ⊗ g)

Next tactic:
cases fData
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; 

Proof state:
case mk
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
μIso✝ : (X Y : D) → F.obj X ⊗ F.obj Y ≅ F.obj (X ⊗ Y)
whiskerLeft_eq✝ :
  ∀ (X : D) {Y₁ Y₂ : D} (f : Y₁ ⟶ Y₂), F.map (X ◁ f) = (μIso✝ X Y₁).inv ≫ F.obj X ◁ F.map f ≫ (μIso✝ X Y₂).hom
whiskerRight_eq✝ :
  ∀ {X₁ X₂ : D} (f : X₁ ⟶ X₂) (Y : D), F.map (f ▷ Y) = (μIso✝ X₁ Y).inv ≫ F.map f ▷ F.obj Y ≫ (μIso✝ X₂ Y).hom
tensorHom_eq✝ :
  ∀ {X₁ Y₁ X₂ Y₂ : D} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂),
    F.map (f ⊗ g) = (μIso✝ X₁ X₂).inv ≫ (F.map f ⊗ F.map g) ≫ (μIso✝ Y₁ Y₂).hom
εIso✝ : 𝟙_ C ≅ F.obj (𝟙_ D)
associator_eq✝ :
  ∀ (X Y Z : D),
    F.map (α_ X Y Z).hom =
      (((μIso✝ (X ⊗ Y) Z).symm ≪≫ ((μIso✝ X Y).symm ⊗ Iso.refl (F.obj Z))) ≪≫
          α_ (F.obj X) (F.obj Y) (F.obj Z) ≪≫ (Iso.refl (F.obj X) ⊗ μIso✝ Y Z) ≪≫ μIso✝ X (Y ⊗ Z)).hom
leftUnitor_eq✝ :
  ∀ (X : D), F.map (λ_ X).hom = (((μIso✝ (𝟙_ D) X).symm ≪≫ (εIso✝.symm ⊗ Iso.refl (F.obj X))) ≪≫ λ_ (F.obj X)).hom
rightUnitor_eq✝ :
  ∀ (X : D), F.map (ρ_ X).hom = (((μIso✝ X (𝟙_ D)).symm ≪≫ (Iso.refl (F.obj X) ⊗ εIso✝.symm)) ≪≫ ρ_ (F.obj X)).hom
this : MonoidalCategory D := induced F (InducingFunctorData.mk μIso✝ εIso✝)
⊢ ∀ {X Y X' Y' : D} (f : X ⟶ Y) (g : X' ⟶ Y'),
    (F.map f ⊗ F.map g) ≫ (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) Y Y' =
      (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) X X' ≫ F.map (f ⊗ g)

Next tactic:
aesop_cat
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by 

Proof state:
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
this : MonoidalCategory D := induced F fData
⊢ ∀ (X Y Z : D),
    ((fun X Y => (InducingFunctorData.μIso fData X Y).hom) X Y ⊗ 𝟙 (F.obj Z)) ≫
        (fun X Y => (InducingFunctorData.μIso fData X Y).hom) (X ⊗ Y) Z ≫ F.map (α_ X Y Z).hom =
      (α_ (F.obj X) (F.obj Y) (F.obj Z)).hom ≫
        (𝟙 (F.obj X) ⊗ (fun X Y => (InducingFunctorData.μIso fData X Y).hom) Y Z) ≫
          (fun X Y => (InducingFunctorData.μIso fData X Y).hom) X (Y ⊗ Z)

Next tactic:
cases fData
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by cases fData; 

Proof state:
case mk
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
μIso✝ : (X Y : D) → F.obj X ⊗ F.obj Y ≅ F.obj (X ⊗ Y)
whiskerLeft_eq✝ :
  ∀ (X : D) {Y₁ Y₂ : D} (f : Y₁ ⟶ Y₂), F.map (X ◁ f) = (μIso✝ X Y₁).inv ≫ F.obj X ◁ F.map f ≫ (μIso✝ X Y₂).hom
whiskerRight_eq✝ :
  ∀ {X₁ X₂ : D} (f : X₁ ⟶ X₂) (Y : D), F.map (f ▷ Y) = (μIso✝ X₁ Y).inv ≫ F.map f ▷ F.obj Y ≫ (μIso✝ X₂ Y).hom
tensorHom_eq✝ :
  ∀ {X₁ Y₁ X₂ Y₂ : D} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂),
    F.map (f ⊗ g) = (μIso✝ X₁ X₂).inv ≫ (F.map f ⊗ F.map g) ≫ (μIso✝ Y₁ Y₂).hom
εIso✝ : 𝟙_ C ≅ F.obj (𝟙_ D)
associator_eq✝ :
  ∀ (X Y Z : D),
    F.map (α_ X Y Z).hom =
      (((μIso✝ (X ⊗ Y) Z).symm ≪≫ ((μIso✝ X Y).symm ⊗ Iso.refl (F.obj Z))) ≪≫
          α_ (F.obj X) (F.obj Y) (F.obj Z) ≪≫ (Iso.refl (F.obj X) ⊗ μIso✝ Y Z) ≪≫ μIso✝ X (Y ⊗ Z)).hom
leftUnitor_eq✝ :
  ∀ (X : D), F.map (λ_ X).hom = (((μIso✝ (𝟙_ D) X).symm ≪≫ (εIso✝.symm ⊗ Iso.refl (F.obj X))) ≪≫ λ_ (F.obj X)).hom
rightUnitor_eq✝ :
  ∀ (X : D), F.map (ρ_ X).hom = (((μIso✝ X (𝟙_ D)).symm ≪≫ (Iso.refl (F.obj X) ⊗ εIso✝.symm)) ≪≫ ρ_ (F.obj X)).hom
this : MonoidalCategory D := induced F (InducingFunctorData.mk μIso✝ εIso✝)
⊢ ∀ (X Y Z : D),
    ((fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) X Y ⊗ 𝟙 (F.obj Z)) ≫
        (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) (X ⊗ Y) Z ≫
          F.map (α_ X Y Z).hom =
      (α_ (F.obj X) (F.obj Y) (F.obj Z)).hom ≫
        (𝟙 (F.obj X) ⊗ (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) Y Z) ≫
          (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) X (Y ⊗ Z)

Next tactic:
aesop_cat
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by cases fData; aesop_cat
    left_unitality := by 

Proof state:
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
this : MonoidalCategory D := induced F fData
⊢ ∀ (X : D),
    (λ_ (F.obj X)).hom =
      (fData.εIso.hom ⊗ 𝟙 (F.obj X)) ≫ (fun X Y => (InducingFunctorData.μIso fData X Y).hom) (𝟙_ D) X ≫ F.map (λ_ X).hom

Next tactic:
cases fData
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by cases fData; aesop_cat
    left_unitality := by cases fData; 

Proof state:
case mk
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
μIso✝ : (X Y : D) → F.obj X ⊗ F.obj Y ≅ F.obj (X ⊗ Y)
whiskerLeft_eq✝ :
  ∀ (X : D) {Y₁ Y₂ : D} (f : Y₁ ⟶ Y₂), F.map (X ◁ f) = (μIso✝ X Y₁).inv ≫ F.obj X ◁ F.map f ≫ (μIso✝ X Y₂).hom
whiskerRight_eq✝ :
  ∀ {X₁ X₂ : D} (f : X₁ ⟶ X₂) (Y : D), F.map (f ▷ Y) = (μIso✝ X₁ Y).inv ≫ F.map f ▷ F.obj Y ≫ (μIso✝ X₂ Y).hom
tensorHom_eq✝ :
  ∀ {X₁ Y₁ X₂ Y₂ : D} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂),
    F.map (f ⊗ g) = (μIso✝ X₁ X₂).inv ≫ (F.map f ⊗ F.map g) ≫ (μIso✝ Y₁ Y₂).hom
εIso✝ : 𝟙_ C ≅ F.obj (𝟙_ D)
associator_eq✝ :
  ∀ (X Y Z : D),
    F.map (α_ X Y Z).hom =
      (((μIso✝ (X ⊗ Y) Z).symm ≪≫ ((μIso✝ X Y).symm ⊗ Iso.refl (F.obj Z))) ≪≫
          α_ (F.obj X) (F.obj Y) (F.obj Z) ≪≫ (Iso.refl (F.obj X) ⊗ μIso✝ Y Z) ≪≫ μIso✝ X (Y ⊗ Z)).hom
leftUnitor_eq✝ :
  ∀ (X : D), F.map (λ_ X).hom = (((μIso✝ (𝟙_ D) X).symm ≪≫ (εIso✝.symm ⊗ Iso.refl (F.obj X))) ≪≫ λ_ (F.obj X)).hom
rightUnitor_eq✝ :
  ∀ (X : D), F.map (ρ_ X).hom = (((μIso✝ X (𝟙_ D)).symm ≪≫ (Iso.refl (F.obj X) ⊗ εIso✝.symm)) ≪≫ ρ_ (F.obj X)).hom
this : MonoidalCategory D := induced F (InducingFunctorData.mk μIso✝ εIso✝)
⊢ ∀ (X : D),
    (λ_ (F.obj X)).hom =
      ((InducingFunctorData.mk μIso✝ εIso✝).εIso.hom ⊗ 𝟙 (F.obj X)) ≫
        (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) (𝟙_ D) X ≫ F.map (λ_ X).hom

Next tactic:
aesop_cat
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by cases fData; aesop_cat
    left_unitality := by cases fData; aesop_cat
    right_unitality := by 

Proof state:
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
this : MonoidalCategory D := induced F fData
⊢ ∀ (X : D),
    (ρ_ (F.obj X)).hom =
      (𝟙 (F.obj X) ⊗ fData.εIso.hom) ≫ (fun X Y => (InducingFunctorData.μIso fData X Y).hom) X (𝟙_ D) ≫ F.map (ρ_ X).hom

Next tactic:
cases fData
/--
We can upgrade `F` to a monoidal functor from `D` to `E` with the induced structure.
-/
@[simps]
def fromInduced [MonoidalCategoryStruct D] (F : D ⥤ C) [Faithful F]
    (fData : InducingFunctorData F) :
    letI := induced F fData
    MonoidalFunctor D C :=
  letI := induced F fData
  { toFunctor := F
    ε := fData.εIso.hom
    μ := fun X Y => (fData.μIso X Y).hom
    μ_natural := by cases fData; aesop_cat
    associativity := by cases fData; aesop_cat
    left_unitality := by cases fData; aesop_cat
    right_unitality := by cases fData; 

Proof state:
case mk
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
μIso✝ : (X Y : D) → F.obj X ⊗ F.obj Y ≅ F.obj (X ⊗ Y)
whiskerLeft_eq✝ :
  ∀ (X : D) {Y₁ Y₂ : D} (f : Y₁ ⟶ Y₂), F.map (X ◁ f) = (μIso✝ X Y₁).inv ≫ F.obj X ◁ F.map f ≫ (μIso✝ X Y₂).hom
whiskerRight_eq✝ :
  ∀ {X₁ X₂ : D} (f : X₁ ⟶ X₂) (Y : D), F.map (f ▷ Y) = (μIso✝ X₁ Y).inv ≫ F.map f ▷ F.obj Y ≫ (μIso✝ X₂ Y).hom
tensorHom_eq✝ :
  ∀ {X₁ Y₁ X₂ Y₂ : D} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂),
    F.map (f ⊗ g) = (μIso✝ X₁ X₂).inv ≫ (F.map f ⊗ F.map g) ≫ (μIso✝ Y₁ Y₂).hom
εIso✝ : 𝟙_ C ≅ F.obj (𝟙_ D)
associator_eq✝ :
  ∀ (X Y Z : D),
    F.map (α_ X Y Z).hom =
      (((μIso✝ (X ⊗ Y) Z).symm ≪≫ ((μIso✝ X Y).symm ⊗ Iso.refl (F.obj Z))) ≪≫
          α_ (F.obj X) (F.obj Y) (F.obj Z) ≪≫ (Iso.refl (F.obj X) ⊗ μIso✝ Y Z) ≪≫ μIso✝ X (Y ⊗ Z)).hom
leftUnitor_eq✝ :
  ∀ (X : D), F.map (λ_ X).hom = (((μIso✝ (𝟙_ D) X).symm ≪≫ (εIso✝.symm ⊗ Iso.refl (F.obj X))) ≪≫ λ_ (F.obj X)).hom
rightUnitor_eq✝ :
  ∀ (X : D), F.map (ρ_ X).hom = (((μIso✝ X (𝟙_ D)).symm ≪≫ (Iso.refl (F.obj X) ⊗ εIso✝.symm)) ≪≫ ρ_ (F.obj X)).hom
this : MonoidalCategory D := induced F (InducingFunctorData.mk μIso✝ εIso✝)
⊢ ∀ (X : D),
    (ρ_ (F.obj X)).hom =
      (𝟙 (F.obj X) ⊗ (InducingFunctorData.mk μIso✝ εIso✝).εIso.hom) ≫
        (fun X Y => (InducingFunctorData.μIso (InducingFunctorData.mk μIso✝ εIso✝) X Y).hom) X (𝟙_ D) ≫ F.map (ρ_ X).hom

Next tactic:
aesop_cat
/-- We can upgrade `e.inverse` to a monoidal functor from `D` with the transported structure to `C`.
-/
@[simps!]
def fromTransported (e : C ≌ D) : MonoidalFunctor (Transported e) C := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ MonoidalFunctor (Transported e) C

Next tactic:
dsimp only [transport, Transported.instMonoidalCategory]
/-- We can upgrade `e.inverse` to a monoidal functor from `D` with the transported structure to `C`.
-/
@[simps!]
def fromTransported (e : C ≌ D) : MonoidalFunctor (Transported e) C := by
  dsimp only [transport, Transported.instMonoidalCategory]
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ MonoidalFunctor (Transported e) C

Next tactic:
exact fromInduced (D := Transported e) e.inverse _
instance instIsEquivalence_fromTransported (e : C ≌ D) :
    IsEquivalence (fromTransported e).toFunctor := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ IsEquivalence (fromTransported e).toLaxMonoidalFunctor.toFunctor

Next tactic:
dsimp [fromTransported]
instance instIsEquivalence_fromTransported (e : C ≌ D) :
    IsEquivalence (fromTransported e).toFunctor := by
  dsimp [fromTransported]
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ IsEquivalence e.inverse

Next tactic:
infer_instance
instance (e : C ≌ D) : IsEquivalence (toTransported e).toFunctor := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ IsEquivalence (toTransported e).toLaxMonoidalFunctor.toFunctor

Next tactic:
dsimp [toTransported]
instance (e : C ≌ D) : IsEquivalence (toTransported e).toFunctor := by
  dsimp [toTransported]
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : MonoidalCategory C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
⊢ IsEquivalence (Functor.asEquivalence e.inverse).inverse

Next tactic:
infer_instance
theorem henstock_le_riemann : Henstock ≤ Riemann := by 

Proof state:
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
⊢ Henstock ≤ Riemann

Next tactic:
trivial
theorem henstock_le_mcShane : Henstock ≤ McShane := by 

Proof state:
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
⊢ Henstock ≤ McShane

Next tactic:
trivial
theorem rCond_of_bRiemann_eq_false {ι} (l : IntegrationParams) (hl : l.bRiemann = false)
    {r : (ι → ℝ) → Ioi (0 : ℝ)} : l.RCond r := by
  

Proof state:
ι✝ : Type u_1
inst✝ : Fintype ι✝
I J : Box ι✝
c c₁ c₂ : ℝ≥0
r✝ r₁ r₂ : (ι✝ → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l✝ l₁ l₂ : IntegrationParams
ι : Type u_2
l : IntegrationParams
hl : l.bRiemann = false
r : (ι → ℝ) → ↑(Set.Ioi 0)
⊢ RCond l r

Next tactic:
simp [RCond, hl]
theorem MemBaseSet.exists_common_compl (h₁ : l.MemBaseSet I c₁ r₁ π₁) (h₂ : l.MemBaseSet I c₂ r₂ π₂)
    (hU : π₁.iUnion = π₂.iUnion) :
    ∃ π : Prepartition I, π.iUnion = ↑I \ π₁.iUnion ∧
      (l.bDistortion → π.distortion ≤ c₁) ∧ (l.bDistortion → π.distortion ≤ c₂) := by
  

Proof state:
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
h₁ : MemBaseSet l I c₁ r₁ π₁
h₂ : MemBaseSet l I c₂ r₂ π₂
hU : TaggedPrepartition.iUnion π₁ = TaggedPrepartition.iUnion π₂
⊢ ∃ π,
    Prepartition.iUnion π = ↑I \ TaggedPrepartition.iUnion π₁ ∧
      (l.bDistortion = true → Prepartition.distortion π ≤ c₁) ∧ (l.bDistortion = true → Prepartition.distortion π ≤ c₂)

Next tactic:
wlog hc : c₁ ≤ c₂ with H
theorem MemBaseSet.exists_common_compl (h₁ : l.MemBaseSet I c₁ r₁ π₁) (h₂ : l.MemBaseSet I c₂ r₂ π₂)
    (hU : π₁.iUnion = π₂.iUnion) :
    ∃ π : Prepartition I, π.iUnion = ↑I \ π₁.iUnion ∧
      (l.bDistortion → π.distortion ≤ c₁) ∧ (l.bDistortion → π.distortion ≤ c₂) := by
  wlog hc : c₁ ≤ c₂ with H
  · 

Proof state:
case inr
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
h₁ : MemBaseSet l I c₁ r₁ π₁
h₂ : MemBaseSet l I c₂ r₂ π₂
hU : TaggedPrepartition.iUnion π₁ = TaggedPrepartition.iUnion π₂
H :
  ∀ {ι : Type u_1} [inst : Fintype ι] {I : Box ι} {J : Box ι} {c : ℝ≥0} {c₁ c₂ : ℝ≥0} {r : (ι → ℝ) → ↑(Set.Ioi 0)}
    {r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)} {π : TaggedPrepartition I} {π₁ π₂ : TaggedPrepartition I} {l : IntegrationParams}
    {l₁ l₂ : IntegrationParams},
    MemBaseSet l I c₁ r₁ π₁ →
      MemBaseSet l I c₂ r₂ π₂ →
        TaggedPrepartition.iUnion π₁ = TaggedPrepartition.iUnion π₂ →
          c₁ ≤ c₂ →
            ∃ π,
              Prepartition.iUnion π = ↑I \ TaggedPrepartition.iUnion π₁ ∧
                (l.bDistortion = true → Prepartition.distortion π ≤ c₁) ∧
                  (l.bDistortion = true → Prepartition.distortion π ≤ c₂)
hc : ¬c₁ ≤ c₂
⊢ ∃ π,
    Prepartition.iUnion π = ↑I \ TaggedPrepartition.iUnion π₁ ∧
      (l.bDistortion = true → Prepartition.distortion π ≤ c₁) ∧ (l.bDistortion = true → Prepartition.distortion π ≤ c₂)

Next tactic:
simpa [hU, _root_.and_comm] using
      @H _ _ I J c c₂ c₁ r r₂ r₁ π π₂ π₁ _ l₂ l₁ h₂ h₁ hU.symm (le_of_not_le hc)
theorem MemBaseSet.exists_common_compl (h₁ : l.MemBaseSet I c₁ r₁ π₁) (h₂ : l.MemBaseSet I c₂ r₂ π₂)
    (hU : π₁.iUnion = π₂.iUnion) :
    ∃ π : Prepartition I, π.iUnion = ↑I \ π₁.iUnion ∧
      (l.bDistortion → π.distortion ≤ c₁) ∧ (l.bDistortion → π.distortion ≤ c₂) := by
  wlog hc : c₁ ≤ c₂ with H
  · simpa [hU, _root_.and_comm] using
      @H _ _ I J c c₂ c₁ r r₂ r₁ π π₂ π₁ _ l₂ l₁ h₂ h₁ hU.symm (le_of_not_le hc)
  

Proof state:
ι✝ : Type u_1
inst✝¹ : Fintype ι✝
I✝ : Box ι✝
c₁✝ c₂✝ : ℝ≥0
r₁✝ r₂✝ : (ι✝ → ℝ) → ↑(Set.Ioi 0)
π₁✝ π₂✝ : TaggedPrepartition I✝
l✝ : IntegrationParams
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
h₁ : MemBaseSet l I c₁ r₁ π₁
h₂ : MemBaseSet l I c₂ r₂ π₂
hU : TaggedPrepartition.iUnion π₁ = TaggedPrepartition.iUnion π₂
hc : c₁ ≤ c₂
⊢ ∃ π,
    Prepartition.iUnion π = ↑I \ TaggedPrepartition.iUnion π₁ ∧
      (l.bDistortion = true → Prepartition.distortion π ≤ c₁) ∧ (l.bDistortion = true → Prepartition.distortion π ≤ c₂)

Next tactic:
by_cases hD : (l.bDistortion : Prop)
theorem MemBaseSet.exists_common_compl (h₁ : l.MemBaseSet I c₁ r₁ π₁) (h₂ : l.MemBaseSet I c₂ r₂ π₂)
    (hU : π₁.iUnion = π₂.iUnion) :
    ∃ π : Prepartition I, π.iUnion = ↑I \ π₁.iUnion ∧
      (l.bDistortion → π.distortion ≤ c₁) ∧ (l.bDistortion → π.distortion ≤ c₂) := by
  wlog hc : c₁ ≤ c₂ with H
  · simpa [hU, _root_.and_comm] using
      @H _ _ I J c c₂ c₁ r r₂ r₁ π π₂ π₁ _ l₂ l₁ h₂ h₁ hU.symm (le_of_not_le hc)
  by_cases hD : (l.bDistortion : Prop)
  · 

Proof state:
case pos
ι✝ : Type u_1
inst✝¹ : Fintype ι✝
I✝ : Box ι✝
c₁✝ c₂✝ : ℝ≥0
r₁✝ r₂✝ : (ι✝ → ℝ) → ↑(Set.Ioi 0)
π₁✝ π₂✝ : TaggedPrepartition I✝
l✝ : IntegrationParams
ι : Type u_1
inst✝ : Fintype ι
I J : Box ι
c c₁ c₂ : ℝ≥0
r r₁ r₂ : (ι → ℝ) → ↑(Set.Ioi 0)
π π₁ π₂ : TaggedPrepartition I
l l₁ l₂ : IntegrationParams
h₁ : MemBaseSet l I c₁ r₁ π₁
h₂ : MemBaseSet l I c₂ r₂ π₂
hU : TaggedPrepartition.iUnion π₁ = TaggedPrepartition.iUnion π₂
hc : c₁ ≤ c₂
hD : l.bDistortion = true
⊢ ∃ π,
    Prepartition.iUnion π = ↑I \ TaggedPrepartition.iUnion π₁ ∧
      (l.bDistortion = true → Prepartition.distortion π ≤ c₁) ∧ (l.bDistortion = true → Prepartition.distortion π ≤ c₂)

Next tactic:
rcases h₁.4 hD with ⟨π, hπU, hπc⟩