-- Mathlib/CategoryTheory/Sites/Canonical.lean
theorem isSheafFor_trans (P : Cᵒᵖ ⥤ Type v) (R S : Sieve X)
    (hR : Presieve.IsSheafFor P (R : Presieve X))
    (hR' : ∀ ⦃Y⦄ ⦃f : Y ⟶ X⦄ (_ : S f), Presieve.IsSeparatedFor P (R.pullback f : Presieve Y))
    (hS : ∀ ⦃Y⦄ ⦃f : Y ⟶ X⦄ (_ : R f), Presieve.IsSheafFor P (S.pullback f : Presieve Y)) :
    Presieve.IsSheafFor P (S : Presieve X)

Proof state:
case hS
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ Presieve.IsSheafFor P (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows

Tactic:
apply isSheafFor_bind _ _ _ hR hS

Result:
case hS
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    R.arrows f → ∀ ⦃Z : C⦄ (g : Z ⟶ Y), Presieve.IsSeparatedFor P (Sieve.pullback g (Sieve.pullback f S)).arrows

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
⊢ (Sieve.pullback f (Sieve.bind R.arrows fun T k x => Sieve.pullback k S)).arrows g ↔ (Sieve.pullback f R).arrows g

Tactic:
constructor

Result:
case h.mp
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
⊢ (Sieve.pullback f (Sieve.bind R.arrows fun T k x => Sieve.pullback k S)).arrows g → (Sieve.pullback f R).arrows g

case h.mpr
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
⊢ (Sieve.pullback f R).arrows g → (Sieve.pullback f (Sieve.bind R.arrows fun T k x => Sieve.pullback k S)).arrows g

Proof state:
case h.mp.intro.intro.intro.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
W : C
k : Z ⟶ W
l : W ⟶ X
hl : R.arrows l
left✝ : ((fun T k x => Sieve.pullback k S) W l hl).arrows k
comm : k ≫ l = g ≫ f
⊢ R.arrows (k ≫ l)

Tactic:
simp [hl]

Result:
no goals

Proof state:
case h.mpr
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
⊢ (Sieve.pullback f R).arrows g → (Sieve.pullback f (Sieve.bind R.arrows fun T k x => Sieve.pullback k S)).arrows g

Tactic:
intro a

Result:
case h.mpr
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
a : (Sieve.pullback f R).arrows g
⊢ (Sieve.pullback f (Sieve.bind R.arrows fun T k x => Sieve.pullback k S)).arrows g

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ Presieve.IsSheafFor P S.arrows

Tactic:
apply Presieve.isSheafFor_subsieve_aux P this

Result:
case hS
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ Presieve.IsSheafFor P (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows

case trans
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Presieve.IsSeparatedFor P (Sieve.pullback f (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S)).arrows

Proof state:
case trans
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Presieve.IsSeparatedFor P (Sieve.pullback f (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S)).arrows

Tactic:
intro Y f hf

Result:
case trans
C : Type u
inst✝ : Category.{v, u} C
X : C
P : Cᵒᵖ ⥤ Type v
R S : Sieve X
hR : Presieve.IsSheafFor P R.arrows
hR' : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Presieve.IsSeparatedFor P (Sieve.pullback f R).arrows
hS : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R.arrows f → Presieve.IsSheafFor P (Sieve.pullback f S).arrows
this : (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ Presieve.IsSeparatedFor P (Sieve.pullback f (Sieve.bind R.arrows fun Y f x => Sieve.pullback f S)).arrows