Theorem: CategoryTheory.GrothendieckTopology.Plus.exists_of_sep
File: Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean

tactic: have inj : ∀ X : C, Function.Injective ((J.toPlus P).app (op X)) := inj_of_sep _ hsep
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
⊢ ∃ t, Meq.mk S t = s
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
⊢ ∃ t, Meq.mk S t = s

tactic: choose T t ht using fun I => exists_rep (s I)
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
⊢ ∃ t, Meq.mk S t = s
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
⊢ ∃ t, Meq.mk S t = s

tactic: let B : J.Cover X := S.bind T
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
⊢ ∃ t, Meq.mk S t = s
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
⊢ ∃ t, Meq.mk S t = s

tactic: choose Z e1 e2 he2 _ _ using fun I : B.Arrow => I.hf
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
⊢ ∃ t, Meq.mk S t = s
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
⊢ ∃ t, Meq.mk S t = s

tactic: let w : Meq P B := meqOfSep P hsep X S s T t ht
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
⊢ ∃ t, Meq.mk S t = s
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
⊢ ∃ t, Meq.mk S t = s

tactic: use mk w
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
⊢ ∃ t, Meq.mk S t = s
state_after: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
⊢ Meq.mk S (mk w) = s

tactic: ext I
state_before: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
⊢ Meq.mk S (mk w) = s
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ↑(Meq.mk S (mk w)) I = ↑s I

tactic: dsimp [Meq.mk]
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ↑(Meq.mk S (mk w)) I = ↑s I
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ((J.plusObj P).map I.f.op) (mk w) = ↑s I

tactic: erw [ht, res_mk_eq_mk_pullback]
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ((J.plusObj P).map I.f.op) (mk w) = ↑s I
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ mk (w.pullback I.f) = mk (t I)

tactic: apply sep P (T I)
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ mk (w.pullback I.f) = mk (t I)
state_after: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ∀ (I_1 : (T I).Arrow), ((J.plusObj P).map I_1.f.op) (mk (w.pullback I.f)) = ((J.plusObj P).map I_1.f.op) (mk (t I))

tactic: intro II
state_before: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
⊢ ∀ (I_1 : (T I).Arrow), ((J.plusObj P).map I_1.f.op) (mk (w.pullback I.f)) = ((J.plusObj P).map I_1.f.op) (mk (t I))
state_after: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ ((J.plusObj P).map II.f.op) (mk (w.pullback I.f)) = ((J.plusObj P).map II.f.op) (mk (t I))

tactic: simp only [res_mk_eq_mk_pullback, eq_mk_iff_exists]
state_before: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ ((J.plusObj P).map II.f.op) (mk (w.pullback I.f)) = ((J.plusObj P).map II.f.op) (mk (t I))
state_after: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ ∃ W h1 h2, ((w.pullback I.f).pullback II.f).refine h1 = ((t I).pullback II.f).refine h2

tactic: use (J.pullback II.f).obj (T I)
state_before: case h.h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ ∃ W h1 h2, ((w.pullback I.f).pullback II.f).refine h1 = ((t I).pullback II.f).refine h2
state_after: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ ∃ h1 h2, ((w.pullback I.f).pullback II.f).refine h1 = ((t I).pullback II.f).refine h2

tactic: use e0, 𝟙 _
state_before: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
⊢ ∃ h1 h2, ((w.pullback I.f).pullback II.f).refine h1 = ((t I).pullback II.f).refine h2
state_after: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
⊢ ((w.pullback I.f).pullback II.f).refine e0 = ((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))

tactic: ext IV
state_before: case h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
⊢ ((w.pullback I.f).pullback II.f).refine e0 = ((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV

tactic: let IA : B.Arrow := ⟨_, (IV.f ≫ II.f) ≫ I.f,
  ⟨I.Y, _, _, I.hf, Sieve.downward_closed _ II.hf _, rfl⟩⟩
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV

tactic: let IB : S.Arrow := IA.fromMiddle
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV

tactic: let IC : (T IB).Arrow := IA.toMiddle
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV

tactic: let ID : (T I).Arrow := ⟨IV.Y, IV.f ≫ II.f, Sieve.downward_closed (T I).sieve II.hf IV.f⟩
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV

tactic: change t IB IC = t I ID
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ↑(((w.pullback I.f).pullback II.f).refine e0) IV =
    ↑(((t I).pullback II.f).refine (𝟙 ((J.pullback II.f).obj (T I)))) IV
state_after: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ↑(t IB) IC = ↑(t I) ID

tactic: apply inj IV.Y
state_before: case h.h
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ↑(t IB) IC = ↑(t I) ID
state_after: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ((J.toPlus P).app { unop := IV.Y }) (↑(t IB) IC) = ((J.toPlus P).app { unop := IV.Y }) (↑(t I) ID)

tactic: erw [toPlus_apply (T I) (t I) ID, toPlus_apply (T IB) (t IB) IC, ← ht, ← ht]
state_before: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ((J.toPlus P).app { unop := IV.Y }) (↑(t IB) IC) = ((J.toPlus P).app { unop := IV.Y }) (↑(t I) ID)
state_after: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ((J.plusObj P).map IC.f.op) (↑s IB) = ((J.plusObj P).map ID.f.op) (↑s I)

tactic: let IR : S.Relation := Cover.Relation.mk { hf := IB.hf } { hf := I.hf } { w := IA.middle_spec }
state_before: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
⊢ ((J.plusObj P).map IC.f.op) (↑s IB) = ((J.plusObj P).map ID.f.op) (↑s I)
state_after: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
IR : S.Relation :=
  { fst := { Y := IB.Y, f := IB.f, hf := ⋯ }, snd := { Y := I.Y, f := I.f, hf := ⋯ },
    r := { Z := IA.Y, g₁ := IA.toMiddleHom, g₂ := IV.f ≫ II.f, w := ⋯ } }
⊢ ((J.plusObj P).map IC.f.op) (↑s IB) = ((J.plusObj P).map ID.f.op) (↑s I)

tactic: exact s.condition IR
state_before: case h.h.a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
e0 : (J.pullback II.f).obj (T I) ⟶ (J.pullback II.f).obj ((J.pullback I.f).obj B) := homOfLE ⋯
IV : ((J.pullback II.f).obj (T I)).Arrow
IA : B.Arrow := { Y := IV.Y, f := (IV.f ≫ II.f) ≫ I.f, hf := ⋯ }
IB : S.Arrow := IA.fromMiddle
IC : (T IB).Arrow := IA.toMiddle
ID : (T I).Arrow := { Y := IV.Y, f := IV.f ≫ II.f, hf := ⋯ }
IR : S.Relation :=
  { fst := { Y := IB.Y, f := IB.f, hf := ⋯ }, snd := { Y := I.Y, f := I.f, hf := ⋯ },
    r := { Z := IA.Y, g₁ := IA.toMiddleHom, g₂ := IV.f ≫ II.f, w := ⋯ } }
⊢ ((J.plusObj P).map IC.f.op) (↑s IB) = ((J.plusObj P).map ID.f.op) (↑s I)
state_after: no goals

tactic: intro Y f hf
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
⊢ (J.pullback II.f).obj (T I) ≤ (J.pullback II.f).obj ((J.pullback I.f).obj B)
state_after: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
Y : C
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T I))).arrows f
⊢ ((fun a => ↑a) ((J.pullback II.f).obj ((J.pullback I.f).obj B))).arrows f

