[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
⊢ FamilyOfElements.Compatible x ↔ FamilyOfElements.PullbackCompatible x
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
⊢ FamilyOfElements.Compatible x → FamilyOfElements.PullbackCompatible x
[PROOFSTEP]
intro t Y₁ Y₂ f₁ f₂ hf₁ hf₂
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
t : FamilyOfElements.Compatible x
Y₁ Y₂ : C
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : R f₁
hf₂ : R f₂
⊢ P.map pullback.fst.op (x f₁ hf₁) = P.map pullback.snd.op (x f₂ hf₂)
[PROOFSTEP]
apply t
[GOAL]
case mp.a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
t : FamilyOfElements.Compatible x
Y₁ Y₂ : C
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : R f₁
hf₂ : R f₂
⊢ pullback.fst ≫ f₁ = pullback.snd ≫ f₂
[PROOFSTEP]
apply pullback.condition
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
⊢ FamilyOfElements.PullbackCompatible x → FamilyOfElements.Compatible x
[PROOFSTEP]
intro t Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ comm
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
inst✝ : HasPullbacks C
t : FamilyOfElements.PullbackCompatible x
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : R f₁
hf₂ : R f₂
comm : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ P.map g₁.op (x f₁ hf₁) = P.map g₂.op (x f₂ hf₂)
[PROOFSTEP]
rw [← pullback.lift_fst _ _ comm, op_comp, FunctorToTypes.map_comp_apply, t hf₁ hf₂, ← FunctorToTypes.map_comp_apply, ←
  op_comp, pullback.lift_snd]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
⊢ Compatible (FamilyOfElements.sieveExtend x)
[PROOFSTEP]
intro _ _ _ _ _ _ _ h₁ h₂ comm
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map g₁✝.op (FamilyOfElements.sieveExtend x f₁✝ h₁) = P.map g₂✝.op (FamilyOfElements.sieveExtend x f₂✝ h₂)
[PROOFSTEP]
iterate 2 erw [← FunctorToTypes.map_comp_apply]; rw [← op_comp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map g₁✝.op (FamilyOfElements.sieveExtend x f₁✝ h₁) = P.map g₂✝.op (FamilyOfElements.sieveExtend x f₂✝ h₂)
[PROOFSTEP]
erw [← FunctorToTypes.map_comp_apply]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map ((Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝)).op ≫ g₁✝.op)
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝)))) =
    P.map g₂✝.op (FamilyOfElements.sieveExtend x f₂✝ h₂)
[PROOFSTEP]
rw [← op_comp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map (g₁✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝)))) =
    P.map g₂✝.op (FamilyOfElements.sieveExtend x f₂✝ h₂)
[PROOFSTEP]
erw [← FunctorToTypes.map_comp_apply]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map (g₁✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝)))) =
    P.map ((Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝)).op ≫ g₂✝.op)
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝) ≫ g = f₂✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝) ≫ g = f₂✝))))
[PROOFSTEP]
rw [← op_comp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ P.map (g₁✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝)))) =
    P.map (g₂✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝) ≫ g = f₂✝))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝) ≫ g = f₂✝))))
[PROOFSTEP]
apply hx
[GOAL]
case a
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
hx : Compatible x
Y₁✝ Y₂✝ Z✝ : C
g₁✝ : Z✝ ⟶ Y₁✝
g₂✝ : Z✝ ⟶ Y₂✝
f₁✝ : Y₁✝ ⟶ X
f₂✝ : Y₂✝ ⟶ X
h₁ : (generate R).arrows f₁✝
h₂ : (generate R).arrows f₂✝
comm : g₁✝ ≫ f₁✝ = g₂✝ ≫ f₂✝
⊢ (g₁✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝)) ≫
      Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₁✝) ≫ g = f₁✝) =
    (g₂✝ ≫ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝)) ≫
      Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f₂✝) ≫ g = f₂✝)
[PROOFSTEP]
simp [comm, h₁.choose_spec.choose_spec.choose_spec.2, h₂.choose_spec.choose_spec.choose_spec.2]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
⊢ FamilyOfElements.sieveExtend x f (_ : f ∈ (generate R).arrows) = x f hf
[PROOFSTEP]
have h := (le_generate R Y hf).choose_spec
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
h : ∃ h g, R g ∧ h ≫ g = f
⊢ FamilyOfElements.sieveExtend x f (_ : f ∈ (generate R).arrows) = x f hf
[PROOFSTEP]
unfold FamilyOfElements.sieveExtend
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
h : ∃ h g, R g ∧ h ≫ g = f
⊢ P.map (Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f)))) =
    x f hf
[PROOFSTEP]
rw [t h.choose (𝟙 _) _ hf _]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
h : ∃ h g, R g ∧ h ≫ g = f
⊢ P.map (𝟙 Y).op (x f hf) = x f hf
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
h : ∃ h g, R g ∧ h ≫ g = f
⊢ Exists.choose h ≫ Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f) = 𝟙 Y ≫ f
[PROOFSTEP]
rw [id_comp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
f : Y ⟶ X
hf : R f
h : ∃ h g, R g ∧ h ≫ g = f
⊢ Exists.choose h ≫ Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f) = f
[PROOFSTEP]
exact h.choose_spec.choose_spec.2
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
⊢ FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) (FamilyOfElements.sieveExtend x) = x
[PROOFSTEP]
funext Y f hf
[GOAL]
case h.h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : FamilyOfElements.Compatible x
Y : C
f : Y ⟶ X
hf : R f
⊢ FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) (FamilyOfElements.sieveExtend x) f hf = x f hf
[PROOFSTEP]
exact extend_agrees t hf
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
⊢ FamilyOfElements.Compatible x ↔ FamilyOfElements.SieveCompatible x
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
⊢ FamilyOfElements.Compatible x → FamilyOfElements.SieveCompatible x
[PROOFSTEP]
intro h Y Z f g hf
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
h : FamilyOfElements.Compatible x
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ x (g ≫ f) (_ : S.arrows (g ≫ f)) = P.map g.op (x f hf)
[PROOFSTEP]
simpa using h (𝟙 _) g (S.downward_closed hf g) hf (id_comp _)
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
⊢ FamilyOfElements.SieveCompatible x → FamilyOfElements.Compatible x
[PROOFSTEP]
intro h Y₁ Y₂ Z g₁ g₂ f₁ f₂ h₁ h₂ k
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
h : FamilyOfElements.SieveCompatible x
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
h₁ : S.arrows f₁
h₂ : S.arrows f₂
k : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ P.map g₁.op (x f₁ h₁) = P.map g₂.op (x f₂ h₂)
[PROOFSTEP]
simp_rw [← h f₁ g₁ h₁, ← h f₂ g₂ h₂]
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P S.arrows
h : FamilyOfElements.SieveCompatible x
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
h₁ : S.arrows f₁
h₂ : S.arrows f₂
k : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ x (g₁ ≫ f₁) (_ : S.arrows (g₁ ≫ f₁)) = x (g₂ ≫ f₂) (_ : S.arrows (g₂ ≫ f₂))
[PROOFSTEP]
congr
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P (generate R).arrows
t : FamilyOfElements.Compatible x
⊢ FamilyOfElements.sieveExtend (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) = x
[PROOFSTEP]
rw [compatible_iff_sieveCompatible] at t 
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P (generate R).arrows
t : FamilyOfElements.SieveCompatible x
⊢ FamilyOfElements.sieveExtend (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) = x
[PROOFSTEP]
funext _ _ h
[GOAL]
case h.h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P (generate R).arrows
t : FamilyOfElements.SieveCompatible x
x✝¹ : C
x✝ : x✝¹ ⟶ X
h : (generate R).arrows x✝
⊢ FamilyOfElements.sieveExtend (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) x✝ h = x x✝ h
[PROOFSTEP]
apply (t _ _ _).symm.trans
[GOAL]
case h.h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P (generate R).arrows
t : FamilyOfElements.SieveCompatible x
x✝¹ : C
x✝ : x✝¹ ⟶ X
h : (generate R).arrows x✝
⊢ x
      (Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫
        Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫ g = x✝))
      (_ :
        (generate R).arrows
          (Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫
            Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫ g = x✝))) =
    x x✝ h
[PROOFSTEP]
congr
[GOAL]
case h.h.h.e_f
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P (generate R).arrows
t : FamilyOfElements.SieveCompatible x
x✝¹ : C
x✝ : x✝¹ ⟶ X
h : (generate R).arrows x✝
⊢ Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫
      Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h_1 g, R g ∧ h_1 ≫ g = x✝) ≫ g = x✝) =
    x✝
[PROOFSTEP]
exact h.choose_spec.choose_spec.choose_spec.2
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x₁ x₂ : FamilyOfElements P (generate R).arrows
t₁ : FamilyOfElements.Compatible x₁
t₂ : FamilyOfElements.Compatible x₂
h :
  FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₁ =
    FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₂
⊢ x₁ = x₂
[PROOFSTEP]
rw [← extend_restrict t₁, ← extend_restrict t₂]
  -- porting note: congr fails to make progress
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x₁ x₂ : FamilyOfElements P (generate R).arrows
t₁ : FamilyOfElements.Compatible x₁
t₂ : FamilyOfElements.Compatible x₂
h :
  FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₁ =
    FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₂
⊢ FamilyOfElements.sieveExtend (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₁) =
    FamilyOfElements.sieveExtend (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₂)
[PROOFSTEP]
apply congr_arg
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x₁ x₂ : FamilyOfElements P (generate R).arrows
t₁ : FamilyOfElements.Compatible x₁
t₂ : FamilyOfElements.Compatible x₂
h :
  FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₁ =
    FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₂
⊢ FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₁ =
    FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x₂
[PROOFSTEP]
exact h
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
S : Sieve X
x : FamilyOfElements P S.arrows
t : Compatible x
f : Y ⟶ X
hf : S.arrows f
Z : C
g : Z ⟶ Y
⊢ x (g ≫ f) (_ : S.arrows (g ≫ f)) = P.map g.op (x f hf)
[PROOFSTEP]
simpa using t (𝟙 _) g (S.downward_closed hf g) hf (id_comp _)
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : D ⥤ C
Z : D
T : Presieve (F.obj Z)
x : FamilyOfElements P T
h : Compatible x
⊢ Compatible (FamilyOfElements.functorPullback F x)
[PROOFSTEP]
intro Z₁ Z₂ W g₁ g₂ f₁ f₂ h₁ h₂ eq
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : D ⥤ C
Z : D
T : Presieve (F.obj Z)
x : FamilyOfElements P T
h : Compatible x
Z₁ Z₂ W : D
g₁ : W ⟶ Z₁
g₂ : W ⟶ Z₂
f₁ : Z₁ ⟶ Z
f₂ : Z₂ ⟶ Z
h₁ : Presieve.functorPullback F T f₁
h₂ : Presieve.functorPullback F T f₂
eq : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ (F.op ⋙ P).map g₁.op (FamilyOfElements.functorPullback F x f₁ h₁) =
    (F.op ⋙ P).map g₂.op (FamilyOfElements.functorPullback F x f₂ h₂)
