l3lab/ntp-mathlib huggingface dataset:
/-- A monadic functor creates any colimits of shapes it preserves. -/
noncomputable def monadicCreatesColimitsOfShapeOfPreservesColimitsOfShape (R : D ⥤ C)
    [MonadicRightAdjoint R] [PreservesColimitsOfShape J R] : CreatesColimitsOfShape J R :=
  letI : PreservesColimitsOfShape J (leftAdjoint R) := by
    apply (Adjunction.leftAdjointPreservesColimits (Adjunction.ofRightAdjoint R)).1
  letI : PreservesColimitsOfShape J (leftAdjoint R ⋙ R) := by
    

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : MonadicRightAdjoint R
inst✝ : PreservesColimitsOfShape J R
this : PreservesColimitsOfShape J (leftAdjoint R) := PreservesColimitsOfSize.preservesColimitsOfShape
⊢ PreservesColimitsOfShape J (leftAdjoint R ⋙ R)

Next tactic:
apply CategoryTheory.Limits.compPreservesColimitsOfShape _ _
/-- If `C` has colimits of shape `J` then any reflective subcategory has colimits of shape `J`. -/
theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimitsOfShape J C] :
    HasColimitsOfShape J D where
  has_colimit := fun F => by
      

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : Reflective R
inst✝ : HasColimitsOfShape J C
F : J ⥤ D
⊢ HasColimit F

Next tactic:
let c := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
/-- If `C` has colimits of shape `J` then any reflective subcategory has colimits of shape `J`. -/
theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimitsOfShape J C] :
    HasColimitsOfShape J D where
  has_colimit := fun F => by
      let c := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
      

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : Reflective R
inst✝ : HasColimitsOfShape J C
F : J ⥤ D
c : Cocone ((F ⋙ R) ⋙ leftAdjoint R) := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
⊢ HasColimit F

Next tactic:
letI : PreservesColimitsOfShape J _ :=
        (Adjunction.ofRightAdjoint R).leftAdjointPreservesColimits.1
/-- If `C` has colimits of shape `J` then any reflective subcategory has colimits of shape `J`. -/
theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimitsOfShape J C] :
    HasColimitsOfShape J D where
  has_colimit := fun F => by
      let c := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
      letI : PreservesColimitsOfShape J _ :=
        (Adjunction.ofRightAdjoint R).leftAdjointPreservesColimits.1
      

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : Reflective R
inst✝ : HasColimitsOfShape J C
F : J ⥤ D
c : Cocone ((F ⋙ R) ⋙ leftAdjoint R) := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
this : PreservesColimitsOfShape J (leftAdjoint R) := PreservesColimitsOfSize.preservesColimitsOfShape
⊢ HasColimit F

Next tactic:
let t : IsColimit c := isColimitOfPreserves (leftAdjoint R) (colimit.isColimit _)
/-- If `C` has colimits of shape `J` then any reflective subcategory has colimits of shape `J`. -/
theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimitsOfShape J C] :
    HasColimitsOfShape J D where
  has_colimit := fun F => by
      let c := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
      letI : PreservesColimitsOfShape J _ :=
        (Adjunction.ofRightAdjoint R).leftAdjointPreservesColimits.1
      let t : IsColimit c := isColimitOfPreserves (leftAdjoint R) (colimit.isColimit _)
      

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : Reflective R
inst✝ : HasColimitsOfShape J C
F : J ⥤ D
c : Cocone ((F ⋙ R) ⋙ leftAdjoint R) := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
this : PreservesColimitsOfShape J (leftAdjoint R) := PreservesColimitsOfSize.preservesColimitsOfShape
t : IsColimit c := isColimitOfPreserves (leftAdjoint R) (colimit.isColimit (F ⋙ R))
⊢ HasColimit F