tactic: apply Sieve.le_pullback_bind _ _ _ I.hf
state_before: C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
Y : C
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T I))).arrows f
⊢ ((fun a => ↑a) ((J.pullback II.f).obj ((J.pullback I.f).obj B))).arrows f
state_after: case a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
Y : C
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T I))).arrows f
⊢ (T { Y := I.Y, f := I.f, hf := ⋯ }).sieve.arrows (f ≫ II.f)

tactic: cases I
state_before: case a
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
I : S.Arrow
II : (T I).Arrow
Y : C
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T I))).arrows f
⊢ (T { Y := I.Y, f := I.f, hf := ⋯ }).sieve.arrows (f ≫ II.f)
state_after: case a.mk
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
Y Y✝ : C
f✝ : Y✝ ⟶ X
hf✝ : S.sieve.arrows f✝
II : (T { Y := Y✝, f := f✝, hf := hf✝ }).Arrow
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T { Y := Y✝, f := f✝, hf := hf✝ }))).arrows f
⊢ (T { Y := { Y := Y✝, f := f✝, hf := hf✝ }.Y, f := { Y := Y✝, f := f✝, hf := hf✝ }.f, hf := ⋯ }).sieve.arrows
    (f ≫ II.f)

tactic: exact hf
state_before: case a.mk
C : Type u
inst✝⁶ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w
inst✝⁵ : Category.{max v u, w} D
inst✝⁴ : ConcreteCategory D
inst✝³ : PreservesLimits (forget D)
inst✝² : ∀ (X : C), HasColimitsOfShape (J.Cover X)ᵒᵖ D
inst✝¹ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)
inst✝ : (X : C) → PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)
P : Cᵒᵖ ⥤ D
hsep :
  ∀ (X : C) (S : J.Cover X) (x y : (forget D).obj (P.obj { unop := X })),
    (∀ (I : S.Arrow), (P.map I.f.op) x = (P.map I.f.op) y) → x = y
X : C
S : J.Cover X
s : Meq (J.plusObj P) S
inj : ∀ (X : C), Function.Injective ⇑((J.toPlus P).app { unop := X })
T : (I : S.Arrow) → J.Cover I.Y
t : (I : S.Arrow) → Meq P (T I)
ht : ∀ (I : S.Arrow), ↑s I = mk (t I)
B : J.Cover X := S.bind T
Z : B.Arrow → C
e1 : (I : B.Arrow) → I.Y ⟶ Z I
e2 : (I : B.Arrow) → Z I ⟶ X
he2 : ∀ (I : B.Arrow), S.sieve.arrows (e2 I)
h✝ :
  ∀ (I : B.Arrow),
    (fun Y f h => ((fun Y f hf => (T { Y := Y, f := f, hf := hf }).sieve) Y f h).arrows) (Z I) (e2 I) ⋯ (e1 I)
a✝ : ∀ (I : B.Arrow), e1 I ≫ e2 I = I.f
w : Meq P B := meqOfSep P hsep X S s T t ht
Y Y✝ : C
f✝ : Y✝ ⟶ X
hf✝ : S.sieve.arrows f✝
II : (T { Y := Y✝, f := f✝, hf := hf✝ }).Arrow
f : Y ⟶ II.Y
hf : ((fun a => ↑a) ((J.pullback II.f).obj (T { Y := Y✝, f := f✝, hf := hf✝ }))).arrows f
⊢ (T { Y := { Y := Y✝, f := f✝, hf := hf✝ }.Y, f := { Y := Y✝, f := f✝, hf := hf✝ }.f, hf := ⋯ }).sieve.arrows
    (f ≫ II.f)
state_after: no goals