l3lab/ntp-mathlib huggingface dataset:
/-- 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]
  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 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) ≫
      pullback.fst =
    ((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) ≫
      pullback.fst

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 _ _
  intro i
  dsimp [OpenCover.bind]
  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 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) ≫
      pullback.snd =
    ((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) ≫
      pullback.snd

Next tactic:
simp
/-- Given an open cover `{ Xᵢ }` of `X` and an open cover `{ Yⱼ }` of `Y`, then
`X ×[Z] Y` is covered by `Xᵢ ×[Z] Yⱼ`. -/
@[simps! J obj map]
def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullback f g).OpenCover := 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✝
𝒰X : OpenCover X
𝒰Y : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
⊢ OpenCover (pullback f g)

Next tactic:
fapply
    ((openCoverOfLeft 𝒰X f g).bind fun x => openCoverOfRight 𝒰Y (𝒰X.map x ≫ f) g).copy
      (𝒰X.J × 𝒰Y.J) (fun ij => pullback (𝒰X.map ij.1 ≫ f) (𝒰Y.map ij.2 ≫ g))
      (fun ij =>
        pullback.map _ _ _ _ (𝒰X.map ij.1) (𝒰Y.map ij.2) (𝟙 _) (Category.comp_id _)
          (Category.comp_id _))
      (Equiv.sigmaEquivProd _ _).symm fun _ => Iso.refl _
