Theorem: CategoryTheory.Presheaf.isSheaf_iff_isSheaf_forget
File: Mathlib/CategoryTheory/Sites/Sheaf.lean

tactic: rw [isSheaf_iff_isSheaf', isSheaf_iff_isSheaf']
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
⊢ IsSheaf J P ↔ IsSheaf J (P ⋙ s)

tactic: refine' forall_congr' (fun U => ball_congr (fun R _ => _))
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
⊢ IsSheaf' J P ↔ IsSheaf' J (P ⋙ s)

tactic: letI : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ↔
    Nonempty
      (IsLimit
        (Fork.ofι (forkMap R (P ⋙ s))
          (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s))))

tactic: have : IsLimit (s.mapCone (Fork.ofι _ (w R P))) ≃ IsLimit (Fork.ofι _ (w R (P ⋙ s))) :=
  isSheafForIsSheafFor' P s U R
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ↔
    Nonempty
      (IsLimit
        (Fork.ofι (forkMap R (P ⋙ s))
          (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s))))

tactic: rw [← Equiv.nonempty_congr this]
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ↔
    Nonempty
      (IsLimit
        (Fork.ofι (forkMap R (P ⋙ s))
          (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s))))

tactic: constructor
state_before: C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ↔
    Nonempty
      (IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))))

tactic: haveI := preservesSmallestLimitsOfPreservesLimits s
state_before: case mp
C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) →
    Nonempty
      (IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))))

tactic: exact Nonempty.map fun t => isLimitOfPreserves s t
state_before: case mp
C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝¹ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this✝ :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
this : PreservesLimitsOfSize s
⊢ Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) →
    Nonempty
      (IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))))

tactic: haveI := reflectsSmallestLimitsOfReflectsLimits s
state_before: case mpr
C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
⊢ Nonempty
      (IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P)))) →
    Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P)))

tactic: exact Nonempty.map fun t => isLimitOfReflects s t
state_before: case mpr
C : Type u₁
inst✝⁵ : Category C
A : Type u₂
inst✝⁴ : Category A
J : GrothendieckTopology C
U✝ : C
R✝ : Presieve U✝
P : Cᵒᵖ ⥤ A
inst✝³ : HasPullbacks C
s : A ⥤ Type (max v₁ u₁)
inst✝² : HasLimits A
inst✝¹ : PreservesLimits s
inst✝ : ReflectsIsomorphisms s
U : C
R : Presieve U
x✝ : generate R ∈ GrothendieckTopology.sieves J U
this✝¹ : ReflectsLimits s := reflectsLimitsOfReflectsIsomorphisms
this✝ :
  IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P))) ≃
    IsLimit
      (Fork.ofι (forkMap R (P ⋙ s))
        (_ : forkMap R (P ⋙ s) ≫ firstMap R (P ⋙ s) = forkMap R (P ⋙ s) ≫ secondMap R (P ⋙ s)))
this : ReflectsLimitsOfSize s
⊢ Nonempty
      (IsLimit (s.mapCone (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P)))) →
    Nonempty (IsLimit (Fork.ofι (forkMap R P) (_ : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P)))