l3lab/ntp-mathlib huggingface dataset:
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
      (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) =
    (Iso.refl ((fun i => pullback (OpenCover.map 𝒰 i ≫ f) g) i)).hom ≫
      OpenCover.map
        (OpenCover.pushforwardIso (GlueData.openCover (gluing 𝒰 f g))
          (limit.isoLimitCone
              { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                isLimit := gluedIsLimit 𝒰 f g }).inv)
        ((Equiv.refl 𝒰.J) i)

Next tactic:
change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
      (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) =
    𝟙 (GlueData.U (gluing 𝒰 f g).toGlueData i) ≫
      GlueData.ι (gluing 𝒰 f g) i ≫
        OpenCover.map
          (openCoverOfIsIso
            (limit.isoLimitCone
                { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                  isLimit := gluedIsLimit 𝒰 f g }).inv)
          (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
                (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
              ((Equiv.refl 𝒰.J) i)).fst

Next tactic:
refine' Eq.trans _ (Category.id_comp _).symm
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
      (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) =
    GlueData.ι (gluing 𝒰 f g) i ≫
      OpenCover.map
        (openCoverOfIsIso
          (limit.isoLimitCone
              { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                isLimit := gluedIsLimit 𝒰 f g }).inv)
        (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
              (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
            ((Equiv.refl 𝒰.J) i)).fst

Next tactic:
apply pullback.hom_ext
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  

Proof state:
case h₀
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.fst =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        OpenCover.map
          (openCoverOfIsIso
            (limit.isoLimitCone
                { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                  isLimit := gluedIsLimit 𝒰 f g }).inv)
          (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
                (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
              ((Equiv.refl 𝒰.J) i)).fst) ≫
      pullback.fst
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.snd =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        OpenCover.map
          (openCoverOfIsIso
            (limit.isoLimitCone
                { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                  isLimit := gluedIsLimit 𝒰 f g }).inv)
          (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
                (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
              ((Equiv.refl 𝒰.J) i)).fst) ≫
      pullback.snd

Next tactic:
all_goals
    dsimp
    simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
    symm
    exact Multicoequalizer.π_desc _ _ _ _ _
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    

Proof state:
case h₀
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.fst =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        OpenCover.map
          (openCoverOfIsIso
            (limit.isoLimitCone
                { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                  isLimit := gluedIsLimit 𝒰 f g }).inv)
          (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
                (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
              ((Equiv.refl 𝒰.J) i)).fst) ≫
      pullback.fst

Next tactic:
dsimp
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    

Proof state:
case h₀
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.fst =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        (limit.isoLimitCone
            { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
              isLimit := gluedIsLimit 𝒰 f g }).inv) ≫
      pullback.fst

Next tactic:
simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
    

Proof state:
case h₀
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.fst ≫ OpenCover.map 𝒰 i = GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g

Next tactic:
symm
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
    symm
    

Proof state:
case h₀
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i

Next tactic:
exact Multicoequalizer.π_desc _ _ _ _ _
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    

Proof state:
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.snd =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        OpenCover.map
          (openCoverOfIsIso
            (limit.isoLimitCone
                { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
                  isLimit := gluedIsLimit 𝒰 f g }).inv)
          (((Equiv.punitProd (GlueData.openCover (gluing 𝒰 f g)).J).symm.trans
                (Equiv.sigmaEquivProd PUnit.{u + 1} (GlueData.openCover (gluing 𝒰 f g)).J).symm)
              ((Equiv.refl 𝒰.J) i)).fst) ≫
      pullback.snd

Next tactic:
dsimp
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    