Next tactic:
apply HasColimit.mk ⟨_, (IsColimit.precomposeInvEquiv _ _).symm t⟩
/-- If `C` has colimits of shape `J` then any reflective subcategory has colimits of shape `J`. -/
theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimitsOfShape J C] :
    HasColimitsOfShape J D where
  has_colimit := fun F => by
      let c := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
      letI : PreservesColimitsOfShape J _ :=
        (Adjunction.ofRightAdjoint R).leftAdjointPreservesColimits.1
      let t : IsColimit c := isColimitOfPreserves (leftAdjoint R) (colimit.isColimit _)
      apply HasColimit.mk ⟨_, (IsColimit.precomposeInvEquiv _ _).symm t⟩
      

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
J : Type u
inst✝² : Category.{v, u} J
R : D ⥤ C
inst✝¹ : Reflective R
inst✝ : HasColimitsOfShape J C
F : J ⥤ D
c : Cocone ((F ⋙ R) ⋙ leftAdjoint R) := (leftAdjoint R).mapCocone (colimit.cocone (F ⋙ R))
this : PreservesColimitsOfShape J (leftAdjoint R) := PreservesColimitsOfSize.preservesColimitsOfShape
t : IsColimit c := isColimitOfPreserves (leftAdjoint R) (colimit.isColimit (F ⋙ R))
⊢ (F ⋙ R) ⋙ leftAdjoint R ≅ F

Next tactic:
apply
        (isoWhiskerLeft F (asIso (Adjunction.ofRightAdjoint R).counit) : _) ≪≫ F.rightUnitor
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
⊢ PreservesLimit K (leftAdjoint R)

Next tactic:
let F := Functor.empty.{v} D
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
⊢ PreservesLimit K (leftAdjoint R)

Next tactic:
letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      apply (leftAdjoint R).mapIso
      letI := monadicCreatesLimits.{v, v} R
      let A := (CategoryTheory.preservesLimitOfCreatesLimitAndHasLimit F R)
      apply (A.preserves (limit.isLimit F)).conePointUniqueUpToIso h
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
⊢ PreservesLimit (F ⋙ R) (leftAdjoint R)

Next tactic:
constructor
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      

Proof state:
case preserves
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
⊢ {c : Cone (F ⋙ R)} → IsLimit c → IsLimit ((leftAdjoint R).mapCone c)

Next tactic:
intro c h
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      

Proof state:
case preserves
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
⊢ IsLimit ((leftAdjoint R).mapCone c)

Next tactic:
haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      

Proof state:
case preserves
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this : HasLimit (F ⋙ R)
⊢ IsLimit ((leftAdjoint R).mapCone c)

Next tactic:
haveI : HasLimit F := hasLimit_of_reflective F R
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      

Proof state:
case preserves
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝ : HasLimit (F ⋙ R)
this : HasLimit F
⊢ IsLimit ((leftAdjoint R).mapCone c)

Next tactic:
apply isLimitChangeEmptyCone D (limit.isLimit F)
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      

Proof state:
case preserves.hi
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝ : HasLimit (F ⋙ R)
this : HasLimit F
⊢ (limit.cone F).pt ≅ ((leftAdjoint R).mapCone c).pt

Next tactic:
apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      

Proof state:
case preserves.hi
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝ : HasLimit (F ⋙ R)
this : HasLimit F
⊢ (R ⋙ leftAdjoint R).obj (limit.cone F).1 ≅ ((leftAdjoint R).mapCone c).pt

Next tactic:
apply (leftAdjoint R).mapIso
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      apply (leftAdjoint R).mapIso
      

Proof state:
case preserves.hi
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝ : HasLimit (F ⋙ R)
this : HasLimit F
⊢ R.obj (limit.cone F).1 ≅ c.pt

Next tactic:
letI := monadicCreatesLimits.{v, v} R
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      apply (leftAdjoint R).mapIso
      letI := monadicCreatesLimits.{v, v} R
      

Proof state:
case preserves.hi
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝¹ : HasLimit (F ⋙ R)
this✝ : HasLimit F
this : CreatesLimitsOfSize.{v, v, v₂, v₁, u₂, u₁} R := monadicCreatesLimits R
⊢ R.obj (limit.cone F).1 ≅ c.pt

Next tactic:
let A := (CategoryTheory.preservesLimitOfCreatesLimitAndHasLimit F R)
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      apply (leftAdjoint R).mapIso
      letI := monadicCreatesLimits.{v, v} R
      let A := (CategoryTheory.preservesLimitOfCreatesLimitAndHasLimit F R)
      

