l3lab/ntp-mathlib huggingface dataset:
/-- If `D` is a reflective subcategory, the property of being an exponential ideal is equivalent to
the presence of a natural isomorphism `i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A`, that is:
`(A ⟹ iB) ≅ i L (A ⟹ iB)`, naturally in `B`.
The converse is given in `ExponentialIdeal.mk_of_iso`.
-/
def exponentialIdealReflective (A : C) [Reflective i] [ExponentialIdeal i] :
    i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A := by
  symm
  apply NatIso.ofComponents _ _
  · intro X
    haveI := Functor.essImage.unit_isIso (ExponentialIdeal.exp_closed (i.obj_mem_essImage X) A)
    apply asIso ((Adjunction.ofRightAdjoint i).unit.app (A ⟹ i.obj X))
  · 

Proof state:
C : Type u₁
D : Type u₂
inst✝⁵ : Category.{v₁, u₁} C
inst✝⁴ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝³ : HasFiniteProducts C
inst✝² : CartesianClosed C
A : C
inst✝¹ : Reflective i
inst✝ : ExponentialIdeal i
⊢ ∀ {X Y : D} (f : X ⟶ Y),
    (i ⋙ exp A).map f ≫ (asIso ((Adjunction.ofRightAdjoint i).unit.app (A ⟹ i.obj Y))).hom =
      (asIso ((Adjunction.ofRightAdjoint i).unit.app (A ⟹ i.obj X))).hom ≫ (i ⋙ exp A ⋙ leftAdjoint i ⋙ i).map f

Next tactic:
simp [asIso]
/-- Given a natural isomorphism `i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A`, we can show `i`
is an exponential ideal.
-/
theorem ExponentialIdeal.mk_of_iso [Reflective i]
    (h : ∀ A : C, i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A) : ExponentialIdeal i := by
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝² : HasFiniteProducts C
inst✝¹ : CartesianClosed C
inst✝ : Reflective i
h : (A : C) → i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A
⊢ ExponentialIdeal i

Next tactic:
apply ExponentialIdeal.mk'
/-- Given a natural isomorphism `i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A`, we can show `i`
is an exponential ideal.
-/
theorem ExponentialIdeal.mk_of_iso [Reflective i]
    (h : ∀ A : C, i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A) : ExponentialIdeal i := by
  apply ExponentialIdeal.mk'
  

Proof state:
case h
C : Type u₁
D : Type u₂
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝² : HasFiniteProducts C
inst✝¹ : CartesianClosed C
inst✝ : Reflective i
h : (A : C) → i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A
⊢ ∀ (B : D) (A : C), (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
intro B A
/-- Given a natural isomorphism `i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A`, we can show `i`
is an exponential ideal.
-/
theorem ExponentialIdeal.mk_of_iso [Reflective i]
    (h : ∀ A : C, i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A) : ExponentialIdeal i := by
  apply ExponentialIdeal.mk'
  intro B A
  

Proof state:
case h
C : Type u₁
D : Type u₂
inst✝⁴ : Category.{v₁, u₁} C
inst✝³ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝² : HasFiniteProducts C
inst✝¹ : CartesianClosed C
inst✝ : Reflective i
h : (A : C) → i ⋙ exp A ⋙ leftAdjoint i ⋙ i ≅ i ⋙ exp A
B : D
A : C
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
exact ⟨_, ⟨(h A).app B⟩⟩
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
⊢ ExponentialIdeal i

Next tactic:
let ir := Adjunction.ofRightAdjoint i
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
⊢ ExponentialIdeal i

Next tactic:
let L : C ⥤ D := leftAdjoint i
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
⊢ ExponentialIdeal i

Next tactic:
let η : 𝟭 C ⟶ L ⋙ i := ir.unit
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
⊢ ExponentialIdeal i

Next tactic:
let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
⊢ ExponentialIdeal i

Next tactic:
apply ExponentialIdeal.mk'
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  

Proof state:
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
⊢ ∀ (B : D) (A : C), (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
intro B A
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  

Proof state:
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  

Proof state:
case q
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
⊢ i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B := ?q
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
apply CartesianClosed.curry (ir.homEquiv _ _ _)
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
⊢ (leftAdjoint i).obj (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) ⟶ B
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B) ?m.26752)
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
  

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
⊢ (leftAdjoint i).obj (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) ⟶
    (leftAdjoint i).obj ((exp A ⋙ prod.functor.obj A).obj (i.obj B))
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry
    ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B)
      (?m.26813 ≫
        (Adjunction.homEquiv ir ((exp A ⋙ prod.functor.obj A).obj (i.obj B)) B).symm ((exp.ev A).app (i.obj B))))
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
refine' prodComparison L A _ ≫ Limits.prod.map (𝟙 _) (ε.app _) ≫ inv (prodComparison _ _ _)
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
  refine' prodComparison L A _ ≫ Limits.prod.map (𝟙 _) (ε.app _) ≫ inv (prodComparison _ _ _)
  