Proof state:
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map (OpenCover.map 𝒰 i ≫ f) g f g (OpenCover.map 𝒰 i) (𝟙 Y) (𝟙 Z)
        (_ : (OpenCover.map 𝒰 i ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ f) (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g) ≫
      pullback.snd =
    (GlueData.ι (gluing 𝒰 f g) i ≫
        (limit.isoLimitCone
            { cone := PullbackCone.mk (p1 𝒰 f g) (p2 𝒰 f g) (_ : p1 𝒰 f g ≫ f = p2 𝒰 f g ≫ g),
              isLimit := gluedIsLimit 𝒰 f g }).inv) ≫
      pullback.snd

Next tactic:
simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
    

Proof state:
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.snd = GlueData.ι (gluing 𝒰 f g) i ≫ p2 𝒰 f g

Next tactic:
symm
/-- Given an open cover `{ Xᵢ }` of `X`, then `X ×[Z] Y` is covered by `Xᵢ ×[Z] Y`. -/
@[simps! J obj map]
def openCoverOfLeft (𝒰 : OpenCover X) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((gluing 𝒰 f g).openCover.pushforwardIso
          (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰 f g⟩).inv).copy
      𝒰.J (fun i => pullback (𝒰.map i ≫ f) g)
      (fun i => pullback.map _ _ _ _ (𝒰.map i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp))
      (Equiv.refl 𝒰.J) fun _ => Iso.refl _
  rintro (i : 𝒰.J)
  change pullback.map _ _ _ _ _ _ _ _ _ = 𝟙 _ ≫ (gluing 𝒰 f g).ι i ≫ _
  refine' Eq.trans _ (Category.id_comp _).symm
  apply pullback.hom_ext
  all_goals
    dsimp
    simp only [limit.isoLimitCone_inv_π, PullbackCone.mk_π_app_left, Category.comp_id,
      PullbackCone.mk_π_app_right, Category.assoc, pullback.lift_fst, pullback.lift_snd]
    symm
    

Proof state:
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover X
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ GlueData.ι (gluing 𝒰 f g) i ≫ p2 𝒰 f g = pullback.snd

Next tactic:
exact Multicoequalizer.π_desc _ _ _ _ _
/-- Given an open cover `{ Yᵢ }` of `Y`, then `X ×[Z] Y` is covered by `X ×[Z] Yᵢ`. -/
@[simps! J obj map]
def openCoverOfRight (𝒰 : OpenCover Y) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
⊢ OpenCover (pullback f g)

Next tactic:
fapply
    ((openCoverOfLeft 𝒰 g f).pushforwardIso (pullbackSymmetry _ _).hom).copy 𝒰.J
      (fun i => pullback f (𝒰.map i ≫ g))
      (fun i => pullback.map _ _ _ _ (𝟙 _) (𝒰.map i) (𝟙 _) (by simp) (Category.comp_id _))
      (Equiv.refl _) fun i => pullbackSymmetry _ _
/-- Given an open cover `{ Yᵢ }` of `Y`, then `X ×[Z] Y` is covered by `X ×[Z] Yᵢ`. -/
@[simps! J obj map]
def openCoverOfRight (𝒰 : OpenCover Y) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((openCoverOfLeft 𝒰 g f).pushforwardIso (pullbackSymmetry _ _).hom).copy 𝒰.J
      (fun i => pullback f (𝒰.map i ≫ g))
      (fun i => pullback.map _ _ _ _ (𝟙 _) (𝒰.map i) (𝟙 _) (by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ f ≫ 𝟙 Z = 𝟙 X ≫ f

Next tactic:
simp
/-- Given an open cover `{ Yᵢ }` of `Y`, then `X ×[Z] Y` is covered by `X ×[Z] Yᵢ`. -/
@[simps! J obj map]
def openCoverOfRight (𝒰 : OpenCover Y) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((openCoverOfLeft 𝒰 g f).pushforwardIso (pullbackSymmetry _ _).hom).copy 𝒰.J
      (fun i => pullback f (𝒰.map i ≫ g))
      (fun i => pullback.map _ _ _ _ (𝟙 _) (𝒰.map i) (𝟙 _) (by simp) (Category.comp_id _))
      (Equiv.refl _) fun i => pullbackSymmetry _ _
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
⊢ ∀ (i : 𝒰.J),
    pullback.map f (OpenCover.map 𝒰 i ≫ g) f g (𝟙 X) (OpenCover.map 𝒰 i) (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f)
        (_ : (OpenCover.map 𝒰 i ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ g) =
      (pullbackSymmetry f (OpenCover.map 𝒰 i ≫ g)).hom ≫
        OpenCover.map (OpenCover.pushforwardIso (openCoverOfLeft 𝒰 g f) (pullbackSymmetry g f).hom) ((Equiv.refl 𝒰.J) i)

Next tactic:
intro i
/-- Given an open cover `{ Yᵢ }` of `Y`, then `X ×[Z] Y` is covered by `X ×[Z] Yᵢ`. -/
@[simps! J obj map]
def openCoverOfRight (𝒰 : OpenCover Y) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((openCoverOfLeft 𝒰 g f).pushforwardIso (pullbackSymmetry _ _).hom).copy 𝒰.J
      (fun i => pullback f (𝒰.map i ≫ g))
      (fun i => pullback.map _ _ _ _ (𝟙 _) (𝒰.map i) (𝟙 _) (by simp) (Category.comp_id _))
      (Equiv.refl _) fun i => pullbackSymmetry _ _
  intro i
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map f (OpenCover.map 𝒰 i ≫ g) f g (𝟙 X) (OpenCover.map 𝒰 i) (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f)
      (_ : (OpenCover.map 𝒰 i ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ g) =
    (pullbackSymmetry f (OpenCover.map 𝒰 i ≫ g)).hom ≫
      OpenCover.map (OpenCover.pushforwardIso (openCoverOfLeft 𝒰 g f) (pullbackSymmetry g f).hom) ((Equiv.refl 𝒰.J) i)

Next tactic:
dsimp [OpenCover.bind]
/-- Given an open cover `{ Yᵢ }` of `Y`, then `X ×[Z] Y` is covered by `X ×[Z] Yᵢ`. -/
@[simps! J obj map]
def openCoverOfRight (𝒰 : OpenCover Y) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  fapply
    ((openCoverOfLeft 𝒰 g f).pushforwardIso (pullbackSymmetry _ _).hom).copy 𝒰.J
      (fun i => pullback f (𝒰.map i ≫ g))
      (fun i => pullback.map _ _ _ _ (𝟙 _) (𝒰.map i) (𝟙 _) (by simp) (Category.comp_id _))
      (Equiv.refl _) fun i => pullbackSymmetry _ _
  intro i
  dsimp [OpenCover.bind]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
𝒰✝ : OpenCover X
f✝ : X ⟶ Z
g✝ : Y ⟶ Z
inst✝ : ∀ (i : 𝒰✝.J), HasPullback (OpenCover.map 𝒰✝ i ≫ f✝) g✝
s : PullbackCone f✝ g✝
𝒰 : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰.J
⊢ pullback.map f (OpenCover.map 𝒰 i ≫ g) f g (𝟙 X) (OpenCover.map 𝒰 i) (𝟙 Z) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f)
      (_ : (OpenCover.map 𝒰 i ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ g) =
    (pullbackSymmetry f (OpenCover.map 𝒰 i ≫ g)).hom ≫
      pullback.map (OpenCover.map 𝒰 i ≫ g) f g f (OpenCover.map 𝒰 i) (𝟙 X) (𝟙 Z)
          (_ : (OpenCover.map 𝒰 i ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰 i ≫ g) (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) ≫
        (pullbackSymmetry g f).hom

Next tactic:
apply pullback.hom_ext