/-- Given an open cover `{ Xᵢ }` of `X` and an open cover `{ Yⱼ }` of `Y`, then
`X ×[Z] Y` is covered by `Xᵢ ×[Z] Yⱼ`. -/
@[simps! J obj map]
def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullback f g).OpenCover := by
  fapply
    ((openCoverOfLeft 𝒰X f g).bind fun x => openCoverOfRight 𝒰Y (𝒰X.map x ≫ f) g).copy
      (𝒰X.J × 𝒰Y.J) (fun ij => pullback (𝒰X.map ij.1 ≫ f) (𝒰Y.map ij.2 ≫ g))
      (fun ij =>
        pullback.map _ _ _ _ (𝒰X.map ij.1) (𝒰Y.map ij.2) (𝟙 _) (Category.comp_id _)
          (Category.comp_id _))
      (Equiv.sigmaEquivProd _ _).symm fun _ => Iso.refl _
  

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✝
𝒰X : OpenCover X
𝒰Y : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
⊢ ∀ (i : 𝒰X.J × 𝒰Y.J),
    pullback.map (OpenCover.map 𝒰X i.1 ≫ f) (OpenCover.map 𝒰Y i.2 ≫ g) f g (OpenCover.map 𝒰X i.1) (OpenCover.map 𝒰Y i.2)
        (𝟙 Z) (_ : (OpenCover.map 𝒰X i.1 ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰X i.1 ≫ f)
        (_ : (OpenCover.map 𝒰Y i.2 ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰Y i.2 ≫ g) =
      (Iso.refl ((fun ij => pullback (OpenCover.map 𝒰X ij.1 ≫ f) (OpenCover.map 𝒰Y ij.2 ≫ g)) i)).hom ≫
        OpenCover.map (OpenCover.bind (openCoverOfLeft 𝒰X f g) fun x => openCoverOfRight 𝒰Y (OpenCover.map 𝒰X x ≫ f) g)
          ((Equiv.sigmaEquivProd 𝒰X.J 𝒰Y.J).symm i)

Next tactic:
rintro ⟨i, j⟩
/-- Given an open cover `{ Xᵢ }` of `X` and an open cover `{ Yⱼ }` of `Y`, then
`X ×[Z] Y` is covered by `Xᵢ ×[Z] Yⱼ`. -/
@[simps! J obj map]
def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullback f g).OpenCover := by
  fapply
    ((openCoverOfLeft 𝒰X f g).bind fun x => openCoverOfRight 𝒰Y (𝒰X.map x ≫ f) g).copy
      (𝒰X.J × 𝒰Y.J) (fun ij => pullback (𝒰X.map ij.1 ≫ f) (𝒰Y.map ij.2 ≫ g))
      (fun ij =>
        pullback.map _ _ _ _ (𝒰X.map ij.1) (𝒰Y.map ij.2) (𝟙 _) (Category.comp_id _)
          (Category.comp_id _))
      (Equiv.sigmaEquivProd _ _).symm fun _ => Iso.refl _
  rintro ⟨i, j⟩
  

Proof state:
case mk
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✝
𝒰X : OpenCover X
𝒰Y : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰X.J
j : 𝒰Y.J
⊢ pullback.map (OpenCover.map 𝒰X (i, j).1 ≫ f) (OpenCover.map 𝒰Y (i, j).2 ≫ g) f g (OpenCover.map 𝒰X (i, j).1)
      (OpenCover.map 𝒰Y (i, j).2) (𝟙 Z) (_ : (OpenCover.map 𝒰X (i, j).1 ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰X (i, j).1 ≫ f)
      (_ : (OpenCover.map 𝒰Y (i, j).2 ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰Y (i, j).2 ≫ g) =
    (Iso.refl ((fun ij => pullback (OpenCover.map 𝒰X ij.1 ≫ f) (OpenCover.map 𝒰Y ij.2 ≫ g)) (i, j))).hom ≫
      OpenCover.map (OpenCover.bind (openCoverOfLeft 𝒰X f g) fun x => openCoverOfRight 𝒰Y (OpenCover.map 𝒰X x ≫ f) g)
        ((Equiv.sigmaEquivProd 𝒰X.J 𝒰Y.J).symm (i, j))

Next tactic:
apply pullback.hom_ext
/-- Given an open cover `{ Xᵢ }` of `X` and an open cover `{ Yⱼ }` of `Y`, then
`X ×[Z] Y` is covered by `Xᵢ ×[Z] Yⱼ`. -/
@[simps! J obj map]
def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullback f g).OpenCover := by
  fapply
    ((openCoverOfLeft 𝒰X f g).bind fun x => openCoverOfRight 𝒰Y (𝒰X.map x ≫ f) g).copy
      (𝒰X.J × 𝒰Y.J) (fun ij => pullback (𝒰X.map ij.1 ≫ f) (𝒰Y.map ij.2 ≫ g))
      (fun ij =>
        pullback.map _ _ _ _ (𝒰X.map ij.1) (𝒰Y.map ij.2) (𝟙 _) (Category.comp_id _)
          (Category.comp_id _))
      (Equiv.sigmaEquivProd _ _).symm fun _ => Iso.refl _
  rintro ⟨i, j⟩
  apply pullback.hom_ext <;> 

Proof state:
case mk.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✝
𝒰X : OpenCover X
𝒰Y : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰X.J
j : 𝒰Y.J
⊢ pullback.map (OpenCover.map 𝒰X (i, j).1 ≫ f) (OpenCover.map 𝒰Y (i, j).2 ≫ g) f g (OpenCover.map 𝒰X (i, j).1)
        (OpenCover.map 𝒰Y (i, j).2) (𝟙 Z) (_ : (OpenCover.map 𝒰X (i, j).1 ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰X (i, j).1 ≫ f)
        (_ : (OpenCover.map 𝒰Y (i, j).2 ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰Y (i, j).2 ≫ g) ≫
      pullback.fst =
    ((Iso.refl ((fun ij => pullback (OpenCover.map 𝒰X ij.1 ≫ f) (OpenCover.map 𝒰Y ij.2 ≫ g)) (i, j))).hom ≫
        OpenCover.map (OpenCover.bind (openCoverOfLeft 𝒰X f g) fun x => openCoverOfRight 𝒰Y (OpenCover.map 𝒰X x ≫ f) g)
          ((Equiv.sigmaEquivProd 𝒰X.J 𝒰Y.J).symm (i, j))) ≫
      pullback.fst

Next tactic:
simp
/-- Given an open cover `{ Xᵢ }` of `X` and an open cover `{ Yⱼ }` of `Y`, then
`X ×[Z] Y` is covered by `Xᵢ ×[Z] Yⱼ`. -/
@[simps! J obj map]
def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullback f g).OpenCover := by
  fapply
    ((openCoverOfLeft 𝒰X f g).bind fun x => openCoverOfRight 𝒰Y (𝒰X.map x ≫ f) g).copy
      (𝒰X.J × 𝒰Y.J) (fun ij => pullback (𝒰X.map ij.1 ≫ f) (𝒰Y.map ij.2 ≫ g))
      (fun ij =>
        pullback.map _ _ _ _ (𝒰X.map ij.1) (𝒰Y.map ij.2) (𝟙 _) (Category.comp_id _)
          (Category.comp_id _))
      (Equiv.sigmaEquivProd _ _).symm fun _ => Iso.refl _
  rintro ⟨i, j⟩
  apply pullback.hom_ext <;> 

Proof state:
case mk.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✝
𝒰X : OpenCover X
𝒰Y : OpenCover Y
f : X ⟶ Z
g : Y ⟶ Z
i : 𝒰X.J
j : 𝒰Y.J
⊢ pullback.map (OpenCover.map 𝒰X (i, j).1 ≫ f) (OpenCover.map 𝒰Y (i, j).2 ≫ g) f g (OpenCover.map 𝒰X (i, j).1)
        (OpenCover.map 𝒰Y (i, j).2) (𝟙 Z) (_ : (OpenCover.map 𝒰X (i, j).1 ≫ f) ≫ 𝟙 Z = OpenCover.map 𝒰X (i, j).1 ≫ f)
        (_ : (OpenCover.map 𝒰Y (i, j).2 ≫ g) ≫ 𝟙 Z = OpenCover.map 𝒰Y (i, j).2 ≫ g) ≫
      pullback.snd =
    ((Iso.refl ((fun ij => pullback (OpenCover.map 𝒰X ij.1 ≫ f) (OpenCover.map 𝒰Y ij.2 ≫ g)) (i, j))).hom ≫
        OpenCover.map (OpenCover.bind (openCoverOfLeft 𝒰X f g) fun x => openCoverOfRight 𝒰Y (OpenCover.map 𝒰X x ≫ f) g)
          ((Equiv.sigmaEquivProd 𝒰X.J 𝒰Y.J).symm (i, j))) ≫
      pullback.snd

Next tactic:
simp
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (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 Z
f : X ⟶ Z
g : Y ⟶ Z
⊢ OpenCover (pullback f g)

Next tactic:
apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).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 Z
f : X ⟶ Z
g : Y ⟶ Z
⊢ (x : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J) →
    OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) x)

Next tactic:
intro i
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
⊢ OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) i)

