l3lab/ntp-mathlib huggingface dataset:
lemma overEquiv_pullback {X : C} {Y₁ Y₂ : Over X} (f : Y₁ ⟶ Y₂) (S : Sieve Y₂) :
    overEquiv _ (S.pullback f) = (overEquiv _ S).pullback f.left := by
  ext Z g
  dsimp [overEquiv, Presieve.functorPushforward]
  constructor
  · rintro ⟨W, a, b, h, rfl⟩
    exact ⟨W, a ≫ f, b, h, by simp⟩
  · rintro ⟨W, a, b, h, w⟩
    let T := Over.mk (b ≫ W.hom)
    let c : T ⟶ Y₁ := Over.homMk g (by dsimp; rw [← Over.w a, ← reassoc_of% w, Over.w f])
    let d : T ⟶ W := Over.homMk b
    refine' ⟨T, c, 𝟙 Z, _, by simp⟩
    rw [show c ≫ f = d ≫ a by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : C
Y₁ Y₂ : Over X
f : Y₁ ⟶ Y₂
S : Sieve Y₂
Z : C
g : Z ⟶ Y₁.left
W : Over X
a : W ⟶ Y₂
b : Z ⟶ W.left
h : S.arrows a
w : g ≫ f.left = b ≫ a.left
T : Over ((Functor.fromPUnit X).obj W.right) := Over.mk (b ≫ W.hom)
c : T ⟶ Y₁ := Over.homMk g
d : T ⟶ W := Over.homMk b
⊢ c ≫ f = d ≫ a

Next tactic:
ext
lemma overEquiv_pullback {X : C} {Y₁ Y₂ : Over X} (f : Y₁ ⟶ Y₂) (S : Sieve Y₂) :
    overEquiv _ (S.pullback f) = (overEquiv _ S).pullback f.left := by
  ext Z g
  dsimp [overEquiv, Presieve.functorPushforward]
  constructor
  · rintro ⟨W, a, b, h, rfl⟩
    exact ⟨W, a ≫ f, b, h, by simp⟩
  · rintro ⟨W, a, b, h, w⟩
    let T := Over.mk (b ≫ W.hom)
    let c : T ⟶ Y₁ := Over.homMk g (by dsimp; rw [← Over.w a, ← reassoc_of% w, Over.w f])
    let d : T ⟶ W := Over.homMk b
    refine' ⟨T, c, 𝟙 Z, _, by simp⟩
    rw [show c ≫ f = d ≫ a by ext; 

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X : C
Y₁ Y₂ : Over X
f : Y₁ ⟶ Y₂
S : Sieve Y₂
Z : C
g : Z ⟶ Y₁.left
W : Over X
a : W ⟶ Y₂
b : Z ⟶ W.left
h : S.arrows a
w : g ≫ f.left = b ≫ a.left
T : Over ((Functor.fromPUnit X).obj W.right) := Over.mk (b ≫ W.hom)
c : T ⟶ Y₁ := Over.homMk g
d : T ⟶ W := Over.homMk b
⊢ (c ≫ f).left = (d ≫ a).left

Next tactic:
exact w
lemma overEquiv_pullback {X : C} {Y₁ Y₂ : Over X} (f : Y₁ ⟶ Y₂) (S : Sieve Y₂) :
    overEquiv _ (S.pullback f) = (overEquiv _ S).pullback f.left := by
  ext Z g
  dsimp [overEquiv, Presieve.functorPushforward]
  constructor
  · rintro ⟨W, a, b, h, rfl⟩
    exact ⟨W, a ≫ f, b, h, by simp⟩
  · rintro ⟨W, a, b, h, w⟩
    let T := Over.mk (b ≫ W.hom)
    let c : T ⟶ Y₁ := Over.homMk g (by dsimp; rw [← Over.w a, ← reassoc_of% w, Over.w f])
    let d : T ⟶ W := Over.homMk b
    refine' ⟨T, c, 𝟙 Z, _, by simp⟩
    rw [show c ≫ f = d ≫ a by ext; exact w]
    

Proof state:
case h.mpr.intro.intro.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X : C
Y₁ Y₂ : Over X
f : Y₁ ⟶ Y₂
S : Sieve Y₂
Z : C
g : Z ⟶ Y₁.left
W : Over X
a : W ⟶ Y₂
b : Z ⟶ W.left
h : S.arrows a
w : g ≫ f.left = b ≫ a.left
T : Over ((Functor.fromPUnit X).obj W.right) := Over.mk (b ≫ W.hom)
c : T ⟶ Y₁ := Over.homMk g
d : T ⟶ W := Over.homMk b
⊢ S.arrows (d ≫ a)

Next tactic:
exact S.downward_closed h _
@[simp]
lemma overEquiv_symm_iff {X : C} {Y : Over X} (S : Sieve Y.left) {Z : Over X} (f : Z ⟶ Y) :
    (overEquiv Y).symm S f ↔ S f.left := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : C
Y : Over X
S : Sieve Y.left
Z : Over X
f : Z ⟶ Y
⊢ ((overEquiv Y).symm S).arrows f ↔ S.arrows f.left

Next tactic:
rfl
lemma overEquiv_iff {X : C} {Y : Over X} (S : Sieve Y) {Z : C} (f : Z ⟶ Y.left) :
    overEquiv Y S f ↔ S (Over.homMk f : Over.mk (f ≫ Y.hom) ⟶ Y) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : C
Y : Over X
S : Sieve Y
Z : C
f : Z ⟶ Y.left
⊢ ((overEquiv Y) S).arrows f ↔ S.arrows (Over.homMk f)

Next tactic:
obtain ⟨S, rfl⟩ := (overEquiv Y).symm.surjective S
lemma overEquiv_iff {X : C} {Y : Over X} (S : Sieve Y) {Z : C} (f : Z ⟶ Y.left) :
    overEquiv Y S f ↔ S (Over.homMk f : Over.mk (f ≫ Y.hom) ⟶ Y) := by
  obtain ⟨S, rfl⟩ := (overEquiv Y).symm.surjective S
  

Proof state:
case intro
C : Type u
inst✝ : Category.{v, u} C
X : C
Y : Over X
Z : C
f : Z ⟶ Y.left
S : Sieve Y.left
⊢ ((overEquiv Y) ((overEquiv Y).symm S)).arrows f ↔ ((overEquiv Y).symm S).arrows (Over.homMk f)

Next tactic:
simp
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
⊢ functorPushforward (Over.map f) ((overEquiv Z).symm S) = (overEquiv ((Over.map f).obj Z)).symm S

Next tactic:
ext W g
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
⊢ (functorPushforward (Over.map f) ((overEquiv Z).symm S)).arrows g ↔ ((overEquiv ((Over.map f).obj Z)).symm S).arrows g

Next tactic:
constructor
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · 

Proof state:
case h.mp
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
⊢ (functorPushforward (Over.map f) ((overEquiv Z).symm S)).arrows g → ((overEquiv ((Over.map f).obj Z)).symm S).arrows g

Next tactic:
rintro ⟨T, a, b, ha, rfl⟩
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · rintro ⟨T, a, b, ha, rfl⟩
    

Proof state:
case h.mp.intro.intro.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
T : Over X
a : T ⟶ Z
b : W ⟶ (Over.map f).obj T
ha : ((overEquiv Z).symm S).arrows a
⊢ ((overEquiv ((Over.map f).obj Z)).symm S).arrows (b ≫ (Over.map f).map a)

Next tactic:
exact S.downward_closed ha _
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · rintro ⟨T, a, b, ha, rfl⟩
    exact S.downward_closed ha _
  · 

Proof state:
case h.mpr
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
⊢ ((overEquiv ((Over.map f).obj Z)).symm S).arrows g → (functorPushforward (Over.map f) ((overEquiv Z).symm S)).arrows g

Next tactic:
intro hg
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · rintro ⟨T, a, b, ha, rfl⟩
    exact S.downward_closed ha _
  · intro hg
    

Proof state:
case h.mpr
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
hg : ((overEquiv ((Over.map f).obj Z)).symm S).arrows g
⊢ (functorPushforward (Over.map f) ((overEquiv Z).symm S)).arrows g

Next tactic:
exact ⟨Over.mk (g.left ≫ Z.hom), Over.homMk g.left,
      Over.homMk (𝟙 _) (by simpa using Over.w g), hg, by aesop_cat⟩
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · rintro ⟨T, a, b, ha, rfl⟩
    exact S.downward_closed ha _
  · intro hg
    exact ⟨Over.mk (g.left ≫ Z.hom), Over.homMk g.left,
      Over.homMk (𝟙 _) (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
hg : ((overEquiv ((Over.map f).obj Z)).symm S).arrows g
⊢ 𝟙 W.left ≫ ((Over.map f).obj (Over.mk (g.left ≫ Z.hom))).hom = W.hom

Next tactic:
simpa using Over.w g
@[simp]
lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) :
    Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) =
      (Sieve.overEquiv ((Over.map f).obj Z)).symm S := by
  ext W g
  constructor
  · rintro ⟨T, a, b, ha, rfl⟩
    exact S.downward_closed ha _
  · intro hg
    exact ⟨Over.mk (g.left ≫ Z.hom), Over.homMk g.left,
      Over.homMk (𝟙 _) (by simpa using Over.w g), hg, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : Over X
S : Sieve Z.left
W : Over Y
g : W ⟶ (Over.map f).obj Z
hg : ((overEquiv ((Over.map f).obj Z)).symm S).arrows g
⊢ g = Over.homMk (𝟙 W.left) ≫ (Over.map f).map (Over.homMk g.left)

Next tactic:
aesop_cat
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
⊢ ⊤ ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y

Next tactic:
change _ ∈ J Y.left
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
⊢ (Sieve.overEquiv Y) ⊤ ∈ sieves J Y.left

Next tactic:
simp
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y₁ Y₂ : Over X
S₁ : Sieve Y₁
f : Y₂ ⟶ Y₁
h₁ : S₁ ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y₁
⊢ Sieve.pullback f S₁ ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y₂

Next tactic:
change _ ∈ J _ at h₁ ⊢
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    change _ ∈ J _ at h₁ ⊢
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y₁ Y₂ : Over X
S₁ : Sieve Y₁
f : Y₂ ⟶ Y₁
h₁ : (Sieve.overEquiv Y₁) S₁ ∈ sieves J Y₁.left
⊢ (Sieve.overEquiv Y₂) (Sieve.pullback f S₁) ∈ sieves J Y₂.left

Next tactic:
rw [Sieve.overEquiv_pullback]
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    change _ ∈ J _ at h₁ ⊢
    rw [Sieve.overEquiv_pullback]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y₁ Y₂ : Over X
S₁ : Sieve Y₁
f : Y₂ ⟶ Y₁
h₁ : (Sieve.overEquiv Y₁) S₁ ∈ sieves J Y₁.left
⊢ Sieve.pullback f.left ((Sieve.overEquiv Y₁) S₁) ∈ sieves J Y₂.left

Next tactic:
exact J.pullback_stable _ h₁
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    change _ ∈ J _ at h₁ ⊢
    rw [Sieve.overEquiv_pullback]
    exact J.pullback_stable _ h₁
  transitive' Y S (hS : _ ∈ J _) R hR := J.transitive hS _ (fun Z f hf => by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
S : Sieve Y
hS : (Sieve.overEquiv Y) S ∈ sieves J Y.left
R : Sieve Y
hR :
  ∀ ⦃Y_1 : Over X⦄ ⦃f : Y_1 ⟶ Y⦄,
    S.arrows f → Sieve.pullback f R ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y_1
Z : C
f : Z ⟶ Y.left
hf : ((Sieve.overEquiv Y) S).arrows f
⊢ Sieve.pullback f ((Sieve.overEquiv Y) R) ∈ sieves J Z

Next tactic:
have hf' : _ ∈ J _ := hR ((Sieve.overEquiv_iff _ _).1 hf)
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    change _ ∈ J _ at h₁ ⊢
    rw [Sieve.overEquiv_pullback]
    exact J.pullback_stable _ h₁
  transitive' Y S (hS : _ ∈ J _) R hR := J.transitive hS _ (fun Z f hf => by
    have hf' : _ ∈ J _ := hR ((Sieve.overEquiv_iff _ _).1 hf)
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
S : Sieve Y
hS : (Sieve.overEquiv Y) S ∈ sieves J Y.left
R : Sieve Y
hR :
  ∀ ⦃Y_1 : Over X⦄ ⦃f : Y_1 ⟶ Y⦄,
    S.arrows f → Sieve.pullback f R ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y_1
Z : C
f : Z ⟶ Y.left
hf : ((Sieve.overEquiv Y) S).arrows f
hf' : (Sieve.overEquiv (Over.mk (f ≫ Y.hom))) (Sieve.pullback (Over.homMk f) R) ∈ sieves J (Over.mk (f ≫ Y.hom)).left
⊢ Sieve.pullback f ((Sieve.overEquiv Y) R) ∈ sieves J Z

Next tactic:
rw [Sieve.overEquiv_pullback] at hf'
/-- The Grothendieck topology on the category `Over X` for any `X : C` that is
induced by a Grothendieck topology on `C`. -/
def over (X : C) : GrothendieckTopology (Over X) where
  sieves Y S := Sieve.overEquiv Y S ∈ J Y.left
  top_mem' Y := by
    change _ ∈ J Y.left
    simp
  pullback_stable' Y₁ Y₂ S₁ f h₁ := by
    change _ ∈ J _ at h₁ ⊢
    rw [Sieve.overEquiv_pullback]
    exact J.pullback_stable _ h₁
  transitive' Y S (hS : _ ∈ J _) R hR := J.transitive hS _ (fun Z f hf => by
    have hf' : _ ∈ J _ := hR ((Sieve.overEquiv_iff _ _).1 hf)
    rw [Sieve.overEquiv_pullback] at hf'
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
S : Sieve Y
hS : (Sieve.overEquiv Y) S ∈ sieves J Y.left
R : Sieve Y
hR :
  ∀ ⦃Y_1 : Over X⦄ ⦃f : Y_1 ⟶ Y⦄,
    S.arrows f → Sieve.pullback f R ∈ (fun Y S => (Sieve.overEquiv Y) S ∈ sieves J Y.left) Y_1
Z : C
f : Z ⟶ Y.left
hf : ((Sieve.overEquiv Y) S).arrows f
hf' : Sieve.pullback (Over.homMk f).left ((Sieve.overEquiv Y) R) ∈ sieves J (Over.mk (f ≫ Y.hom)).left
⊢ Sieve.pullback f ((Sieve.overEquiv Y) R) ∈ sieves J Z

Next tactic:
exact hf'
lemma mem_over_iff {X : C} {Y : Over X} (S : Sieve Y) :
    S ∈ (J.over X) Y ↔ Sieve.overEquiv _ S ∈ J Y.left := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
S : Sieve Y
⊢ S ∈ sieves (over J X) Y ↔ (Sieve.overEquiv Y) S ∈ sieves J Y.left

Next tactic:
rfl
lemma overEquiv_symm_mem_over {X : C} (Y : Over X) (S : Sieve Y.left) (hS : S ∈ J Y.left) :
    (Sieve.overEquiv Y).symm S ∈ (J.over X) Y := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
Y : Over X
S : Sieve Y.left
hS : S ∈ sieves J Y.left
⊢ (Sieve.overEquiv Y).symm S ∈ sieves (over J X) Y

Next tactic:
simpa only [mem_over_iff, Equiv.apply_symm_apply] using hS
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
⊢ F.val.map f₁.op (x g₁ hg₁) = F.val.map f₂.op (x g₂ hg₂)

Next tactic:
let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
⊢ F.val.map f₁.op (x g₁ hg₁) = F.val.map f₂.op (x g₂ hg₂)

Next tactic:
let g₁' : W' ⟶ Y₁ := Over.homMk f₁
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    let g₁' : W' ⟶ Y₁ := Over.homMk f₁
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
g₁' : W' ⟶ Y₁ := Over.homMk f₁
⊢ F.val.map f₁.op (x g₁ hg₁) = F.val.map f₂.op (x g₂ hg₂)

Next tactic:
let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by simpa using h.symm =≫ Z.hom)
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    let g₁' : W' ⟶ Y₁ := Over.homMk f₁
    let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