Proof state:
case preserves.hi
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
c : Cone (F ⋙ R)
h : IsLimit c
this✝¹ : HasLimit (F ⋙ R)
this✝ : HasLimit F
this : CreatesLimitsOfSize.{v, v, v₂, v₁, u₂, u₁} R := monadicCreatesLimits R
A : PreservesLimit F R := preservesLimitOfCreatesLimitAndHasLimit F R
⊢ R.obj (limit.cone F).1 ≅ c.pt

Next tactic:
apply (A.preserves (limit.isLimit F)).conePointUniqueUpToIso h
/-- The reflector always preserves terminal objects. Note this in general doesn't apply to any other
limit.
-/
noncomputable def leftAdjointPreservesTerminalOfReflective (R : D ⥤ C) [Reflective R] :
    PreservesLimitsOfShape (Discrete.{v} PEmpty) (leftAdjoint R) where
  preservesLimit {K} := by
    let F := Functor.empty.{v} D
    letI : PreservesLimit (F ⋙ R) (leftAdjoint R) := by
      constructor
      intro c h
      haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩
      haveI : HasLimit F := hasLimit_of_reflective F R
      apply isLimitChangeEmptyCone D (limit.isLimit F)
      apply (asIso ((Adjunction.ofRightAdjoint R).counit.app _)).symm.trans
      apply (leftAdjoint R).mapIso
      letI := monadicCreatesLimits.{v, v} R
      let A := (CategoryTheory.preservesLimitOfCreatesLimitAndHasLimit F R)
      apply (A.preserves (limit.isLimit F)).conePointUniqueUpToIso h
    

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
J : Type u
inst✝¹ : Category.{v, u} J
R : D ⥤ C
inst✝ : Reflective R
K : Discrete PEmpty.{v + 1} ⥤ C
F : Discrete PEmpty.{v + 1} ⥤ D := Functor.empty D
this : PreservesLimit (F ⋙ R) (leftAdjoint R) :=
  {
    preserves := fun {c} h =>
      isLimitChangeEmptyCone D (limit.isLimit F) ((leftAdjoint R).mapCone c)
        ((asIso ((Adjunction.ofRightAdjoint R).counit.app (limit.cone F).1)).symm ≪≫
          (leftAdjoint R).mapIso
            (let A := preservesLimitOfCreatesLimitAndHasLimit F R;
            IsLimit.conePointUniqueUpToIso (PreservesLimit.preserves (limit.isLimit F)) h)) }
⊢ PreservesLimit K (leftAdjoint R)

Next tactic:
apply preservesLimitOfIsoDiagram _ (Functor.emptyExt (F ⋙ R) _)
@[to_additive (attr := simp) ite_nsmul]
theorem pow_ite (P : Prop) [Decidable P] (a : M) (b c : ℕ) :
    (a ^ if P then b else c) = if P then a ^ b else a ^ c := by 

Proof state:
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a : M
b c : ℕ
⊢ (a ^ if P then b else c) = if P then a ^ b else a ^ c

Next tactic:
split_ifs
@[to_additive (attr := simp) ite_nsmul]
theorem pow_ite (P : Prop) [Decidable P] (a : M) (b c : ℕ) :
    (a ^ if P then b else c) = if P then a ^ b else a ^ c := by split_ifs <;> 

Proof state:
case pos
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a : M
b c : ℕ
h✝ : P
⊢ a ^ b = a ^ b

Next tactic:
rfl
@[to_additive (attr := simp) ite_nsmul]
theorem pow_ite (P : Prop) [Decidable P] (a : M) (b c : ℕ) :
    (a ^ if P then b else c) = if P then a ^ b else a ^ c := by split_ifs <;> 

Proof state:
case neg
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a : M
b c : ℕ
h✝ : ¬P
⊢ a ^ c = a ^ c

Next tactic:
rfl
@[to_additive (attr := simp) nsmul_ite]
theorem ite_pow (P : Prop) [Decidable P] (a b : M) (c : ℕ) :
    (if P then a else b) ^ c = if P then a ^ c else b ^ c := by 