Next tactic:
let Xᵢ := pullback f (𝒰.map i)
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map 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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
⊢ OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) i)

Next tactic:
let Yᵢ := pullback g (𝒰.map i)
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map 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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
⊢ OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) i)

Next tactic:
let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  

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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
⊢ OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) i)

Next tactic:
have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
  

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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
this :
  IsLimit
    (PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
      (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g))
⊢ OpenCover (OpenCover.obj (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g) i)

Next tactic:
refine'
    @openCoverOfIsIso
      (f := (pullbackSymmetry _ _).hom ≫
        (limit.isoLimitCone ⟨_, this⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) _ _) ?_
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
  refine'
    @openCoverOfIsIso
      (f := (pullbackSymmetry _ _).hom ≫
        (limit.isoLimitCone ⟨_, this⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) _ _) ?_
  · 

Proof state:
case refine'_1
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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
this :
  IsLimit
    (PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
      (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g))
⊢ (pullback.snd ≫ OpenCover.map 𝒰 i) ≫ 𝟙 Z =
    𝟙 (pullback f (OpenCover.map 𝒰 i)) ≫ OpenCover.map (OpenCover.pullbackCover 𝒰 f) i ≫ f

Next tactic:
simp only [Category.comp_id, Category.id_comp, ← pullback.condition]
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
  refine'
    @openCoverOfIsIso
      (f := (pullbackSymmetry _ _).hom ≫
        (limit.isoLimitCone ⟨_, this⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) _ _) ?_
  · simp only [Category.comp_id, Category.id_comp, ← pullback.condition]
    -- Porting note : `simpa` failed, but this is indeed `rfl`
    

Proof state:
case refine'_1
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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
this :
  IsLimit
    (PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
      (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g))
⊢ pullback.fst ≫ f = OpenCover.map (OpenCover.pullbackCover 𝒰 f) i ≫ f

Next tactic:
rfl
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
  refine'
    @openCoverOfIsIso
      (f := (pullbackSymmetry _ _).hom ≫
        (limit.isoLimitCone ⟨_, this⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) _ _) ?_
  · simp only [Category.comp_id, Category.id_comp, ← pullback.condition]
    -- Porting note : `simpa` failed, but this is indeed `rfl`
    rfl
  · 