g₁' : W' ⟶ Y₁ := Over.homMk f₁
⊢ f₂ ≫ Y₂.hom = W'.hom

Next tactic:
simpa using h.symm =≫ Z.hom
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    let g₁' : W' ⟶ Y₁ := Over.homMk f₁
    let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by simpa using h.symm =≫ Z.hom)
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
g₁' : W' ⟶ Y₁ := Over.homMk f₁
g₂' : W' ⟶ Y₂ := Over.homMk f₂
⊢ F.val.map f₁.op (x g₁ hg₁) = F.val.map f₂.op (x g₂ hg₂)

Next tactic:
exact hx g₁' g₂' hg₁ hg₂ (by ext; exact h)
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    let g₁' : W' ⟶ Y₁ := Over.homMk f₁
    let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by simpa using h.symm =≫ Z.hom)
    exact hx g₁' g₂' hg₁ hg₂ (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
g₁' : W' ⟶ Y₁ := Over.homMk f₁
g₂' : W' ⟶ Y₂ := Over.homMk f₂
⊢ g₁' ≫ g₁ = g₂' ≫ g₂

Next tactic:
ext
lemma over_forget_compatiblePreserving (X : C) :
    CompatiblePreserving J (Over.forget X) where
  compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by
    let W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
    let g₁' : W' ⟶ Y₁ := Over.homMk f₁
    let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by simpa using h.symm =≫ Z.hom)
    exact hx g₁' g₂' hg₁ hg₂ (by ext; 

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X : C
F : SheafOfTypes J
Z : Over X
T : Presieve Z
x : Presieve.FamilyOfElements ((Over.forget X).op ⋙ F.val) T
hx : Presieve.FamilyOfElements.Compatible x
Y₁ Y₂ : Over X
W : C
f₁ : W ⟶ (Over.forget X).obj Y₁
f₂ : W ⟶ (Over.forget X).obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
h : f₁ ≫ (Over.forget X).map g₁ = f₂ ≫ (Over.forget X).map g₂
W' : Over X := Over.mk (f₁ ≫ Y₁.hom)
g₁' : W' ⟶ Y₁ := Over.homMk f₁
g₂' : W' ⟶ Y₂ := Over.homMk f₂
⊢ (g₁' ≫ g₁).left = (g₂' ≫ g₂).left

Next tactic:
exact h
lemma over_map_coverPreserving {X Y : C} (f : X ⟶ Y) :
    CoverPreserving (J.over X) (J.over Y) (Over.map f) where
  cover_preserve {U S} hS := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X Y : C
f : X ⟶ Y
U : Over X
S : Sieve U
hS : S ∈ sieves (over J X) U
⊢ Sieve.functorPushforward (Over.map f) S ∈ sieves (over J Y) ((Over.map f).obj U)

Next tactic:
obtain ⟨S, rfl⟩ := (Sieve.overEquiv U).symm.surjective S
lemma over_map_coverPreserving {X Y : C} (f : X ⟶ Y) :
    CoverPreserving (J.over X) (J.over Y) (Over.map f) where
  cover_preserve {U S} hS := by
    obtain ⟨S, rfl⟩ := (Sieve.overEquiv U).symm.surjective S
    

Proof state:
case intro
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X Y : C
f : X ⟶ Y
U : Over X
S : Sieve U.left
hS : (Sieve.overEquiv U).symm S ∈ sieves (over J X) U
⊢ Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv U).symm S) ∈ sieves (over J Y) ((Over.map f).obj U)