[PROOFSTEP]
exact h (F.map g₁) (F.map g₂) h₁ h₂ (by simp only [← F.map_comp, eq])
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : D ⥤ C
Z : D
T : Presieve (F.obj Z)
x : FamilyOfElements P T
h : Compatible x
Z₁ Z₂ W : D
g₁ : W ⟶ Z₁
g₂ : W ⟶ Z₂
f₁ : Z₁ ⟶ Z
f₂ : Z₂ ⟶ Z
h₁ : Presieve.functorPullback F T f₁
h₂ : Presieve.functorPullback F T f₂
eq : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ F.map g₁ ≫ F.map f₁ = F.map g₂ ≫ F.map f₂
[PROOFSTEP]
simp only [← F.map_comp, eq]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y✝ : C
S : Sieve X✝
R : Presieve X✝
J J₂ : GrothendieckTopology C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : D ⥤ C
X : D
T : Presieve X
x : FamilyOfElements (F.op ⋙ P) T
Y : C
f : Y ⟶ F.obj X
h : Presieve.functorPushforward F T f
⊢ P.obj (op Y)
[PROOFSTEP]
obtain ⟨Z, g, h, h₁, _⟩ := getFunctorPushforwardStructure h
[GOAL]
case mk
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y✝ : C
S : Sieve X✝
R : Presieve X✝
J J₂ : GrothendieckTopology C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : D ⥤ C
X : D
T : Presieve X
x : FamilyOfElements (F.op ⋙ P) T
Y : C
f : Y ⟶ F.obj X
h✝ : Presieve.functorPushforward F T f
Z : D
g : Z ⟶ X
h : Y ⟶ F.obj Z
h₁ : T g
fac✝ : f = h ≫ F.map g
⊢ P.obj (op Y)
[PROOFSTEP]
exact P.map h.op (x g h₁)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : Compatible x
⊢ Compatible (FamilyOfElements.pullback f x)
[PROOFSTEP]
simp only [compatible_iff_sieveCompatible] at h ⊢
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : SieveCompatible x
⊢ SieveCompatible (FamilyOfElements.pullback f x)
[PROOFSTEP]
intro W Z f₁ f₂ hf
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : SieveCompatible x
W Z : C
f₁ : W ⟶ Y
f₂ : Z ⟶ W
hf : (Sieve.pullback f S).arrows f₁
⊢ FamilyOfElements.pullback f x (f₂ ≫ f₁) (_ : (Sieve.pullback f S).arrows (f₂ ≫ f₁)) =
    P.map f₂.op (FamilyOfElements.pullback f x f₁ hf)
[PROOFSTEP]
unfold FamilyOfElements.pullback
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : SieveCompatible x
W Z : C
f₁ : W ⟶ Y
f₂ : Z ⟶ W
hf : (Sieve.pullback f S).arrows f₁
⊢ x ((f₂ ≫ f₁) ≫ f) (_ : (Sieve.pullback f S).arrows (f₂ ≫ f₁)) = P.map f₂.op (x (f₁ ≫ f) hf)
[PROOFSTEP]
rw [← h (f₁ ≫ f) f₂ hf]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : SieveCompatible x
W Z : C
f₁ : W ⟶ Y
f₂ : Z ⟶ W
hf : (Sieve.pullback f S).arrows f₁
⊢ x ((f₂ ≫ f₁) ≫ f) (_ : (Sieve.pullback f S).arrows (f₂ ≫ f₁)) = x (f₂ ≫ f₁ ≫ f) (_ : S.arrows (f₂ ≫ f₁ ≫ f))
[PROOFSTEP]
congr 1
[GOAL]
case e_f
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : Y ⟶ X
x : FamilyOfElements P S.arrows
h : SieveCompatible x
W Z : C
f₁ : W ⟶ Y
f₂ : Z ⟶ W
hf : (Sieve.pullback f S).arrows f₁
⊢ (f₂ ≫ f₁) ≫ f = f₂ ≫ f₁ ≫ f
[PROOFSTEP]
simp only [assoc]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : P ⟶ Q
x : FamilyOfElements P R
h : Compatible x
⊢ Compatible (FamilyOfElements.compPresheafMap f x)
[PROOFSTEP]
intro Z₁ Z₂ W g₁ g₂ f₁ f₂ h₁ h₂ eq
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : P ⟶ Q
x : FamilyOfElements P R
h : Compatible x
Z₁ Z₂ W : C
g₁ : W ⟶ Z₁
g₂ : W ⟶ Z₂
f₁ : Z₁ ⟶ X
f₂ : Z₂ ⟶ X
h₁ : R f₁
h₂ : R f₂
eq : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ Q.map g₁.op (FamilyOfElements.compPresheafMap f x f₁ h₁) = Q.map g₂.op (FamilyOfElements.compPresheafMap f x f₂ h₂)
[PROOFSTEP]
unfold FamilyOfElements.compPresheafMap
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
f : P ⟶ Q
x : FamilyOfElements P R
h : Compatible x
Z₁ Z₂ W : C
g₁ : W ⟶ Z₁
g₂ : W ⟶ Z₂
f₁ : Z₁ ⟶ X
f₂ : Z₂ ⟶ X
h₁ : R f₁
h₂ : R f₂
eq : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ Q.map g₁.op (NatTrans.app f (op Z₁) (x f₁ h₁)) = Q.map g₂.op (NatTrans.app f (op Z₂) (x f₂ h₂))
[PROOFSTEP]
rwa [← FunctorToTypes.naturality, ← FunctorToTypes.naturality, h]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
f : P ⟶ Q
h : IsAmalgamation x t
⊢ IsAmalgamation (FamilyOfElements.compPresheafMap f x) (NatTrans.app f (op X) t)
[PROOFSTEP]
intro Y g hg
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
f : P ⟶ Q
h : IsAmalgamation x t
Y : C
g : Y ⟶ X
hg : R g
⊢ Q.map g.op (NatTrans.app f (op X) t) = FamilyOfElements.compPresheafMap f x g hg
[PROOFSTEP]
dsimp [FamilyOfElements.compPresheafMap]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
f : P ⟶ Q
h : IsAmalgamation x t
Y : C
g : Y ⟶ X
hg : R g
⊢ Q.map g.op (NatTrans.app f (op X) t) = NatTrans.app f (op Y) (x g hg)
[PROOFSTEP]
change (f.app _ ≫ Q.map _) _ = _
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
f : P ⟶ Q
h : IsAmalgamation x t
Y : C
g : Y ⟶ X
hg : R g
⊢ (NatTrans.app f (op X) ≫ Q.map g.op) t = NatTrans.app f (op Y) (x g hg)
[PROOFSTEP]
rw [← f.naturality, types_comp_apply, h g hg]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
h : ∃ t, FamilyOfElements.IsAmalgamation x t
⊢ FamilyOfElements.Compatible x
[PROOFSTEP]
cases' h with t ht
[GOAL]
case intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
⊢ FamilyOfElements.Compatible x
[PROOFSTEP]
intro Y₁ Y₂ Z g₁ g₂ f₁ f₂ h₁ h₂ comm
[GOAL]
case intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
h₁ : R f₁
h₂ : R f₂
comm : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ P.map g₁.op (x f₁ h₁) = P.map g₂.op (x f₂ h₂)
[PROOFSTEP]
rw [← ht _ h₁, ← ht _ h₂, ← FunctorToTypes.map_comp_apply, ← op_comp, comm]
[GOAL]
case intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
h₁ : R f₁
h₂ : R f₂
comm : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ P.map (g₂ ≫ f₂).op t = P.map g₂.op (P.map f₂.op t)
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
⊢ FamilyOfElements.IsAmalgamation (FamilyOfElements.sieveExtend x) t
[PROOFSTEP]
intro Y f hf
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
Y : C
f : Y ⟶ X
hf : (generate R).arrows f
⊢ P.map f.op t = FamilyOfElements.sieveExtend x f hf
[PROOFSTEP]
dsimp [FamilyOfElements.sieveExtend]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
x : FamilyOfElements P R
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
Y : C
f : Y ⟶ X
hf : (generate R).arrows f
⊢ P.map f.op t =
    P.map (Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f)).op
      (x (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f))
        (_ : R (Exists.choose (_ : ∃ g, R g ∧ Exists.choose (_ : ∃ h g, R g ∧ h ≫ g = f) ≫ g = f))))
