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

tactic: rw [isSheaf_iff_multifork]
state_before: C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
⊢ IsSheaf J P ↔ ∀ (X : C) (S : J.Cover X), IsIso (S.toMultiequalizer P)
state_after: C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
⊢ (∀ (X : C) (S : J.Cover X), Nonempty (IsLimit (S.multifork P))) ↔
    ∀ (X : C) (S : J.Cover X), IsIso (S.toMultiequalizer P)

tactic: refine forall₂_congr fun X S => ⟨?_, ?_⟩
state_before: C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
⊢ (∀ (X : C) (S : J.Cover X), Nonempty (IsLimit (S.multifork P))) ↔
    ∀ (X : C) (S : J.Cover X), IsIso (S.toMultiequalizer P)
state_after: case refine_1
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
⊢ Nonempty (IsLimit (S.multifork P)) → IsIso (S.toMultiequalizer P)

case refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
⊢ IsIso (S.toMultiequalizer P) → Nonempty (IsLimit (S.multifork P))

tactic: rintro ⟨h⟩
state_before: case refine_1
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
⊢ Nonempty (IsLimit (S.multifork P)) → IsIso (S.toMultiequalizer P)
state_after: case refine_1.intro
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsLimit (S.multifork P)
⊢ IsIso (S.toMultiequalizer P)

tactic: let e : P.obj (op X) ≅ multiequalizer (S.index P) :=
  h.conePointUniqueUpToIso (limit.isLimit _)
state_before: case refine_1.intro
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsLimit (S.multifork P)
⊢ IsIso (S.toMultiequalizer P)
state_after: case refine_1.intro
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsLimit (S.multifork P)
e : P.obj { unop := X } ≅ multiequalizer (S.index P) := h.conePointUniqueUpToIso (limit.isLimit (S.index P).multicospan)
⊢ IsIso (S.toMultiequalizer P)

tactic: exact (inferInstance : IsIso e.hom)
state_before: case refine_1.intro
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsLimit (S.multifork P)
e : P.obj { unop := X } ≅ multiequalizer (S.index P) := h.conePointUniqueUpToIso (limit.isLimit (S.index P).multicospan)
⊢ IsIso (S.toMultiequalizer P)
state_after: no goals

tactic: intro h
state_before: case refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
⊢ IsIso (S.toMultiequalizer P) → Nonempty (IsLimit (S.multifork P))
state_after: case refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ Nonempty (IsLimit (S.multifork P))

tactic: refine ⟨IsLimit.ofIsoLimit (limit.isLimit _) (Cones.ext ?_ ?_)⟩
state_before: case refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ Nonempty (IsLimit (S.multifork P))
state_after: case refine_2.refine_1
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ (limit.cone (S.index P).multicospan).pt ≅ (S.multifork P).pt

case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ ∀ (j : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo),
    (limit.cone (S.index P).multicospan).π.app j = ?refine_2.refine_1.hom ≫ (S.multifork P).π.app j

tactic: apply (@asIso _ _ _ _ _ h).symm
state_before: case refine_2.refine_1
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ (limit.cone (S.index P).multicospan).pt ≅ (S.multifork P).pt
state_after: no goals

tactic: intro a
state_before: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
⊢ ∀ (j : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo),
    (limit.cone (S.index P).multicospan).π.app j = (asIso (S.toMultiequalizer P)).symm.hom ≫ (S.multifork P).π.app j
state_after: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (limit.cone (S.index P).multicospan).π.app a = (asIso (S.toMultiequalizer P)).symm.hom ≫ (S.multifork P).π.app a

tactic: symm
state_before: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (limit.cone (S.index P).multicospan).π.app a = (asIso (S.toMultiequalizer P)).symm.hom ≫ (S.multifork P).π.app a
state_after: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (asIso (S.toMultiequalizer P)).symm.hom ≫ (S.multifork P).π.app a = (limit.cone (S.index P).multicospan).π.app a

tactic: erw [IsIso.inv_comp_eq]
state_before: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (asIso (S.toMultiequalizer P)).symm.hom ≫ (S.multifork P).π.app a = (limit.cone (S.index P).multicospan).π.app a
state_after: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (S.multifork P).π.app a = S.toMultiequalizer P ≫ (limit.cone (S.index P).multicospan).π.app a

tactic: dsimp
state_before: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (S.multifork P).π.app a = S.toMultiequalizer P ≫ (limit.cone (S.index P).multicospan).π.app a
state_after: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (match a with
    | WalkingMulticospan.left a => P.map a.f.op
    | WalkingMulticospan.right b => P.map b.fst.f.op ≫ P.map b.r.g₁.op) =
    S.toMultiequalizer P ≫ limit.π (S.index P).multicospan a

tactic: simp
state_before: case refine_2.refine_2
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
A : Type u₂
inst✝³ : Category.{v₂, u₂} A
A' : Type u₂
inst✝² : Category.{max v₁ u₁, u₂} A'
B : Type u₃
inst✝¹ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
P : Cᵒᵖ ⥤ A
P' : Cᵒᵖ ⥤ A'
inst✝ : ∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
X : C
S : J.Cover X
h : IsIso (S.toMultiequalizer P)
a : WalkingMulticospan (S.index P).fstTo (S.index P).sndTo
⊢ (match a with
    | WalkingMulticospan.left a => P.map a.f.op
    | WalkingMulticospan.right b => P.map b.fst.f.op ≫ P.map b.r.g₁.op) =
    S.toMultiequalizer P ≫ limit.π (S.index P).multicospan a
state_after: no goals