Proof state:
case h
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry
    ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B)
      ((prodComparison L A (i.obj (L.obj (A ⟹ i.obj B))) ≫
          prod.map (𝟙 (L.obj A)) (ε.app (L.obj (A ⟹ i.obj B))) ≫ inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B))) ≫
        (Adjunction.homEquiv ir ((exp A ⋙ prod.functor.obj A).obj (i.obj B)) B).symm ((exp.ev A).app (i.obj B))))
⊢ (A ⟹ i.obj B) ∈ Functor.essImage i

Next tactic:
have : η.app (A ⟹ i.obj B) ≫ q = 𝟙 (A ⟹ i.obj B) := by
    dsimp
    rw [← curry_natural_left, curry_eq_iff, uncurry_id_eq_ev, ← ir.homEquiv_naturality_left,
      ir.homEquiv_apply_eq, assoc, assoc, prodComparison_natural_assoc, L.map_id,
      ← prod.map_id_comp_assoc, ir.left_triangle_components, prod.map_id_id, id_comp]
    apply IsIso.hom_inv_id_assoc
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
  refine' prodComparison L A _ ≫ Limits.prod.map (𝟙 _) (ε.app _) ≫ inv (prodComparison _ _ _)
  have : η.app (A ⟹ i.obj B) ≫ q = 𝟙 (A ⟹ i.obj B) := by
    

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry
    ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B)
      ((prodComparison L A (i.obj (L.obj (A ⟹ i.obj B))) ≫
          prod.map (𝟙 (L.obj A)) (ε.app (L.obj (A ⟹ i.obj B))) ≫ inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B))) ≫
        (Adjunction.homEquiv ir ((exp A ⋙ prod.functor.obj A).obj (i.obj B)) B).symm ((exp.ev A).app (i.obj B))))
⊢ η.app (A ⟹ i.obj B) ≫ q = 𝟙 (A ⟹ i.obj B)

Next tactic:
dsimp
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
  refine' prodComparison L A _ ≫ Limits.prod.map (𝟙 _) (ε.app _) ≫ inv (prodComparison _ _ _)
  have : η.app (A ⟹ i.obj B) ≫ q = 𝟙 (A ⟹ i.obj B) := by
    dsimp
    

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry
    ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B)
      ((prodComparison L A (i.obj (L.obj (A ⟹ i.obj B))) ≫
          prod.map (𝟙 (L.obj A)) (ε.app (L.obj (A ⟹ i.obj B))) ≫ inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B))) ≫
        (Adjunction.homEquiv ir ((exp A ⋙ prod.functor.obj A).obj (i.obj B)) B).symm ((exp.ev A).app (i.obj B))))
⊢ (Adjunction.ofRightAdjoint i).unit.app (A ⟹ i.obj B) ≫
      CartesianClosed.curry
        ((Adjunction.homEquiv (Adjunction.ofRightAdjoint i) (A ⨯ i.obj ((leftAdjoint i).obj (A ⟹ i.obj B))) B)
          ((prodComparison (leftAdjoint i) A (i.obj ((leftAdjoint i).obj (A ⟹ i.obj B))) ≫
              prod.map (𝟙 ((leftAdjoint i).obj A))
                  ((Adjunction.ofRightAdjoint i).counit.app ((leftAdjoint i).obj (A ⟹ i.obj B))) ≫
                inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B))) ≫
            (Adjunction.homEquiv (Adjunction.ofRightAdjoint i) (A ⨯ A ⟹ i.obj B) B).symm ((exp.ev A).app (i.obj B)))) =
    𝟙 (A ⟹ i.obj B)