[PROOFSTEP]
rw [← ht _, ← FunctorToTypes.map_comp_apply, ← op_comp, hf.choose_spec.choose_spec.choose_spec.2]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ IsSeparatedFor P R ↔ IsSeparatedFor P (generate R).arrows
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ IsSeparatedFor P R → IsSeparatedFor P (generate R).arrows
[PROOFSTEP]
intro h x t₁ t₂ ht₁ ht₂
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P R
x : FamilyOfElements P (generate R).arrows
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ t₁ = t₂
[PROOFSTEP]
apply h (x.restrict (le_generate R)) t₁ t₂ _ _
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P R
x : FamilyOfElements P (generate R).arrows
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ FamilyOfElements.IsAmalgamation (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) t₁
[PROOFSTEP]
exact isAmalgamation_restrict _ x t₁ ht₁
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P R
x : FamilyOfElements P (generate R).arrows
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ FamilyOfElements.IsAmalgamation (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) t₂
[PROOFSTEP]
exact isAmalgamation_restrict _ x t₂ ht₂
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ IsSeparatedFor P (generate R).arrows → IsSeparatedFor P R
[PROOFSTEP]
intro h x t₁ t₂ ht₁ ht₂
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P (generate R).arrows
x : FamilyOfElements P R
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ t₁ = t₂
[PROOFSTEP]
apply h x.sieveExtend
[GOAL]
case mpr.a
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P (generate R).arrows
x : FamilyOfElements P R
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ FamilyOfElements.IsAmalgamation (FamilyOfElements.sieveExtend x) t₁
[PROOFSTEP]
exact isAmalgamation_sieveExtend x t₁ ht₁
[GOAL]
case mpr.a
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
h : IsSeparatedFor P (generate R).arrows
x : FamilyOfElements P R
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ FamilyOfElements.IsAmalgamation (FamilyOfElements.sieveExtend x) t₂
[PROOFSTEP]
exact isAmalgamation_sieveExtend x t₂ ht₂
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ t₁ = t₂
[PROOFSTEP]
have q₁ := h₁ (𝟙 X) (by tauto)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ ⊤ (𝟙 X)
[PROOFSTEP]
tauto
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
q₁ : P.map (𝟙 X).op t₁ = x (𝟙 X) (_ : True)
⊢ t₁ = t₂
[PROOFSTEP]
have q₂ := h₂ (𝟙 X) (by tauto)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
q₁ : P.map (𝟙 X).op t₁ = x (𝟙 X) (_ : True)
⊢ ⊤ (𝟙 X)
[PROOFSTEP]
tauto
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
q₁ : P.map (𝟙 X).op t₁ = x (𝟙 X) (_ : True)
q₂ : P.map (𝟙 X).op t₂ = x (𝟙 X) (_ : True)
⊢ t₁ = t₂
[PROOFSTEP]
simp only [op_id, FunctorToTypes.map_id_apply] at q₁ q₂ 
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P ⊤
t₁ t₂ : P.obj (op X)
h₁ : FamilyOfElements.IsAmalgamation x t₁
h₂ : FamilyOfElements.IsAmalgamation x t₂
q₁ : t₁ = x (𝟙 X) (_ : True)
q₂ : t₂ = x (𝟙 X) (_ : True)
⊢ t₁ = t₂
[PROOFSTEP]
rw [q₁, q₂]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
⊢ { x // FamilyOfElements.Compatible x }
[PROOFSTEP]
refine' ⟨fun Y f hf => _, _⟩
[GOAL]
case refine'_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ P.obj (op Y)
[PROOFSTEP]
apply α.app (op Y) ⟨_, hf⟩
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
⊢ FamilyOfElements.Compatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }
[PROOFSTEP]
rw [compatible_iff_sieveCompatible]
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
⊢ FamilyOfElements.SieveCompatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }
[PROOFSTEP]
intro Y Z f g hf
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ (fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) Z (g ≫ f) (_ : S.arrows (g ≫ f)) =
    P.map g.op ((fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) Y f hf)
[PROOFSTEP]
dsimp
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ NatTrans.app α (op Z) { val := g ≫ f, property := (_ : S.arrows (g ≫ f)) } =
    P.map g.op (NatTrans.app α (op Y) { val := f, property := hf })
[PROOFSTEP]
rw [← FunctorToTypes.naturality _ _ α g.op]
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ NatTrans.app α (op Z) { val := g ≫ f, property := (_ : S.arrows (g ≫ f)) } =
    NatTrans.app α (op Z) ((functor S).map g.op { val := f, property := hf })
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
t : { x // FamilyOfElements.Compatible x }
Y Z : Cᵒᵖ
g : Y ⟶ Z
⊢ (functor S).map g ≫ (fun Y f => ↑t ↑f (_ : S.arrows ↑f)) Z = (fun Y f => ↑t ↑f (_ : S.arrows ↑f)) Y ≫ P.map g
[PROOFSTEP]
ext ⟨f, hf⟩
[GOAL]
case h.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
t : { x // FamilyOfElements.Compatible x }
Y Z : Cᵒᵖ
g : Y ⟶ Z
f : Y.unop ⟶ X
hf : S.arrows f
⊢ ((functor S).map g ≫ (fun Y f => ↑t ↑f (_ : S.arrows ↑f)) Z) { val := f, property := hf } =
    ((fun Y f => ↑t ↑f (_ : S.arrows ↑f)) Y ≫ P.map g) { val := f, property := hf }
[PROOFSTEP]
apply t.2.to_sieveCompatible _
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
⊢ (fun t => NatTrans.mk fun Y f => ↑t ↑f (_ : S.arrows ↑f))
      ((fun α =>
          { val := fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf },
            property :=
              (_ : FamilyOfElements.Compatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) })
        α) =
    α
[PROOFSTEP]
ext X ⟨_, _⟩
[GOAL]
case w.h.h.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S : Sieve X✝
R : Presieve X✝
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
α : functor S ⟶ P
X : Cᵒᵖ
val✝ : X.unop ⟶ X✝
property✝ : S.arrows val✝
⊢ NatTrans.app
      ((fun t => NatTrans.mk fun Y f => ↑t ↑f (_ : S.arrows ↑f))
        ((fun α =>
            { val := fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf },
              property :=
                (_ : FamilyOfElements.Compatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) })
          α))
      X { val := val✝, property := property✝ } =
    NatTrans.app α X { val := val✝, property := property✝ }
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ Function.RightInverse (fun t => NatTrans.mk fun Y f => ↑t ↑f (_ : S.arrows ↑f)) fun α =>
    { val := fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf },
      property := (_ : FamilyOfElements.Compatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) }
[PROOFSTEP]
rintro ⟨x, hx⟩
[GOAL]
case mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : FamilyOfElements P S.arrows
hx : FamilyOfElements.Compatible x
⊢ (fun α =>
        { val := fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf },
          property :=
            (_ : FamilyOfElements.Compatible fun Y f hf => NatTrans.app α (op Y) { val := f, property := hf }) })
      ((fun t => NatTrans.mk fun Y f => ↑t ↑f (_ : S.arrows ↑f)) { val := x, property := hx }) =
    { val := x, property := hx }
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
⊢ functorInclusion S ≫ g = x ↔ FamilyOfElements.IsAmalgamation (↑(↑natTransEquivCompatibleFamily x)) (↑yonedaEquiv g)
[PROOFSTEP]
change _ ↔ ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S f), P.map f.op (yonedaEquiv g) = x.app (op Y) ⟨f, h⟩
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
⊢ functorInclusion S ≫ g = x ↔
    ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
      P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
⊢ functorInclusion S ≫ g = x →
    ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
      P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
[PROOFSTEP]
rintro rfl Y f hf
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
g : yoneda.obj X ⟶ P
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ P.map f.op (↑yonedaEquiv g) = NatTrans.app (functorInclusion S ≫ g) (op Y) { val := f, property := hf }
[PROOFSTEP]
rw [yonedaEquiv_naturality]
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
g : yoneda.obj X ⟶ P
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ ↑yonedaEquiv (yoneda.map f ≫ g) = NatTrans.app (functorInclusion S ≫ g) (op Y) { val := f, property := hf }
[PROOFSTEP]
dsimp
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
g : yoneda.obj X ⟶ P
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ NatTrans.app g (op Y) (𝟙 Y ≫ f) = NatTrans.app g (op Y) f
[PROOFSTEP]
simp
  -- See note [dsimp, simp].
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
⊢ (∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
      P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }) →
    functorInclusion S ≫ g = x
[PROOFSTEP]
intro h
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
h :
  ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
    P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
⊢ functorInclusion S ≫ g = x
[PROOFSTEP]
ext Y ⟨f, hf⟩
[GOAL]
case mpr.w.h.h.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
h :
  ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
    P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
Y : Cᵒᵖ
f : Y.unop ⟶ X
hf : S.arrows f
⊢ NatTrans.app (functorInclusion S ≫ g) Y { val := f, property := hf } = NatTrans.app x Y { val := f, property := hf }
[PROOFSTEP]
convert h f hf
[GOAL]
case h.e'_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
h :
  ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
    P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
Y : Cᵒᵖ
f : Y.unop ⟶ X
hf : S.arrows f
e_1✝ : P.obj Y = P.obj (op Y.unop)
⊢ NatTrans.app (functorInclusion S ≫ g) Y { val := f, property := hf } = P.map f.op (↑yonedaEquiv g)
[PROOFSTEP]
rw [yonedaEquiv_naturality]
[GOAL]
case h.e'_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : functor S ⟶ P
g : yoneda.obj X ⟶ P
h :
  ∀ ⦃Y : C⦄ (f : Y ⟶ X) (h : S.arrows f),
    P.map f.op (↑yonedaEquiv g) = NatTrans.app x (op Y) { val := f, property := h }