Next tactic:
rw [Sieve.functorPushforward_over_map]
lemma over_map_coverPreserving {X Y : C} (f : X ⟶ Y) :
    CoverPreserving (J.over X) (J.over Y) (Over.map f) where
  cover_preserve {U S} hS := by
    obtain ⟨S, rfl⟩ := (Sieve.overEquiv U).symm.surjective S
    rw [Sieve.functorPushforward_over_map]
    

Proof state:
case intro
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X Y : C
f : X ⟶ Y
U : Over X
S : Sieve U.left
hS : (Sieve.overEquiv U).symm S ∈ sieves (over J X) U
⊢ (Sieve.overEquiv ((Over.map f).obj U)).symm S ∈ sieves (over J Y) ((Over.map f).obj U)

Next tactic:
apply overEquiv_symm_mem_over
lemma over_map_coverPreserving {X Y : C} (f : X ⟶ Y) :
    CoverPreserving (J.over X) (J.over Y) (Over.map f) where
  cover_preserve {U S} hS := by
    obtain ⟨S, rfl⟩ := (Sieve.overEquiv U).symm.surjective S
    rw [Sieve.functorPushforward_over_map]
    apply overEquiv_symm_mem_over
    

Proof state:
case intro.hS
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
X Y : C
f : X ⟶ Y
U : Over X
S : Sieve U.left
hS : (Sieve.overEquiv U).symm S ∈ sieves (over J X) U
⊢ S ∈ sieves J ((Over.map f).obj U).left

Next tactic:
simpa [mem_over_iff] using hS