-- Mathlib/CategoryTheory/Sites/Types.lean
theorem typesGlue_eval {S hs α} (s) : typesGlue.{u} S hs α (eval S α s) = s

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
⊢ ∀ ⦃Y : Type u⦄ ⦃f : Y ⟶ α⦄, discretePresieve α f → S.map f.op (typesGlue S hs α (eval S α s)) = S.map f.op s

Tactic:
intro β f hf

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map f.op (typesGlue S hs α (eval S α s)) = S.map f.op s

Proof state:
case h
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
x : β
⊢ ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)) x = f x

Tactic:
exact congr_arg f (Classical.choose_spec hf x).symm

Result:
no goals

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)).op s = S.map f.op s

Tactic:
suffices ((↾fun _ ↦ PUnit.unit) ≫ ↾fun _ ↦ f (Classical.choose hf)) = f by rw [this]

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)) = f

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)) = f

Tactic:
funext x

Result:
case h
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
x : β
⊢ ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)) x = f x

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
this : ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)) = f
⊢ S.map ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)).op s = S.map f.op s

Tactic:
rw [this]

Result:
no goals

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map f.op (typesGlue S hs α (eval S α s)) = S.map f.op s

Tactic:
apply (IsSheafFor.valid_glue _ _ _ hf).trans

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map (↾fun x => PUnit.unit).op (eval S α s (f (Classical.choose hf))) = S.map f.op s

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map ((↾fun x => f (Classical.choose hf)).op ≫ (↾fun x => PUnit.unit).op) s = S.map f.op s

Tactic:
rw [← op_comp]

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map ((↾fun x => PUnit.unit) ≫ ↾fun x => f (Classical.choose hf)).op s = S.map f.op s

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map (↾fun x => PUnit.unit).op (eval S α s (f (Classical.choose hf))) = S.map f.op s

Tactic:
apply (FunctorToTypes.map_comp_apply _ _ _ _).symm.trans

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
β : Type u
f : β ⟶ α
hf : discretePresieve α f
⊢ S.map ((↾fun x => f (Classical.choose hf)).op ≫ (↾fun x => PUnit.unit).op) s = S.map f.op s

Proof state:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
⊢ typesGlue S hs α (eval S α s) = s

Tactic:
apply (hs.isSheafFor _ _ (generate_discretePresieve_mem α)).isSeparatedFor.ext

Result:
S : Type uᵒᵖ ⥤ Type u
hs : IsSheaf typesGrothendieckTopology S
α : Type u
s : S.obj (op α)
⊢ ∀ ⦃Y : Type u⦄ ⦃f : Y ⟶ α⦄, discretePresieve α f → S.map f.op (typesGlue S hs α (eval S α s)) = S.map f.op s