l3lab/ntp-mathlib huggingface dataset:
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ R : Presieve X
⊢ IsSheafFor P R ↔ IsSheafFor P (generate R).arrows

Next tactic:
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ R : Presieve X
⊢ (IsSeparatedFor P R ∧
      ∀ (x : FamilyOfElements P R), FamilyOfElements.Compatible x → ∃ t, FamilyOfElements.IsAmalgamation x t) ↔
    IsSheafFor P (generate R).arrows

Next tactic:
rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
rw [← isSeparatedFor_iff_generate]
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
apply and_congr (Iff.refl _)
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
constructor
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · 

Proof state:
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
intro q x hx
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    

Proof state:
case mp
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
intro t ht
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    intro t ht
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
simpa [hx] using isAmalgamation_sieveExtend _ _ ht
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    intro t ht
    simpa [hx] using isAmalgamation_sieveExtend _ _ ht
  · 

Proof state:
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
intro q x hx
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    intro t ht
    simpa [hx] using isAmalgamation_sieveExtend _ _ ht
  · intro q x hx
    

Proof state:
case mpr
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
apply Exists.imp _ (q _ hx.sieveExtend)
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    intro t ht
    simpa [hx] using isAmalgamation_sieveExtend _ _ ht
  · intro q x hx
    apply Exists.imp _ (q _ hx.sieveExtend)
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
intro t ht
/-- C2.1.3 in [Elephant] -/
theorem isSheafFor_iff_generate (R : Presieve X) :
    IsSheafFor P R ↔ IsSheafFor P (generate R : Presieve X) := by
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor]
  rw [← isSeparatedFor_iff_generate]
  apply and_congr (Iff.refl _)
  constructor
  · intro q x hx
    apply Exists.imp _ (q _ (hx.restrict (le_generate R)))
    intro t ht
    simpa [hx] using isAmalgamation_sieveExtend _ _ ht
  · intro q x hx
    apply Exists.imp _ (q _ hx.sieveExtend)
    intro t ht
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R✝ 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

Next tactic:
simpa [hx] using isAmalgamation_restrict (le_generate R) _ _ ht
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (singleton (𝟙 X))

Next tactic:
intro x _
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  intro x _
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t

Next tactic:
refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  intro x _
  refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
  · 

Proof state:
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
P : Cᵒᵖ ⥤ Type w
x : FamilyOfElements P (singleton (𝟙 X))
a✝ : FamilyOfElements.Compatible x
⊢ (fun t => FamilyOfElements.IsAmalgamation x t) (x (𝟙 X) (_ : singleton (𝟙 X) (𝟙 X)))

Next tactic:
rintro _ _ ⟨rfl, rfl⟩
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  intro x _
  refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
  · rintro _ _ ⟨rfl, rfl⟩
    

Proof state:
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
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))

Next tactic:
simp
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  intro x _
  refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
  · rintro _ _ ⟨rfl, rfl⟩
    simp
  · 

Proof state:
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
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))

Next tactic:
intro t ht
/-- Every presheaf is a sheaf for the family {𝟙 X}.

[Elephant] C2.1.5(i)
-/
theorem isSheafFor_singleton_iso (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (Presieve.singleton (𝟙 X)) := by
  intro x _
  refine' ⟨x _ (Presieve.singleton_self _), _, _⟩
  · rintro _ _ ⟨rfl, rfl⟩
    simp
  · intro t ht
    

Proof state:
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
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))

Next tactic:
simpa using ht _ (Presieve.singleton_self _)
/-- Every presheaf is a sheaf for the maximal sieve.

[Elephant] C2.1.5(ii)
-/
theorem isSheafFor_top_sieve (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P ((⊤ : Sieve X) : Presieve X) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P ⊤.arrows

Next tactic:
rw [← generate_of_singleton_isSplitEpi (𝟙 X)]
/-- Every presheaf is a sheaf for the maximal sieve.

[Elephant] C2.1.5(ii)
-/
theorem isSheafFor_top_sieve (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P ((⊤ : Sieve X) : Presieve X) := by
  rw [← generate_of_singleton_isSplitEpi (𝟙 X)]
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (generate (singleton (𝟙 X))).arrows

Next tactic:
rw [← isSheafFor_iff_generate]
/-- Every presheaf is a sheaf for the maximal sieve.

[Elephant] C2.1.5(ii)
-/
theorem isSheafFor_top_sieve (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P ((⊤ : Sieve X) : Presieve X) := by
  rw [← generate_of_singleton_isSplitEpi (𝟙 X)]
  rw [← isSheafFor_iff_generate]
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P✝ Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P : Cᵒᵖ ⥤ Type w
⊢ IsSheafFor P (singleton (𝟙 X))

Next tactic:
apply isSheafFor_singleton_iso
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
⊢ IsSheafFor P R → IsSheafFor P' R

Next tactic:
intro h x hx
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
P' : Cᵒᵖ ⥤ Type w
i : P ≅ P'
h : IsSheafFor P R
x : FamilyOfElements P' R
hx : FamilyOfElements.Compatible x
⊢ ∃! t, FamilyOfElements.IsAmalgamation x t

Next tactic:
let x' := x.compPresheafMap i.inv
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
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

Next tactic:
have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
P Q U : Cᵒᵖ ⥤ Type w
X Y : C
S : Sieve X
R : Presieve X
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

Next tactic:
obtain ⟨t, ht1, ht2⟩ := h x' this
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  obtain ⟨t, ht1, ht2⟩ := h x' this
  

Proof state:
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
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

Next tactic:
use i.hom.app _ t
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  obtain ⟨t, ht1, ht2⟩ := h x' this
  use i.hom.app _ t
  

Proof state:
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
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) (i.hom.app (op X) t) ∧
    ∀ (y : P'.obj (op X)), (fun t => FamilyOfElements.IsAmalgamation x t) y → y = i.hom.app (op X) t

Next tactic:
fconstructor
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  obtain ⟨t, ht1, ht2⟩ := h x' this
  use i.hom.app _ t
  fconstructor
  · 

Proof state:
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
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) (i.hom.app (op X) t)

Next tactic:
convert FamilyOfElements.IsAmalgamation.compPresheafMap i.hom ht1
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  obtain ⟨t, ht1, ht2⟩ := h x' this
  use i.hom.app _ t
  fconstructor
  · convert FamilyOfElements.IsAmalgamation.compPresheafMap i.hom ht1
    

Proof state:
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
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'

Next tactic:
simp
/-- If `P` is a sheaf for `S`, and it is iso to `P'`, then `P'` is a sheaf for `S`. This shows that
"being a sheaf for a presieve" is a mathematical or hygienic property.
-/
theorem isSheafFor_iso {P' : Cᵒᵖ ⥤ Type w} (i : P ≅ P') : IsSheafFor P R → IsSheafFor P' R := by
  intro h x hx
  let x' := x.compPresheafMap i.inv
  have : x'.Compatible := FamilyOfElements.Compatible.compPresheafMap i.inv hx
  obtain ⟨t, ht1, ht2⟩ := h x' this
  use i.hom.app _ t
  fconstructor
  · convert FamilyOfElements.IsAmalgamation.compPresheafMap i.hom ht1
    simp
  · 

Proof state:
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
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 = i.hom.app (op X) t

Next tactic:
intro y hy