Proof state:
case refine'_2
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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
this :
  IsLimit
    (PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
      (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g))
⊢ g ≫ 𝟙 Z = 𝟙 Y ≫ g

Next tactic:
simp only [Category.comp_id, Category.id_comp]
/-- (Implementation). Use `openCoverOfBase` instead. -/
@[simps! map]
def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by
  apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind
  intro i
  let Xᵢ := pullback f (𝒰.map i)
  let Yᵢ := pullback g (𝒰.map i)
  let W := pullback (pullback.snd : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
  have :=
    bigSquareIsPullback (pullback.fst : W ⟶ _) (pullback.fst : Yᵢ ⟶ _) (pullback.snd : Xᵢ ⟶ _)
      (𝒰.map i) pullback.snd pullback.snd g pullback.condition.symm pullback.condition.symm
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
      (PullbackCone.flipIsLimit <| pullbackIsPullback _ _)
  refine'
    @openCoverOfIsIso
      (f := (pullbackSymmetry _ _).hom ≫
        (limit.isoLimitCone ⟨_, this⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) _ _) ?_
  · simp only [Category.comp_id, Category.id_comp, ← pullback.condition]
    -- Porting note : `simpa` failed, but this is indeed `rfl`
    rfl
  · simp only [Category.comp_id, Category.id_comp]
  -- Porting note : this `IsIso` instance was `inferInstance`
  · 

Proof state:
case refine'_3
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 Z
f : X ⟶ Z
g : Y ⟶ Z
i : (openCoverOfLeft (OpenCover.pullbackCover 𝒰 f) f g).J
Xᵢ : Scheme := pullback f (OpenCover.map 𝒰 i)
Yᵢ : Scheme := pullback g (OpenCover.map 𝒰 i)
W : Scheme := pullback pullback.snd pullback.snd
this :
  IsLimit
    (PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
      (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g))
⊢ IsIso
    ((pullbackSymmetry pullback.snd pullback.snd).hom ≫
      (limit.isoLimitCone
            {
              cone :=
                PullbackCone.mk pullback.snd (pullback.fst ≫ pullback.fst)
                  (_ : pullback.snd ≫ pullback.snd ≫ OpenCover.map 𝒰 i = (pullback.fst ≫ pullback.fst) ≫ g),
              isLimit := this }).inv ≫
        pullback.map (pullback.snd ≫ OpenCover.map 𝒰 i) g (OpenCover.map (OpenCover.pullbackCover 𝒰 f) i ≫ f) g
          (𝟙 (pullback f (OpenCover.map 𝒰 i))) (𝟙 Y) (𝟙 Z)
          (_ :
            (pullback.snd ≫ OpenCover.map 𝒰 i) ≫ 𝟙 Z =
              𝟙 (pullback f (OpenCover.map 𝒰 i)) ≫ OpenCover.map (OpenCover.pullbackCover 𝒰 f) i ≫ f)
          (_ : g ≫ 𝟙 Z = 𝟙 Y ≫ g))

Next tactic:
apply IsIso.comp_isIso
/-- Given an open cover `{ Zᵢ }` of `Z`, then `X ×[Z] Y` is covered by `Xᵢ ×[Zᵢ] Yᵢ`, where
  `Xᵢ = X ×[Z] Zᵢ` and `Yᵢ = Y ×[Z] Zᵢ` is the preimage of `Zᵢ` in `X` and `Y`. -/
@[simps! J obj map]
def openCoverOfBase (𝒰 : OpenCover Z) (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 Z
f : X ⟶ Z
g : Y ⟶ Z
⊢ OpenCover (pullback f g)

Next tactic:
apply
    (openCoverOfBase'.{u, u} 𝒰 f g).copy 𝒰.J
      (fun i =>
        pullback (pullback.snd : pullback f (𝒰.map i) ⟶ _)
          (pullback.snd : pullback g (𝒰.map i) ⟶ _))
      (fun i =>
        pullback.map _ _ _ _ pullback.fst pullback.fst (𝒰.map i) pullback.condition.symm
          pullback.condition.symm)
      ((Equiv.prodPUnit 𝒰.J).symm.trans (Equiv.sigmaEquivProd 𝒰.J PUnit).symm) fun _ => Iso.refl _