l3lab/ntp-mathlib huggingface dataset:
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
⊢ Sieve.pullback f S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y

Next tactic:
have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
⊢ Sieve.pullback f S = Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))

Next tactic:
conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => 

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
| Sieve.pullback f S

Next tactic:
rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
⊢ Sieve.pullback f (Sieve.functorPullback G (Sieve.functorPushforward G S)) =
    Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))

Next tactic:
ext
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      

Proof state:
case h
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
Y✝ : C
f✝ : Y✝ ⟶ Y
⊢ (Sieve.pullback f (Sieve.functorPullback G (Sieve.functorPushforward G S))).arrows f✝ ↔
    (Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))).arrows f✝

Next tactic:
change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      

Proof state:
case h
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
Y✝ : C
f✝ : Y✝ ⟶ Y
⊢ (Sieve.functorPushforward G S).arrows (G.map (f✝ ≫ f)) ↔ (Sieve.functorPushforward G S).arrows (G.map f✝ ≫ G.map f)

Next tactic:
rw [G.map_comp]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
this : Sieve.pullback f S = Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))
⊢ Sieve.pullback f S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y

Next tactic:
rw [this]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
this : Sieve.pullback f S = Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))
⊢ Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S)) ∈
    (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y

Next tactic:
change K _ _
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X Y : C
S : Sieve X
f : Y ⟶ X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
this : Sieve.pullback f S = Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))
⊢ GrothendieckTopology.sieves K (G.obj Y)
    (Sieve.functorPushforward G (Sieve.functorPullback G (Sieve.pullback (G.map f) (Sieve.functorPushforward G S))))

Next tactic:
apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
⊢ S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X

Next tactic:
apply K.transitive hS
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    

Proof state:
case h
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
⊢ ∀ ⦃Y : D⦄ ⦃f : Y ⟶ G.obj X⦄,
    (Sieve.functorPushforward G S).arrows f →
      Sieve.pullback f (Sieve.functorPushforward G S') ∈ GrothendieckTopology.sieves K Y

Next tactic:
rintro Y _ ⟨Z, g, i, hg, rfl⟩
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    rintro Y _ ⟨Z, g, i, hg, rfl⟩
    

Proof state:
case h.intro.intro.intro.intro
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
Y : D
Z : C
g : Z ⟶ X
i : Y ⟶ G.obj Z
hg : S.arrows g
⊢ Sieve.pullback (i ≫ G.map g) (Sieve.functorPushforward G S') ∈ GrothendieckTopology.sieves K Y

Next tactic:
rw [Sieve.pullback_comp]
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    rintro Y _ ⟨Z, g, i, hg, rfl⟩
    rw [Sieve.pullback_comp]
    

Proof state:
case h.intro.intro.intro.intro
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
Y : D
Z : C
g : Z ⟶ X
i : Y ⟶ G.obj Z
hg : S.arrows g
⊢ Sieve.pullback i (Sieve.pullback (G.map g) (Sieve.functorPushforward G S')) ∈ GrothendieckTopology.sieves K Y

Next tactic:
apply K.pullback_stable i
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    rintro Y _ ⟨Z, g, i, hg, rfl⟩
    rw [Sieve.pullback_comp]
    apply K.pullback_stable i
    

Proof state:
case h.intro.intro.intro.intro
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
Y : D
Z : C
g : Z ⟶ X
i : Y ⟶ G.obj Z
hg : S.arrows g
⊢ Sieve.pullback (G.map g) (Sieve.functorPushforward G S') ∈ GrothendieckTopology.sieves K (G.obj Z)

Next tactic:
refine' K.superset_covering _ (H' hg)
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    rintro Y _ ⟨Z, g, i, hg, rfl⟩
    rw [Sieve.pullback_comp]
    apply K.pullback_stable i
    refine' K.superset_covering _ (H' hg)
    

Proof state:
case h.intro.intro.intro.intro
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
Y : D
Z : C
g : Z ⟶ X
i : Y ⟶ G.obj Z
hg : S.arrows g
⊢ Sieve.functorPushforward G (Sieve.pullback g S') ≤ Sieve.pullback (G.map g) (Sieve.functorPushforward G S')

Next tactic:
rintro W _ ⟨Z', g', i', hg, rfl⟩
/-- If a functor `G : C ⥤ (D, K)` is fully faithful and locally dense,
then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`.
-/
@[simps]
def inducedTopology : GrothendieckTopology C where
  sieves X S := K _ (S.functorPushforward G)
  top_mem' X := by
    change K _ _
    rw [Sieve.functorPushforward_top]
    exact K.top_mem _
  pullback_stable' X Y S f hS := by
    have : S.pullback f = ((S.functorPushforward G).pullback (G.map f)).functorPullback G := by
      conv_lhs => rw [← (Sieve.fullyFaithfulFunctorGaloisCoinsertion G X).u_l_eq S]
      ext
      change (S.functorPushforward G) _ ↔ (S.functorPushforward G) _
      rw [G.map_comp]
    rw [this]
    change K _ _
    apply Hld ⟨_, K.pullback_stable (G.map f) hS⟩
  transitive' X S hS S' H' := by
    apply K.transitive hS
    rintro Y _ ⟨Z, g, i, hg, rfl⟩
    rw [Sieve.pullback_comp]
    apply K.pullback_stable i
    refine' K.superset_covering _ (H' hg)
    rintro W _ ⟨Z', g', i', hg, rfl⟩
    

Proof state:
case h.intro.intro.intro.intro.intro.intro.intro.intro
C : Type u_1
inst✝⁴ : Category.{?u.3086, u_1} C
D : Type u_2
inst✝³ : Category.{?u.3093, u_2} D
G : C ⥤ D
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type v
inst✝² : Category.{u, v} A
inst✝¹ : Full G
inst✝ : Faithful G
Hld : LocallyCoverDense K G
X : C
S : Sieve X
hS : S ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) X
S' : Sieve X
H' :
  ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄,
    S.arrows f →
      Sieve.pullback f S' ∈ (fun X S => GrothendieckTopology.sieves K (G.obj X) (Sieve.functorPushforward G S)) Y
Y : D
Z : C
g : Z ⟶ X
i : Y ⟶ G.obj Z
hg✝ : S.arrows g
W : D
Z' : C
g' : Z' ⟶ Z
i' : W ⟶ G.obj Z'
hg : (Sieve.pullback g S').arrows g'
⊢ (Sieve.pullback (G.map g) (Sieve.functorPushforward G S')).arrows (i' ≫ G.map g')

Next tactic:
refine' ⟨Z', g' ≫ g , i', hg, _⟩