Proof state:
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a b : M
c : ℕ
⊢ (if P then a else b) ^ c = if P then a ^ c else b ^ c

Next tactic:
split_ifs
@[to_additive (attr := simp) nsmul_ite]
theorem ite_pow (P : Prop) [Decidable P] (a b : M) (c : ℕ) :
    (if P then a else b) ^ c = if P then a ^ c else b ^ c := by split_ifs <;> 

Proof state:
case pos
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a b : M
c : ℕ
h✝ : P
⊢ a ^ c = a ^ c

Next tactic:
rfl
@[to_additive (attr := simp) nsmul_ite]
theorem ite_pow (P : Prop) [Decidable P] (a b : M) (c : ℕ) :
    (if P then a else b) ^ c = if P then a ^ c else b ^ c := by split_ifs <;> 

Proof state:
case neg
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Pow M ℕ
P : Prop
inst✝ : Decidable P
a b : M
c : ℕ
h✝ : ¬P
⊢ b ^ c = b ^ c

Next tactic:
rfl
theorem nsmul_zero (n : ℕ) : n • (0 : A) = 0 := by
  

Proof state:
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
n : ℕ
⊢ n • 0 = 0

Next tactic:
induction' n with n ih
theorem nsmul_zero (n : ℕ) : n • (0 : A) = 0 := by
  induction' n with n ih
  · 

Proof state:
case zero
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
⊢ Nat.zero • 0 = 0

Next tactic:
exact zero_nsmul _
theorem nsmul_zero (n : ℕ) : n • (0 : A) = 0 := by
  induction' n with n ih
  · exact zero_nsmul _
  · 

Proof state:
case succ
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
n : ℕ
ih : n • 0 = 0
⊢ Nat.succ n • 0 = 0

Next tactic:
rw [succ_nsmul, ih, add_zero]
@[simp]
theorem one_nsmul (a : A) : 1 • a = a := by 

Proof state:
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
a : A
⊢ 1 • a = a

Next tactic:
rw [succ_nsmul, zero_nsmul, add_zero]
theorem add_nsmul (a : A) (m n : ℕ) : (m + n) • a = m • a + n • a := by
  

Proof state:
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
a : A
m n : ℕ
⊢ (m + n) • a = m • a + n • a

Next tactic:
induction m with
  | zero => rw [Nat.zero_add, zero_nsmul, zero_add]
  | succ m ih => rw [Nat.succ_add, Nat.succ_eq_add_one, succ_nsmul, ih, succ_nsmul, add_assoc]
theorem add_nsmul (a : A) (m n : ℕ) : (m + n) • a = m • a + n • a := by
  induction m with
  

Proof state:
case zero
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
a : A
n : ℕ
⊢ (Nat.zero + n) • a = Nat.zero • a + n • a

Next tactic:
| zero => rw [Nat.zero_add, zero_nsmul, zero_add]
theorem add_nsmul (a : A) (m n : ℕ) : (m + n) • a = m • a + n • a := by
  induction m with
  | zero => 

Proof state:
case zero
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
a : A
n : ℕ
⊢ (Nat.zero + n) • a = Nat.zero • a + n • a

Next tactic:
rw [Nat.zero_add, zero_nsmul, zero_add]
theorem add_nsmul (a : A) (m n : ℕ) : (m + n) • a = m • a + n • a := by
  induction m with
  | zero => rw [Nat.zero_add, zero_nsmul, zero_add]
  

Proof state:
case succ
α : Type u_1
M : Type u
N : Type v
G : Type w
H : Type x
A : Type y
B : Type z
R : Type u₁
S : Type u₂
inst✝¹ : Monoid M
inst✝ : AddMonoid A
a : A
n m : ℕ
ih : (m + n) • a = m • a + n • a
⊢ (Nat.succ m + n) • a = Nat.succ m • a + n • a

Next tactic:
| succ m ih => rw [Nat.succ_add, Nat.succ_eq_add_one, succ_nsmul, ih, succ_nsmul, add_assoc]