Next tactic:
rw [← curry_natural_left, curry_eq_iff, uncurry_id_eq_ev, ← ir.homEquiv_naturality_left,
      ir.homEquiv_apply_eq, assoc, assoc, prodComparison_natural_assoc, L.map_id,
      ← prod.map_id_comp_assoc, ir.left_triangle_components, prod.map_id_id, id_comp]
/-- If the reflector preserves binary products, the subcategory is an exponential ideal.
This is the converse of `preservesBinaryProductsOfExponentialIdeal`.
-/
instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)] : ExponentialIdeal i := by
  let ir := Adjunction.ofRightAdjoint i
  let L : C ⥤ D := leftAdjoint i
  let η : 𝟭 C ⟶ L ⋙ i := ir.unit
  let ε : i ⋙ L ⟶ 𝟭 D := ir.counit
  apply ExponentialIdeal.mk'
  intro B A
  let q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B
  apply CartesianClosed.curry (ir.homEquiv _ _ _)
  apply _ ≫ (ir.homEquiv _ _).symm ((exp.ev A).app (i.obj B))
  refine' prodComparison L A _ ≫ Limits.prod.map (𝟙 _) (ε.app _) ≫ inv (prodComparison _ _ _)
  have : η.app (A ⟹ i.obj B) ≫ q = 𝟙 (A ⟹ i.obj B) := by
    dsimp
    rw [← curry_natural_left, curry_eq_iff, uncurry_id_eq_ev, ← ir.homEquiv_naturality_left,
      ir.homEquiv_apply_eq, assoc, assoc, prodComparison_natural_assoc, L.map_id,
      ← prod.map_id_comp_assoc, ir.left_triangle_components, prod.map_id_id, id_comp]
    

Proof state:
C : Type u₁
D : Type u₂
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Category.{v₁, u₂} D
i : D ⥤ C
inst✝⁴ : HasFiniteProducts C
inst✝³ : Reflective i
inst✝² : CartesianClosed C
inst✝¹ : HasFiniteProducts D
inst✝ : PreservesLimitsOfShape (Discrete WalkingPair) (leftAdjoint i)
ir : leftAdjoint i ⊣ i := Adjunction.ofRightAdjoint i
L : C ⥤ D := leftAdjoint i
η : 𝟭 C ⟶ L ⋙ i := ir.unit
ε : i ⋙ L ⟶ 𝟭 D := ir.counit
B : D
A : C
q : i.obj (L.obj (A ⟹ i.obj B)) ⟶ A ⟹ i.obj B :=
  CartesianClosed.curry
    ((Adjunction.homEquiv ir (A ⨯ i.obj (L.obj (A ⟹ i.obj B))) B)
      ((prodComparison L A (i.obj (L.obj (A ⟹ i.obj B))) ≫
          prod.map (𝟙 (L.obj A)) (ε.app (L.obj (A ⟹ i.obj B))) ≫ inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B))) ≫
        (Adjunction.homEquiv ir ((exp A ⋙ prod.functor.obj A).obj (i.obj B)) B).symm ((exp.ev A).app (i.obj B))))
⊢ prodComparison (leftAdjoint i) A (A ⟹ i.obj B) ≫
      inv (prodComparison (leftAdjoint i) A (A ⟹ i.obj B)) ≫
        (Adjunction.homEquiv (Adjunction.ofRightAdjoint i) (A ⨯ A ⟹ i.obj B) B).symm ((exp.ev A).app (i.obj B)) =
    (Adjunction.homEquiv ir (A ⨯ A ⟹ i.obj B) B).symm ((exp.ev A).app (i.obj B))

Next tactic:
apply IsIso.hom_inv_id_assoc