Y : Cᵒᵖ
f : Y.unop ⟶ X
hf : S.arrows f
e_1✝ : P.obj Y = P.obj (op Y.unop)
⊢ NatTrans.app (functorInclusion S ≫ g) Y { val := f, property := hf } = ↑yonedaEquiv (yoneda.map f ≫ g)
[PROOFSTEP]
simp [yonedaEquiv]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ IsSheafFor P S.arrows ↔ YonedaSheafCondition P S
[PROOFSTEP]
rw [IsSheafFor, YonedaSheafCondition]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ (∀ (x : FamilyOfElements P S.arrows), FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∀ (f : functor S ⟶ P), ∃! g, functorInclusion S ≫ g = f
[PROOFSTEP]
simp_rw [extension_iff_amalgamation]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ (∀ (x : FamilyOfElements P S.arrows), FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∀ (f : functor S ⟶ P), ∃! g, FamilyOfElements.IsAmalgamation (↑(↑natTransEquivCompatibleFamily f)) (↑yonedaEquiv g)
[PROOFSTEP]
rw [Equiv.forall_congr_left' natTransEquivCompatibleFamily]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ (∀ (x : FamilyOfElements P S.arrows), FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∀ (y : { x // FamilyOfElements.Compatible x }),
      ∃! g,
        FamilyOfElements.IsAmalgamation (↑(↑natTransEquivCompatibleFamily (↑natTransEquivCompatibleFamily.symm y)))
          (↑yonedaEquiv g)
[PROOFSTEP]
rw [Subtype.forall]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ (∀ (x : FamilyOfElements P S.arrows), FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∀ (a : FamilyOfElements P S.arrows) (b : FamilyOfElements.Compatible a),
      ∃! g,
        FamilyOfElements.IsAmalgamation
          (↑(↑natTransEquivCompatibleFamily (↑natTransEquivCompatibleFamily.symm { val := a, property := b })))
          (↑yonedaEquiv g)
[PROOFSTEP]
apply ball_congr
[GOAL]
case H
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
⊢ ∀ (x : FamilyOfElements P S.arrows) (h : FamilyOfElements.Compatible x),
    (∃! t, FamilyOfElements.IsAmalgamation x t) ↔
      ∃! g,
        FamilyOfElements.IsAmalgamation
          (↑(↑natTransEquivCompatibleFamily (↑natTransEquivCompatibleFamily.symm { val := x, property := h })))
          (↑yonedaEquiv g)
[PROOFSTEP]
intro x hx
[GOAL]
case H
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : FamilyOfElements P S.arrows
hx : FamilyOfElements.Compatible x
⊢ (∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∃! g,
      FamilyOfElements.IsAmalgamation
        (↑(↑natTransEquivCompatibleFamily (↑natTransEquivCompatibleFamily.symm { val := x, property := hx })))
        (↑yonedaEquiv g)
[PROOFSTEP]
rw [Equiv.exists_unique_congr_left _]
[GOAL]
case H
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type v₁
x : FamilyOfElements P S.arrows
hx : FamilyOfElements.Compatible x
⊢ (∃! t, FamilyOfElements.IsAmalgamation x t) ↔
    ∃! y,
      FamilyOfElements.IsAmalgamation
        (↑(↑natTransEquivCompatibleFamily (↑natTransEquivCompatibleFamily.symm { val := x, property := hx }))) y
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ (IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    IsSheafFor P R
[PROOFSTEP]
rw [IsSeparatedFor, ← forall_and]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ (∀ (x : FamilyOfElements P R),
      (∀ (t₁ t₂ : P.obj (op X)),
          FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
        (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t)) ↔
    IsSheafFor P R
[PROOFSTEP]
apply forall_congr'
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
⊢ ∀ (a : FamilyOfElements P R),
    (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation a t₁ → FamilyOfElements.IsAmalgamation a t₂ → t₁ = t₂) ∧
        (FamilyOfElements.Compatible a → ∃ t, FamilyOfElements.IsAmalgamation a t) ↔
      FamilyOfElements.Compatible a → ∃! t, FamilyOfElements.IsAmalgamation a t
[PROOFSTEP]
intro x
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
⊢ (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
      (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
constructor
[GOAL]
case h.mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
⊢ (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
      (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) →
    FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro z hx
[GOAL]
case h.mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
z :
  (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
    (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t)
hx : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
exact exists_unique_of_exists_of_unique (z.2 hx) z.1
[GOAL]
case h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
⊢ (FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t) →
    (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
      (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t)
[PROOFSTEP]
intro h
[GOAL]
case h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
h : FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
⊢ (∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂) ∧
    (FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t)
[PROOFSTEP]
refine' ⟨_, ExistsUnique.exists ∘ h⟩
[GOAL]
case h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
h : FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
⊢ ∀ (t₁ t₂ : P.obj (op X)), FamilyOfElements.IsAmalgamation x t₁ → FamilyOfElements.IsAmalgamation x t₂ → t₁ = t₂
[PROOFSTEP]
intro t₁ t₂ ht₁ ht₂
[GOAL]
case h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
h : FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ t₁ = t₂
[PROOFSTEP]
apply (h _).unique ht₁ ht₂
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
x : FamilyOfElements P R
h : FamilyOfElements.Compatible x → ∃! t, FamilyOfElements.IsAmalgamation x t
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ FamilyOfElements.Compatible x
[PROOFSTEP]
exact is_compatible_of_exists_amalgamation x ⟨_, ht₂⟩
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
t : IsSeparatedFor P R
⊢ (∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) →
    IsSheafFor P R
[PROOFSTEP]
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
t : IsSeparatedFor P R
⊢ (∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) →
    IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
exact And.intro t
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ IsSheafFor P R ↔ IsSheafFor P (generate R).arrows
[PROOFSTEP]
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    IsSheafFor P (generate R).arrows
[PROOFSTEP]
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    IsSeparatedFor P (generate R).arrows ∧
      ∀ (x : FamilyOfElements P (generate R).arrows),
        FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
rw [← isSeparatedFor_iff_generate]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P (generate R).arrows),
        FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
apply and_congr (Iff.refl _)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    ∀ (x : FamilyOfElements P (generate R).arrows),
      FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) →
    ∀ (x : FamilyOfElements P (generate R).arrows),
      FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro q x hx
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q : ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P (generate R).arrows
hx : FamilyOfElements.Compatible x
⊢ ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q : ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P (generate R).arrows
hx : FamilyOfElements.Compatible x
⊢ ∀ (a : P.obj (op X)),
    FamilyOfElements.IsAmalgamation (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) a →
      FamilyOfElements.IsAmalgamation x a
[PROOFSTEP]
intro t ht
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q : ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P (generate R).arrows
hx : FamilyOfElements.Compatible x
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation (FamilyOfElements.restrict (_ : R ≤ (generate R).arrows) x) t
⊢ FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
simpa [hx] using isAmalgamation_sieveExtend _ _ ht
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
⊢ (∀ (x : FamilyOfElements P (generate R).arrows),
      FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) →
    ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro q x hx
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q :
  ∀ (x : FamilyOfElements P (generate R).arrows),
    FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
⊢ ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
apply Exists.imp _ (q _ hx.sieveExtend)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q :
  ∀ (x : FamilyOfElements P (generate R).arrows),
    FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
⊢ ∀ (a : P.obj (op X)),
    FamilyOfElements.IsAmalgamation (FamilyOfElements.sieveExtend x) a → FamilyOfElements.IsAmalgamation x a
[PROOFSTEP]
intro t ht
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
q :
  ∀ (x : FamilyOfElements P (generate R).arrows),
    FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation (FamilyOfElements.sieveExtend x) t
⊢ FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
simpa [hx] using isAmalgamation_restrict (le_generate R) _ _ ht
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (singleton (𝟙 X))
[PROOFSTEP]
intro x _
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
[GOAL]
case refine'_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (x (𝟙 X) (_ : singleton (𝟙 X) (𝟙 X)))
[PROOFSTEP]
rintro _ _ ⟨rfl, rfl⟩
[GOAL]
case refine'_1.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
Y : C
⊢ P.map (𝟙 X).op (x (𝟙 X) (_ : singleton (𝟙 X) (𝟙 X))) = x (𝟙 X) (_ : singleton' (𝟙 X) (𝟙 X))
[PROOFSTEP]
simp
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
⊢ ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = x (𝟙 X) (_ : singleton (𝟙 X) (𝟙 X))
[PROOFSTEP]
intro t ht
[GOAL]
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
t : P.obj (op X)
ht : FamilyOfElements.IsAmalgamation x t
⊢ t = x (𝟙 X) (_ : singleton (𝟙 X) (𝟙 X))
[PROOFSTEP]
simpa using ht _ (Presieve.singleton_self _)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P ⊤.arrows
[PROOFSTEP]
rw [← generate_of_singleton_isSplitEpi (𝟙 X)]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (generate (singleton (𝟙 X))).arrows
[PROOFSTEP]
rw [← isSheafFor_iff_generate]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (singleton (𝟙 X))
[PROOFSTEP]
apply isSheafFor_singleton_iso
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
⊢ IsSheafFor P R → IsSheafFor P' R
[PROOFSTEP]
intro h x hx
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
let x' := x.compPresheafMap i.inv
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
obtain ⟨t, ht1, ht2⟩ := h x' this
[GOAL]
case intro.intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
use i.hom.app _ t
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (NatTrans.app i.hom (op X) t) ∧
    ∀ (y : P'.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = NatTrans.app i.hom (op X) t
[PROOFSTEP]
fconstructor
[GOAL]
case h.left
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (NatTrans.app i.hom (op X) t)
[PROOFSTEP]
convert FamilyOfElements.IsAmalgamation.compPresheafMap i.hom ht1
[GOAL]
case h.e.h.e'_6.h.h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
⊢ x = FamilyOfElements.compPresheafMap i.hom x'
[PROOFSTEP]
simp
[GOAL]
case h.right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
⊢ ∀ (y : P'.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = NatTrans.app i.hom (op X) t
[PROOFSTEP]
intro y hy
[GOAL]
case h.right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
y : P'.obj (op X)
hy : FamilyOfElements.IsAmalgamation x y
⊢ y = NatTrans.app i.hom (op X) t
[PROOFSTEP]
rw [show y = (i.inv.app (op X) ≫ i.hom.app (op X)) y by simp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
y : P'.obj (op X)
hy : FamilyOfElements.IsAmalgamation x y
⊢ y = (NatTrans.app i.inv (op X) ≫ NatTrans.app i.hom (op X)) y
[PROOFSTEP]
simp
[GOAL]
case h.right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
x' : FamilyOfElements P R := FamilyOfElements.compPresheafMap i.inv x
this : FamilyOfElements.Compatible x'
t : P.obj (op X)
ht1 : FamilyOfElements.IsAmalgamation x' t
ht2 : ∀ (y : P.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x' t) y → y = t
y : P'.obj (op X)
hy : FamilyOfElements.IsAmalgamation x y
⊢ (NatTrans.app i.inv (op X) ≫ NatTrans.app i.hom (op X)) y = NatTrans.app i.hom (op X) t
[PROOFSTEP]
simp [ht2 (i.inv.app _ y) (FamilyOfElements.IsAmalgamation.compPresheafMap i.inv hy)]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
⊢ IsSheafFor P R
[PROOFSTEP]
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
⊢ IsSeparatedFor P R ∧
    ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
constructor
[GOAL]
case left
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
⊢ IsSeparatedFor P R
[PROOFSTEP]
intro x t₁ t₂ ht₁ ht₂
[GOAL]
case left
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
t₁ t₂ : P.obj (op X)
ht₁ : FamilyOfElements.IsAmalgamation x t₁
ht₂ : FamilyOfElements.IsAmalgamation x t₂
⊢ t₁ = t₂
[PROOFSTEP]
exact hS.isSeparatedFor _ _ _ (isAmalgamation_restrict h x t₁ ht₁) (isAmalgamation_restrict h x t₂ ht₂)
[GOAL]
case right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
⊢ ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro x hx
[GOAL]
case right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
⊢ ∃ t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
use hS.amalgamate _ (hx.restrict h)
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
⊢ FamilyOfElements.IsAmalgamation x
    (IsSheafFor.amalgamate hS (FamilyOfElements.restrict h x)
      (_ : FamilyOfElements.Compatible (FamilyOfElements.restrict h x)))
[PROOFSTEP]
intro W j hj
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
W : C
j : W ⟶ X
hj : R j
⊢ P.map j.op
      (IsSheafFor.amalgamate hS (FamilyOfElements.restrict h x)
        (_ : FamilyOfElements.Compatible (FamilyOfElements.restrict h x))) =
    x j hj
[PROOFSTEP]
apply (trans hj).ext
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
W : C
j : W ⟶ X
hj : R j
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ W⦄,
    (Sieve.pullback j S).arrows f →
      P.map f.op
          (P.map j.op
            (IsSheafFor.amalgamate hS (FamilyOfElements.restrict h x)
              (_ : FamilyOfElements.Compatible (FamilyOfElements.restrict h x)))) =
        P.map f.op (x j hj)
[PROOFSTEP]
intro Y f hf
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
W : C
j : W ⟶ X
hj : R j
Y : C
f : Y ⟶ W
hf : (Sieve.pullback j S).arrows f
⊢ P.map f.op
      (P.map j.op
        (IsSheafFor.amalgamate hS (FamilyOfElements.restrict h x)
          (_ : FamilyOfElements.Compatible (FamilyOfElements.restrict h x)))) =
    P.map f.op (x j hj)
[PROOFSTEP]
rw [← FunctorToTypes.map_comp_apply, ← op_comp, hS.valid_glue (hx.restrict h) _ hf, FamilyOfElements.restrict, ←
  hx (𝟙 _) f (h _ hf) _ (id_comp _)]
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y✝ : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
hS : IsSheafFor P S.arrows
trans : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, R f → IsSeparatedFor P (Sieve.pullback f S).arrows
x : FamilyOfElements P R
hx : FamilyOfElements.Compatible x
W : C
j : W ⟶ X
hj : R j
Y : C
f : Y ⟶ W
hf : (Sieve.pullback j S).arrows f
⊢ x (f ≫ j) (_ : f ≫ j ∈ R) = P.map (𝟙 Y).op (x (f ≫ j) (_ : f ≫ j ∈ R))
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S✝ : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
P : Cᵒᵖ ⥤ Type w
S : Sieve X
R : Presieve X
h : S.arrows ≤ R
trans : ∀ ⦃Y : C⦄ (f : Y ⟶ X), IsSheafFor P (Sieve.pullback f S).arrows
⊢ IsSheafFor P S.arrows
[PROOFSTEP]
simpa using trans (𝟙 _)
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
⊢ IsSheaf (Pretopology.toGrothendieck C K) P ↔
    ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
⊢ IsSheaf (Pretopology.toGrothendieck C K) P →
    ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
[PROOFSTEP]
intro PJ X R hR
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PJ : IsSheaf (Pretopology.toGrothendieck C K) P
X : C
R : Presieve X
hR : R ∈ Pretopology.coverings K X
⊢ IsSheafFor P R
[PROOFSTEP]
rw [isSheafFor_iff_generate]
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PJ : IsSheaf (Pretopology.toGrothendieck C K) P
X : C
R : Presieve X
hR : R ∈ Pretopology.coverings K X
⊢ IsSheafFor P (generate R).arrows
[PROOFSTEP]
apply PJ (Sieve.generate R) ⟨_, hR, le_generate R⟩
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
⊢ (∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R) →
    IsSheaf (Pretopology.toGrothendieck C K) P
[PROOFSTEP]
rintro PK X S ⟨R, hR, RS⟩
[GOAL]
case mpr.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
⊢ IsSheafFor P S.arrows
[PROOFSTEP]
have gRS : ⇑(generate R) ≤ S := by
  apply giGenerate.gc.monotone_u
  rwa [sets_iff_generate]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
⊢ (generate R).arrows ≤ S.arrows
[PROOFSTEP]
apply giGenerate.gc.monotone_u
[GOAL]
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
⊢ generate R ≤ S
[PROOFSTEP]
rwa [sets_iff_generate]
[GOAL]
case mpr.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
gRS : (generate R).arrows ≤ S.arrows
⊢ IsSheafFor P S.arrows
[PROOFSTEP]
apply isSheafFor_subsieve P gRS _
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
gRS : (generate R).arrows ≤ S.arrows
⊢ ∀ ⦃Y : C⦄ (f : Y ⟶ X), IsSheafFor P (Sieve.pullback f (generate R)).arrows
[PROOFSTEP]
intro Y f
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y✝ : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
gRS : (generate R).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
⊢ IsSheafFor P (Sieve.pullback f (generate R)).arrows
[PROOFSTEP]
rw [← pullbackArrows_comm, ← isSheafFor_iff_generate]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y✝ : C
S✝ : Sieve X✝
R✝ : Presieve X✝
J J₂ : GrothendieckTopology C
inst✝ : HasPullbacks C
K : Pretopology C
PK : ∀ {X : C} (R : Presieve X), R ∈ Pretopology.coverings K X → IsSheafFor P R
X : C
S : Sieve X
R : Presieve X
hR : R ∈ Pretopology.coverings K X
RS : R ≤ S.arrows
gRS : (generate R).arrows ≤ S.arrows
Y : C
f : Y ⟶ X
⊢ IsSheafFor P (pullbackArrows f R)
[PROOFSTEP]
exact PK (pullbackArrows f R) (K.pullbacks f R hR)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X✝ Y : C
S : Sieve X✝
R : Presieve X✝
J J₂ : GrothendieckTopology C
X : C
⊢ ∀ (S : Sieve X), S ∈ GrothendieckTopology.sieves ⊥ X → IsSheafFor P S.arrows
[PROOFSTEP]
simp [isSheafFor_top_sieve]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
W : C
x : FamilyOfElements (yoneda.obj W) R
hx : FamilyOfElements.Compatible x
⊢ ∀ ⦃X_1 Y : FullSubcategory fun f => R f.hom⦄ (f : X_1 ⟶ Y),
    (diagram R).map f ≫ (fun f => x f.obj.hom (_ : R f.obj.hom)) Y =
      (fun f => x f.obj.hom (_ : R f.obj.hom)) X_1 ≫ ((Functor.const (FullSubcategory fun f => R f.hom)).obj W).map f
[PROOFSTEP]
intro g₁ g₂ F
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
W : C
x : FamilyOfElements (yoneda.obj W) R
hx : FamilyOfElements.Compatible x
g₁ g₂ : FullSubcategory fun f => R f.hom
F : g₁ ⟶ g₂
⊢ (diagram R).map F ≫ (fun f => x f.obj.hom (_ : R f.obj.hom)) g₂ =
    (fun f => x f.obj.hom (_ : R f.obj.hom)) g₁ ≫ ((Functor.const (FullSubcategory fun f => R f.hom)).obj W).map F
[PROOFSTEP]
simp only [Functor.id_obj, Functor.comp_obj, fullSubcategoryInclusion.obj, Over.forget_obj, Functor.const_obj_obj,
  Functor.comp_map, fullSubcategoryInclusion.map, Over.forget_map, Functor.const_obj_map, Category.comp_id]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
W : C
x : FamilyOfElements (yoneda.obj W) R
hx : FamilyOfElements.Compatible x
g₁ g₂ : FullSubcategory fun f => R f.hom
F : g₁ ⟶ g₂
⊢ F.left ≫ x g₂.obj.hom (_ : R g₂.obj.hom) = x g₁.obj.hom (_ : R g₁.obj.hom)
[PROOFSTEP]
rw [← Category.id_comp (x g₁.obj.hom g₁.property)]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
W : C
x : FamilyOfElements (yoneda.obj W) R
hx : FamilyOfElements.Compatible x
g₁ g₂ : FullSubcategory fun f => R f.hom
F : g₁ ⟶ g₂
⊢ F.left ≫ x g₂.obj.hom (_ : R g₂.obj.hom) = 𝟙 (op ((𝟭 C).obj g₁.obj.left)).unop ≫ x g₁.obj.hom (_ : R g₁.obj.hom)
[PROOFSTEP]
apply hx
[GOAL]
case a
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ : Presieve X
J J₂ : GrothendieckTopology C
R : Presieve X
W : C
x : FamilyOfElements (yoneda.obj W) R
hx : FamilyOfElements.Compatible x
g₁ g₂ : FullSubcategory fun f => R f.hom
F : g₁ ⟶ g₂
⊢ F.1 ≫ g₂.obj.hom = 𝟙 (op ((𝟭 C).obj g₁.obj.left)).unop ≫ g₁.obj.hom
[PROOFSTEP]
simp only [Functor.id_obj, Over.w, Opposite.unop_op, Category.id_comp]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
⊢ FamilyOfElements.Compatible (yonedaFamilyOfElements_fromCocone S.arrows s)
[PROOFSTEP]
intro Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ hgf
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
⊢ (yoneda.obj s.pt).map g₁.op (yonedaFamilyOfElements_fromCocone S.arrows s f₁ hf₁) =
    (yoneda.obj s.pt).map g₂.op (yonedaFamilyOfElements_fromCocone S.arrows s f₂ hf₂)
[PROOFSTEP]
have Hs := s.ι.naturality
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
⊢ (yoneda.obj s.pt).map g₁.op (yonedaFamilyOfElements_fromCocone S.arrows s f₁ hf₁) =
    (yoneda.obj s.pt).map g₂.op (yonedaFamilyOfElements_fromCocone S.arrows s f₂ hf₂)
[PROOFSTEP]
simp only [Functor.id_obj, yoneda_obj_obj, Opposite.unop_op, yoneda_obj_map, Quiver.Hom.unop_op]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
⊢ g₁ ≫ yonedaFamilyOfElements_fromCocone S.arrows s f₁ hf₁ = g₂ ≫ yonedaFamilyOfElements_fromCocone S.arrows s f₂ hf₂
[PROOFSTEP]
dsimp [yonedaFamilyOfElements_fromCocone]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
have hgf₁ : S.arrows (g₁ ≫ f₁) := by exact Sieve.downward_closed S hf₁ g₁
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
⊢ S.arrows (g₁ ≫ f₁)
[PROOFSTEP]
exact Sieve.downward_closed S hf₁ g₁
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
have hgf₂ : S.arrows (g₂ ≫ f₂) := by exact Sieve.downward_closed S hf₂ g₂
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
⊢ S.arrows (g₂ ≫ f₂)
[PROOFSTEP]
exact Sieve.downward_closed S hf₂ g₂
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
let F : (Over.mk (g₁ ≫ f₁) : Over X) ⟶ (Over.mk (g₂ ≫ f₂) : Over X) := (Over.homMk (𝟙 Z))
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
let F₁ : (Over.mk (g₁ ≫ f₁) : Over X) ⟶ (Over.mk f₁ : Over X) := (Over.homMk g₁)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
F₁ : Over.mk (g₁ ≫ f₁) ⟶ Over.mk f₁ := Over.homMk g₁
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
let F₂ : (Over.mk (g₂ ≫ f₂) : Over X) ⟶ (Over.mk f₂ : Over X) := (Over.homMk g₂)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
F₁ : Over.mk (g₁ ≫ f₁) ⟶ Over.mk f₁ := Over.homMk g₁
F₂ : Over.mk (g₂ ≫ f₂) ⟶ Over.mk f₂ := Over.homMk g₂
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
have hF := @Hs ⟨Over.mk (g₁ ≫ f₁), hgf₁⟩ ⟨Over.mk (g₂ ≫ f₂), hgf₂⟩ F
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
F₁ : Over.mk (g₁ ≫ f₁) ⟶ Over.mk f₁ := Over.homMk g₁
F₂ : Over.mk (g₂ ≫ f₂) ⟶ Over.mk f₂ := Over.homMk g₂
hF :
  (diagram S.arrows).map F ≫ NatTrans.app s.ι { obj := Over.mk (g₂ ≫ f₂), property := hgf₂ } =
    NatTrans.app s.ι { obj := Over.mk (g₁ ≫ f₁), property := hgf₁ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
have hF₁ := @Hs ⟨Over.mk (g₁ ≫ f₁), hgf₁⟩ ⟨Over.mk f₁, hf₁⟩ F₁
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
F₁ : Over.mk (g₁ ≫ f₁) ⟶ Over.mk f₁ := Over.homMk g₁
F₂ : Over.mk (g₂ ≫ f₂) ⟶ Over.mk f₂ := Over.homMk g₂
hF :
  (diagram S.arrows).map F ≫ NatTrans.app s.ι { obj := Over.mk (g₂ ≫ f₂), property := hgf₂ } =
    NatTrans.app s.ι { obj := Over.mk (g₁ ≫ f₁), property := hgf₁ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F
hF₁ :
  (diagram S.arrows).map F₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    NatTrans.app s.ι { obj := Over.mk (g₁ ≫ f₁), property := hgf₁ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F₁
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
have hF₂ := @Hs ⟨Over.mk (g₂ ≫ f₂), hgf₂⟩ ⟨Over.mk f₂, hf₂⟩ F₂
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
s : Cocone (diagram S.arrows)
Y₁ Y₂ Z : C
g₁ : Z ⟶ Y₁
g₂ : Z ⟶ Y₂
f₁ : Y₁ ⟶ X
f₂ : Y₂ ⟶ X
hf₁ : S.arrows f₁
hf₂ : S.arrows f₂
hgf : g₁ ≫ f₁ = g₂ ≫ f₂
Hs :
  ∀ ⦃X_1 Y : FullSubcategory fun f => S.arrows f.hom⦄ (f : X_1 ⟶ Y),
    (diagram S.arrows).map f ≫ NatTrans.app s.ι Y =
      NatTrans.app s.ι X_1 ≫ ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map f
hgf₁ : S.arrows (g₁ ≫ f₁)
hgf₂ : S.arrows (g₂ ≫ f₂)
F : Over.mk (g₁ ≫ f₁) ⟶ Over.mk (g₂ ≫ f₂) := Over.homMk (𝟙 Z)
F₁ : Over.mk (g₁ ≫ f₁) ⟶ Over.mk f₁ := Over.homMk g₁
F₂ : Over.mk (g₂ ≫ f₂) ⟶ Over.mk f₂ := Over.homMk g₂
hF :
  (diagram S.arrows).map F ≫ NatTrans.app s.ι { obj := Over.mk (g₂ ≫ f₂), property := hgf₂ } =
    NatTrans.app s.ι { obj := Over.mk (g₁ ≫ f₁), property := hgf₁ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F
hF₁ :
  (diagram S.arrows).map F₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    NatTrans.app s.ι { obj := Over.mk (g₁ ≫ f₁), property := hgf₁ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F₁
hF₂ :
  (diagram S.arrows).map F₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ } =
    NatTrans.app s.ι { obj := Over.mk (g₂ ≫ f₂), property := hgf₂ } ≫
      ((Functor.const (FullSubcategory fun f => S.arrows f.hom)).obj s.pt).map F₂
⊢ g₁ ≫ NatTrans.app s.ι { obj := Over.mk f₁, property := hf₁ } =
    g₂ ≫ NatTrans.app s.ι { obj := Over.mk f₂, property := hf₂ }
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
⊢ (∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows) ↔ Nonempty (IsColimit (cocone S.arrows))
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
⊢ (∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows) → Nonempty (IsColimit (cocone S.arrows))
[PROOFSTEP]
intro H
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
⊢ Nonempty (IsColimit (cocone S.arrows))
[PROOFSTEP]
refine Nonempty.intro ?_
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
⊢ IsColimit (cocone S.arrows)
[PROOFSTEP]
exact
  { desc := fun s =>
      H s.pt (yonedaFamilyOfElements_fromCocone S.arrows s) (yonedaFamily_fromCocone_compatible S s) |>.choose
    fac := by
      intro s f
      replace H := H s.pt (yonedaFamilyOfElements_fromCocone S.arrows s) (yonedaFamily_fromCocone_compatible S s)
      have ht := H.choose_spec.1 f.obj.hom f.property
      aesop_cat
    uniq := by
      intro s Fs HFs
      replace H := H s.pt (yonedaFamilyOfElements_fromCocone S.arrows s) (yonedaFamily_fromCocone_compatible S s)
      apply H.choose_spec.2 Fs
      exact fun _ f hf => HFs ⟨Over.mk f, hf⟩ }
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
⊢ ∀ (s : Cocone (diagram S.arrows)) (j : FullSubcategory fun f => S.arrows f.hom),
    NatTrans.app (cocone S.arrows).ι j ≫
        (fun s =>
            Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
          s =
      NatTrans.app s.ι j
[PROOFSTEP]
intro s f
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
f : FullSubcategory fun f => S.arrows f.hom
⊢ NatTrans.app (cocone S.arrows).ι f ≫
      (fun s =>
          Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
        s =
    NatTrans.app s.ι f
[PROOFSTEP]
replace H := H s.pt (yonedaFamilyOfElements_fromCocone S.arrows s) (yonedaFamily_fromCocone_compatible S s)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H✝ : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
f : FullSubcategory fun f => S.arrows f.hom
H : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t
⊢ NatTrans.app (cocone S.arrows).ι f ≫
      (fun s =>
          Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
        s =
    NatTrans.app s.ι f
[PROOFSTEP]
have ht := H.choose_spec.1 f.obj.hom f.property
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H✝ : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
f : FullSubcategory fun f => S.arrows f.hom
H : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t
ht :
  (yoneda.obj s.pt).map f.obj.hom.op (Exists.choose H) =
    yonedaFamilyOfElements_fromCocone S.arrows s f.obj.hom (_ : S.arrows f.obj.hom)
⊢ NatTrans.app (cocone S.arrows).ι f ≫
      (fun s =>
          Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
        s =
    NatTrans.app s.ι f
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
⊢ ∀ (s : Cocone (diagram S.arrows)) (m : (cocone S.arrows).pt ⟶ s.pt),
    (∀ (j : FullSubcategory fun f => S.arrows f.hom), NatTrans.app (cocone S.arrows).ι j ≫ m = NatTrans.app s.ι j) →
      m =
        (fun s =>
            Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
          s
[PROOFSTEP]
intro s Fs HFs
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
Fs : (cocone S.arrows).pt ⟶ s.pt
HFs : ∀ (j : FullSubcategory fun f => S.arrows f.hom), NatTrans.app (cocone S.arrows).ι j ≫ Fs = NatTrans.app s.ι j
⊢ Fs =
    (fun s =>
        Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
      s
[PROOFSTEP]
replace H := H s.pt (yonedaFamilyOfElements_fromCocone S.arrows s) (yonedaFamily_fromCocone_compatible S s)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H✝ : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
Fs : (cocone S.arrows).pt ⟶ s.pt
HFs : ∀ (j : FullSubcategory fun f => S.arrows f.hom), NatTrans.app (cocone S.arrows).ι j ≫ Fs = NatTrans.app s.ι j
H : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t
⊢ Fs =
    (fun s =>
        Exists.choose (_ : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t))
      s
[PROOFSTEP]
apply H.choose_spec.2 Fs
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H✝ : ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
s : Cocone (diagram S.arrows)
Fs : (cocone S.arrows).pt ⟶ s.pt
HFs : ∀ (j : FullSubcategory fun f => S.arrows f.hom), NatTrans.app (cocone S.arrows).ι j ≫ Fs = NatTrans.app s.ι j
H : ∃! t, FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) t
⊢ FamilyOfElements.IsAmalgamation (yonedaFamilyOfElements_fromCocone S.arrows s) Fs
[PROOFSTEP]
exact fun _ f hf => HFs ⟨Over.mk f, hf⟩
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
⊢ Nonempty (IsColimit (cocone S.arrows)) → ∀ (W : C), IsSheafFor (yoneda.obj W) S.arrows
[PROOFSTEP]
intro H W x hx
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
H : Nonempty (IsColimit (cocone S.arrows))
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
replace H := Classical.choice H
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
H : IsColimit (cocone S.arrows)
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
let s := compatibleYonedaFamily_toCocone S W x hx
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
H : IsColimit (cocone S.arrows)
s : Cocone (diagram S.arrows) := compatibleYonedaFamily_toCocone S.arrows W x hx
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
use H.desc s
[GOAL]
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
H : IsColimit (cocone S.arrows)
s : Cocone (diagram S.arrows) := compatibleYonedaFamily_toCocone S.arrows W x hx
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (IsColimit.desc H s) ∧
    ∀ (y : (yoneda.obj W).obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = IsColimit.desc H s
[PROOFSTEP]
constructor
[GOAL]
case h.left
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
H : IsColimit (cocone S.arrows)
s : Cocone (diagram S.arrows) := compatibleYonedaFamily_toCocone S.arrows W x hx
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (IsColimit.desc H s)
[PROOFSTEP]
exact fun _ f hf => (H.fac s) ⟨Over.mk f, hf⟩
[GOAL]
case h.right
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
S : Sieve X
W : C
x : FamilyOfElements (yoneda.obj W) S.arrows
hx : FamilyOfElements.Compatible x
H : IsColimit (cocone S.arrows)
s : Cocone (diagram S.arrows) := compatibleYonedaFamily_toCocone S.arrows W x hx
⊢ ∀ (y : (yoneda.obj W).obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = IsColimit.desc H s
[PROOFSTEP]
exact fun g hg => H.uniq s g (fun ⟨⟨f, _, hom⟩, hf⟩ => hg hom hf)
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : FirstObj P R
h :
  ∀ (Y : C) (f : Y ⟶ X) (hf : R f),
    Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₁ =
      Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₂
⊢ z₁ = z₂
[PROOFSTEP]
apply Limits.Types.limit_ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : FirstObj P R
h :
  ∀ (Y : C) (f : Y ⟶ X) (hf : R f),
    Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₁ =
      Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₂
⊢ ∀ (j : Discrete ((Y : C) × { f // R f })),
    limit.π (Discrete.functor fun f => P.obj (op f.fst)) j z₁ =
      limit.π (Discrete.functor fun f => P.obj (op f.fst)) j z₂
[PROOFSTEP]
rintro ⟨⟨Y, f, hf⟩⟩
[GOAL]
case w.mk.mk.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : FirstObj P R
h :
  ∀ (Y : C) (f : Y ⟶ X) (hf : R f),
    Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₁ =
      Pi.π (fun f => P.obj (op f.fst)) { fst := Y, snd := { val := f, property := hf } } z₂
Y : C
f : Y ⟶ X
hf : R f
⊢ limit.π (Discrete.functor fun f => P.obj (op f.fst)) { as := { fst := Y, snd := { val := f, property := hf } } } z₁ =
    limit.π (Discrete.functor fun f => P.obj (op f.fst)) { as := { fst := Y, snd := { val := f, property := hf } } } z₂
[PROOFSTEP]
exact h Y f hf
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : SecondObj P S
h :
  ∀ (Y Z : C) (g : Z ⟶ Y) (f : Y ⟶ X) (hf : S.arrows f),
    Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₁ =
      Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₂
⊢ z₁ = z₂
[PROOFSTEP]
apply Limits.Types.limit_ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : SecondObj P S
h :
  ∀ (Y Z : C) (g : Z ⟶ Y) (f : Y ⟶ X) (hf : S.arrows f),
    Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₁ =
      Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₂
⊢ ∀ (j : Discrete ((Y : C) × (Z : C) × (_ : Z ⟶ Y) × { f' // S.arrows f' })),
    limit.π (Discrete.functor fun f => P.obj (op f.snd.fst)) j z₁ =
      limit.π (Discrete.functor fun f => P.obj (op f.snd.fst)) j z₂
[PROOFSTEP]
rintro ⟨⟨Y, Z, g, f, hf⟩⟩
[GOAL]
case w.mk.mk.mk.mk.mk
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
z₁ z₂ : SecondObj P S
h :
  ∀ (Y Z : C) (g : Z ⟶ Y) (f : Y ⟶ X) (hf : S.arrows f),
    Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₁ =
      Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } z₂
Y Z : C
g : Z ⟶ Y
f : Y ⟶ X
hf : S.arrows f
⊢ limit.π (Discrete.functor fun f => P.obj (op f.snd.fst))
      { as := { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } } z₁ =
    limit.π (Discrete.functor fun f => P.obj (op f.snd.fst))
      { as := { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } } z₂
[PROOFSTEP]
apply h
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ forkMap P S.arrows ≫ firstMap P S = forkMap P S.arrows ≫ secondMap P S
[PROOFSTEP]
ext
[GOAL]
case h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
a✝ : P.obj (op X)
Y✝ Z✝ : C
g✝ : Z✝ ⟶ Y✝
f✝ : Y✝ ⟶ X
hf✝ : S.arrows f✝
⊢ Pi.π (fun f => P.obj (op f.snd.fst))
      { fst := Y✝, snd := { fst := Z✝, snd := { fst := g✝, snd := { val := f✝, property := hf✝ } } } }
      ((forkMap P S.arrows ≫ firstMap P S) a✝) =
    Pi.π (fun f => P.obj (op f.snd.fst))
      { fst := Y✝, snd := { fst := Z✝, snd := { fst := g✝, snd := { val := f✝, property := hf✝ } } } }
      ((forkMap P S.arrows ≫ secondMap P S) a✝)
[PROOFSTEP]
simp [firstMap, secondMap, forkMap]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
⊢ Presieve.FamilyOfElements.Compatible ((firstObjEqFamily P S.arrows).hom x) ↔ firstMap P S x = secondMap P S x
[PROOFSTEP]
rw [Presieve.compatible_iff_sieveCompatible]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
⊢ Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x) ↔ firstMap P S x = secondMap P S x
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
⊢ Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x) → firstMap P S x = secondMap P S x
[PROOFSTEP]
intro t
[GOAL]
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
t : Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x)
⊢ firstMap P S x = secondMap P S x
[PROOFSTEP]
apply SecondObj.ext
[GOAL]
case mp.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
t : Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x)
⊢ ∀ (Y Z : C) (g : Z ⟶ Y) (f : Y ⟶ X) (hf : S.arrows f),
    Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } (firstMap P S x) =
      Pi.π (fun f => P.obj (op f.snd.fst))
        { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } (secondMap P S x)
[PROOFSTEP]
intros Y Z g f hf
[GOAL]
case mp.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
t : Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x)
Y Z : C
g : Z ⟶ Y
f : Y ⟶ X
hf : S.arrows f
⊢ Pi.π (fun f => P.obj (op f.snd.fst))
      { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } (firstMap P S x) =
    Pi.π (fun f => P.obj (op f.snd.fst))
      { fst := Y, snd := { fst := Z, snd := { fst := g, snd := { val := f, property := hf } } } } (secondMap P S x)
[PROOFSTEP]
simpa [firstMap, secondMap] using t _ g hf
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
⊢ firstMap P S x = secondMap P S x → Presieve.FamilyOfElements.SieveCompatible ((firstObjEqFamily P S.arrows).hom x)
[PROOFSTEP]
intro t Y Z f g hf
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
t : firstMap P S x = secondMap P S x
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ (firstObjEqFamily P S.arrows).hom x (g ≫ f) (_ : S.arrows (g ≫ f)) =
    P.map g.op ((firstObjEqFamily P S.arrows).hom x f hf)
[PROOFSTEP]
rw [Types.limit_ext_iff'] at t 
[GOAL]
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : FirstObj P S.arrows
t :
  ∀ (j : Discrete ((Y : C) × (Z : C) × (_ : Z ⟶ Y) × { f' // S.arrows f' })),
    limit.π (Discrete.functor fun f => P.obj (op f.snd.fst)) j (firstMap P S x) =
      limit.π (Discrete.functor fun f => P.obj (op f.snd.fst)) j (secondMap P S x)
Y Z : C
f : Y ⟶ X
g : Z ⟶ Y
hf : S.arrows f
⊢ (firstObjEqFamily P S.arrows).hom x (g ≫ f) (_ : S.arrows (g ≫ f)) =
    P.map g.op ((firstObjEqFamily P S.arrows).hom x f hf)
[PROOFSTEP]
simpa [firstMap, secondMap] using t ⟨⟨Y, Z, g, f, hf⟩⟩
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ Presieve.IsSheafFor P S.arrows ↔
    Nonempty
      (IsLimit
        (Fork.ofι (forkMap P S.arrows) (_ : forkMap P S.arrows ≫ firstMap P S = forkMap P S.arrows ≫ secondMap P S)))
[PROOFSTEP]
rw [Types.type_equalizer_iff_unique, ← Equiv.forall_congr_left (firstObjEqFamily P (S : Presieve X)).toEquiv.symm]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ Presieve.IsSheafFor P S.arrows ↔
    ∀ (x : Presieve.FamilyOfElements P S.arrows),
      firstMap P S (↑(firstObjEqFamily P S.arrows).symm x) = secondMap P S (↑(firstObjEqFamily P S.arrows).symm x) →
        ∃! x_1, forkMap P S.arrows x_1 = ↑(firstObjEqFamily P S.arrows).symm x
[PROOFSTEP]
simp_rw [← compatible_iff]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ Presieve.IsSheafFor P S.arrows ↔
    ∀ (x : Presieve.FamilyOfElements P S.arrows),
      Presieve.FamilyOfElements.Compatible ((firstObjEqFamily P S.arrows).hom (↑(firstObjEqFamily P S.arrows).symm x)) →
        ∃! x_1, forkMap P S.arrows x_1 = ↑(firstObjEqFamily P S.arrows).symm x
[PROOFSTEP]
simp only [inv_hom_id_apply, Iso.toEquiv_symm_fun]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ Presieve.IsSheafFor P S.arrows ↔
    ∀ (x : Presieve.FamilyOfElements P S.arrows),
      Presieve.FamilyOfElements.Compatible x → ∃! x_1, forkMap P S.arrows x_1 = (firstObjEqFamily P S.arrows).inv x
[PROOFSTEP]
apply ball_congr
[GOAL]
case H
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
⊢ ∀ (x : Presieve.FamilyOfElements P S.arrows),
    Presieve.FamilyOfElements.Compatible x →
      ((∃! t, Presieve.FamilyOfElements.IsAmalgamation x t) ↔
        ∃! x_1, forkMap P S.arrows x_1 = (firstObjEqFamily P S.arrows).inv x)
[PROOFSTEP]
intro x _
[GOAL]
case H
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
⊢ (∃! t, Presieve.FamilyOfElements.IsAmalgamation x t) ↔
    ∃! x_1, forkMap P S.arrows x_1 = (firstObjEqFamily P S.arrows).inv x
[PROOFSTEP]
apply exists_unique_congr
[GOAL]
case H.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
⊢ ∀ (a : P.obj (op X)),
    Presieve.FamilyOfElements.IsAmalgamation x a ↔ forkMap P S.arrows a = (firstObjEqFamily P S.arrows).inv x
[PROOFSTEP]
intro t
[GOAL]
case H.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t ↔ forkMap P S.arrows t = (firstObjEqFamily P S.arrows).inv x
[PROOFSTEP]
rw [← Iso.toEquiv_symm_fun]
[GOAL]
case H.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t ↔ forkMap P S.arrows t = ↑(firstObjEqFamily P S.arrows).symm x
[PROOFSTEP]
rw [Equiv.eq_symm_apply]
[GOAL]
case H.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t ↔ ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x
[PROOFSTEP]
constructor
[GOAL]
case H.h.mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t → ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x
[PROOFSTEP]
intro q
[GOAL]
case H.h.mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : Presieve.FamilyOfElements.IsAmalgamation x t
⊢ ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x
[PROOFSTEP]
funext Y f hf
[GOAL]
case H.h.mp.h.h.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : Presieve.FamilyOfElements.IsAmalgamation x t
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) f hf = x f hf
[PROOFSTEP]
simpa [firstObjEqFamily, forkMap] using q _ _
[GOAL]
case H.h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x → Presieve.FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro q Y f hf
[GOAL]
case H.h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ P.map f.op t = x f hf
[PROOFSTEP]
rw [← q]
[GOAL]
case H.h.mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
x : Presieve.FamilyOfElements P S.arrows
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) = x
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ P.map f.op t = ↑(firstObjEqFamily P S.arrows).toEquiv (forkMap P S.arrows t) f hf
[PROOFSTEP]
simp [firstObjEqFamily, forkMap]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ forkMap P R ≫ firstMap P R = forkMap P R ≫ secondMap P R
[PROOFSTEP]
dsimp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ forkMap P R ≫ firstMap P R = forkMap P R ≫ secondMap P R
[PROOFSTEP]
ext
[GOAL]
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
b✝ : ((Y : C) × { f // R f }) × (Z : C) × { g // R g }
a✝ : P.obj (op X)
⊢ ((forkMap P R ≫ firstMap P R) ≫ Pi.π (fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) b✝) a✝ =
    ((forkMap P R ≫ secondMap P R) ≫ Pi.π (fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) b✝) a✝
[PROOFSTEP]
simp only [firstMap, secondMap, forkMap]
[GOAL]
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
b✝ : ((Y : C) × { f // R f }) × (Z : C) × { g // R g }
a✝ : P.obj (op X)
⊢ (((Pi.lift fun f => P.map (↑f.snd).op) ≫
          Pi.lift fun x => Pi.π (fun f => P.obj (op f.fst)) x.fst ≫ P.map pullback.fst.op) ≫
        Pi.π (fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) b✝)
      a✝ =
    (((Pi.lift fun f => P.map (↑f.snd).op) ≫
          Pi.lift fun x => Pi.π (fun f => P.obj (op f.fst)) x.snd ≫ P.map pullback.snd.op) ≫
        Pi.π (fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) b✝)
      a✝
[PROOFSTEP]
simp only [limit.lift_π, limit.lift_π_assoc, assoc, Fan.mk_π_app]
[GOAL]
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
b✝ : ((Y : C) × { f // R f }) × (Z : C) × { g // R g }
a✝ : P.obj (op X)
⊢ (P.map (↑b✝.fst.snd).op ≫ P.map pullback.fst.op) a✝ = (P.map (↑b✝.snd.snd).op ≫ P.map pullback.snd.op) a✝
[PROOFSTEP]
rw [← P.map_comp, ← op_comp, pullback.condition]
[GOAL]
case h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
b✝ : ((Y : C) × { f // R f }) × (Z : C) × { g // R g }
a✝ : P.obj (op X)
⊢ P.map (pullback.snd ≫ ↑b✝.snd.snd).op a✝ = (P.map (↑b✝.snd.snd).op ≫ P.map pullback.snd.op) a✝
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
⊢ Presieve.FamilyOfElements.Compatible ((firstObjEqFamily P R).hom x) ↔ firstMap P R x = secondMap P R x
[PROOFSTEP]
rw [Presieve.pullbackCompatible_iff]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
⊢ Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x) ↔ firstMap P R x = secondMap P R x
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
⊢ Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x) → firstMap P R x = secondMap P R x
[PROOFSTEP]
intro t
[GOAL]
case mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
t : Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x)
⊢ firstMap P R x = secondMap P R x
[PROOFSTEP]
apply Limits.Types.limit_ext
[GOAL]
case mp.w
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
t : Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x)
⊢ ∀ (j : Discrete (((Y : C) × { f // R f }) × (Z : C) × { g // R g })),
    limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) j (firstMap P R x) =
      limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) j (secondMap P R x)
[PROOFSTEP]
rintro ⟨⟨Y, f, hf⟩, Z, g, hg⟩
[GOAL]
case mp.w.mk.mk.mk.mk.mk.mk
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
t : Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x)
Y : C
f : Y ⟶ X
hf : R f
Z : C
g : Z ⟶ X
hg : R g
⊢ limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd)))
      { as := ({ fst := Y, snd := { val := f, property := hf } }, { fst := Z, snd := { val := g, property := hg } }) }
      (firstMap P R x) =
    limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd)))
      { as := ({ fst := Y, snd := { val := f, property := hf } }, { fst := Z, snd := { val := g, property := hg } }) }
      (secondMap P R x)
[PROOFSTEP]
simpa [firstMap, secondMap] using t hf hg
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
⊢ firstMap P R x = secondMap P R x → Presieve.FamilyOfElements.PullbackCompatible ((firstObjEqFamily P R).hom x)
[PROOFSTEP]
intro t Y Z f g hf hg
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
t : firstMap P R x = secondMap P R x
Y Z : C
f : Y ⟶ X
g : Z ⟶ X
hf : R f
hg : R g
⊢ P.map pullback.fst.op ((firstObjEqFamily P R).hom x f hf) = P.map pullback.snd.op ((firstObjEqFamily P R).hom x g hg)
[PROOFSTEP]
rw [Types.limit_ext_iff'] at t 
[GOAL]
case mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : FirstObj P R
t :
  ∀ (j : Discrete (((Y : C) × { f // R f }) × (Z : C) × { g // R g })),
    limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) j (firstMap P R x) =
      limit.π (Discrete.functor fun fg => P.obj (op (Limits.pullback ↑fg.fst.snd ↑fg.snd.snd))) j (secondMap P R x)
Y Z : C
f : Y ⟶ X
g : Z ⟶ X
hf : R f
hg : R g
⊢ P.map pullback.fst.op ((firstObjEqFamily P R).hom x f hf) = P.map pullback.snd.op ((firstObjEqFamily P R).hom x g hg)
[PROOFSTEP]
simpa [firstMap, secondMap] using t ⟨⟨⟨Y, f, hf⟩, Z, g, hg⟩⟩
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ Presieve.IsSheafFor P R ↔
    Nonempty (IsLimit (Fork.ofι (forkMap P R) (_ : forkMap P R ≫ firstMap P R = forkMap P R ≫ secondMap P R)))
[PROOFSTEP]
rw [Types.type_equalizer_iff_unique]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ Presieve.IsSheafFor P R ↔ ∀ (y : FirstObj P R), firstMap P R y = secondMap P R y → ∃! x, forkMap P R x = y
[PROOFSTEP]
erw [← Equiv.forall_congr_left (firstObjEqFamily P R).toEquiv.symm]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ Presieve.IsSheafFor P R ↔
    ∀ (x : Presieve.FamilyOfElements P R),
      firstMap P R (↑(firstObjEqFamily P R).symm x) = secondMap P R (↑(firstObjEqFamily P R).symm x) →
        ∃! x_1, forkMap P R x_1 = ↑(firstObjEqFamily P R).symm x
[PROOFSTEP]
simp_rw [← compatible_iff, ← Iso.toEquiv_fun, Equiv.apply_symm_apply]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ Presieve.IsSheafFor P R ↔
    ∀ (x : Presieve.FamilyOfElements P R),
      Presieve.FamilyOfElements.Compatible x → ∃! x_1, forkMap P R x_1 = ↑(firstObjEqFamily P R).symm x
[PROOFSTEP]
apply ball_congr
[GOAL]
case H
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
⊢ ∀ (x : Presieve.FamilyOfElements P R),
    Presieve.FamilyOfElements.Compatible x →
      ((∃! t, Presieve.FamilyOfElements.IsAmalgamation x t) ↔ ∃! x_1, forkMap P R x_1 = ↑(firstObjEqFamily P R).symm x)
[PROOFSTEP]
intro x _
[GOAL]
case H
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
⊢ (∃! t, Presieve.FamilyOfElements.IsAmalgamation x t) ↔ ∃! x_1, forkMap P R x_1 = ↑(firstObjEqFamily P R).symm x
[PROOFSTEP]
apply exists_unique_congr
[GOAL]
case H.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
⊢ ∀ (a : P.obj (op X)), Presieve.FamilyOfElements.IsAmalgamation x a ↔ forkMap P R a = ↑(firstObjEqFamily P R).symm x
[PROOFSTEP]
intro t
[GOAL]
case H.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t ↔ forkMap P R t = ↑(firstObjEqFamily P R).symm x
[PROOFSTEP]
rw [Equiv.eq_symm_apply]
[GOAL]
case H.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t ↔ ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x
[PROOFSTEP]
constructor
[GOAL]
case H.h.mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ Presieve.FamilyOfElements.IsAmalgamation x t → ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x
[PROOFSTEP]
intro q
[GOAL]
case H.h.mp
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : Presieve.FamilyOfElements.IsAmalgamation x t
⊢ ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x
[PROOFSTEP]
funext Y f hf
[GOAL]
case H.h.mp.h.h.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : Presieve.FamilyOfElements.IsAmalgamation x t
Y : C
f : Y ⟶ X
hf : R f
⊢ ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) f hf = x f hf
[PROOFSTEP]
simpa [forkMap] using q _ _
[GOAL]
case H.h.mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
⊢ ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x → Presieve.FamilyOfElements.IsAmalgamation x t
[PROOFSTEP]
intro q Y f hf
[GOAL]
case H.h.mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x
Y : C
f : Y ⟶ X
hf : R f
⊢ P.map f.op t = x f hf
[PROOFSTEP]
rw [← q]
[GOAL]
case H.h.mpr
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
P : Cᵒᵖ ⥤ Type (max v₁ u₁)
X : C
R : Presieve X
S : Sieve X
inst✝ : HasPullbacks C
x : Presieve.FamilyOfElements P R
h✝ : Presieve.FamilyOfElements.Compatible x
t : P.obj (op X)
q : ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) = x
Y : C
f : Y ⟶ X
hf : R f
⊢ P.map f.op t = ↑(firstObjEqFamily P R).toEquiv (forkMap P R t) f hf
[PROOFSTEP]
simp [forkMap]
