l3lab/ntp-mathlib huggingface dataset:
/-- We show that the map `W ×[X] Uᵢ ⟶ Uᵢ ×[Z] Y ⟶ W` is the first projection, where the
first map is given by the lift of `W ×[X] Uᵢ ⟶ Uᵢ` and `W ×[X] Uᵢ ⟶ W ⟶ Y`.

It suffices to show that the two map agrees when restricted onto `Uⱼ ×[Z] Y`. In this case,
both maps factor through `V j i` via `pullback_fst_ι_to_V` -/
theorem lift_comp_ι (i : 𝒰.J) :
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (by rw [← pullback.condition_assoc, Category.assoc, p_comm]) ≫
        (gluing 𝒰 f g).ι i =
      (pullback.fst : pullback (p1 𝒰 f g) (𝒰.map i) ⟶ _) := by
  apply ((gluing 𝒰 f g).openCover.pullbackCover pullback.fst).hom_ext
  intro j
  dsimp only [OpenCover.pullbackCover]
  trans pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i ≫ (gluing 𝒰 f g).ι _
  · rw [← show _ = fV 𝒰 f g j i ≫ _ from (gluing 𝒰 f g).glue_condition j i]
    simp_rw [← Category.assoc]
    congr 1
    rw [gluing_f, gluing_t]
    apply pullback.hom_ext <;> simp_rw [Category.assoc]
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · rw [t_fst_fst, pullback.lift_fst, pullbackFstιToV_snd]; rfl
    · rw [t_fst_snd, pullback.lift_snd, pullbackFstιToV_fst_assoc, pullback.condition_assoc]
      erw [Multicoequalizer.π_desc]
      rfl
  · rw [pullback.condition, ← Category.assoc]
    congr 1
    

Proof state:
case e_a
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
i : 𝒰.J
j : (OpenCover.pullbackCover (GlueData.openCover (gluing 𝒰 f g)) pullback.fst).J
⊢ pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i = pullback.snd

Next tactic:
apply pullback.hom_ext
/-- We show that the map `W ×[X] Uᵢ ⟶ Uᵢ ×[Z] Y ⟶ W` is the first projection, where the
first map is given by the lift of `W ×[X] Uᵢ ⟶ Uᵢ` and `W ×[X] Uᵢ ⟶ W ⟶ Y`.

It suffices to show that the two map agrees when restricted onto `Uⱼ ×[Z] Y`. In this case,
both maps factor through `V j i` via `pullback_fst_ι_to_V` -/
theorem lift_comp_ι (i : 𝒰.J) :
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (by rw [← pullback.condition_assoc, Category.assoc, p_comm]) ≫
        (gluing 𝒰 f g).ι i =
      (pullback.fst : pullback (p1 𝒰 f g) (𝒰.map i) ⟶ _) := by
  apply ((gluing 𝒰 f g).openCover.pullbackCover pullback.fst).hom_ext
  intro j
  dsimp only [OpenCover.pullbackCover]
  trans pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i ≫ (gluing 𝒰 f g).ι _
  · rw [← show _ = fV 𝒰 f g j i ≫ _ from (gluing 𝒰 f g).glue_condition j i]
    simp_rw [← Category.assoc]
    congr 1
    rw [gluing_f, gluing_t]
    apply pullback.hom_ext <;> simp_rw [Category.assoc]
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · rw [t_fst_fst, pullback.lift_fst, pullbackFstιToV_snd]; rfl
    · rw [t_fst_snd, pullback.lift_snd, pullbackFstιToV_fst_assoc, pullback.condition_assoc]
      erw [Multicoequalizer.π_desc]
      rfl
  · rw [pullback.condition, ← Category.assoc]
    congr 1
    apply pullback.hom_ext
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · 

Proof state:
case e_a.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
i : 𝒰.J
j : (OpenCover.pullbackCover (GlueData.openCover (gluing 𝒰 f g)) pullback.fst).J
⊢ (pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i) ≫ pullback.fst = pullback.snd ≫ pullback.fst

Next tactic:
simp only [pullbackFstιToV_fst]
/-- We show that the map `W ×[X] Uᵢ ⟶ Uᵢ ×[Z] Y ⟶ W` is the first projection, where the
first map is given by the lift of `W ×[X] Uᵢ ⟶ Uᵢ` and `W ×[X] Uᵢ ⟶ W ⟶ Y`.

It suffices to show that the two map agrees when restricted onto `Uⱼ ×[Z] Y`. In this case,
both maps factor through `V j i` via `pullback_fst_ι_to_V` -/
theorem lift_comp_ι (i : 𝒰.J) :
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (by rw [← pullback.condition_assoc, Category.assoc, p_comm]) ≫
        (gluing 𝒰 f g).ι i =
      (pullback.fst : pullback (p1 𝒰 f g) (𝒰.map i) ⟶ _) := by
  apply ((gluing 𝒰 f g).openCover.pullbackCover pullback.fst).hom_ext
  intro j
  dsimp only [OpenCover.pullbackCover]
  trans pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i ≫ (gluing 𝒰 f g).ι _
  · rw [← show _ = fV 𝒰 f g j i ≫ _ from (gluing 𝒰 f g).glue_condition j i]
    simp_rw [← Category.assoc]
    congr 1
    rw [gluing_f, gluing_t]
    apply pullback.hom_ext <;> simp_rw [Category.assoc]
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · rw [t_fst_fst, pullback.lift_fst, pullbackFstιToV_snd]; rfl
    · rw [t_fst_snd, pullback.lift_snd, pullbackFstιToV_fst_assoc, pullback.condition_assoc]
      erw [Multicoequalizer.π_desc]
      rfl
  · rw [pullback.condition, ← Category.assoc]
    congr 1
    apply pullback.hom_ext
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · simp only [pullbackFstιToV_fst]; 

Proof state:
case e_a.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
i : 𝒰.J
j : (OpenCover.pullbackCover (GlueData.openCover (gluing 𝒰 f g)) pullback.fst).J
⊢ pullback.snd ≫ pullback.fst = pullback.snd ≫ pullback.fst

Next tactic:
rfl
/-- We show that the map `W ×[X] Uᵢ ⟶ Uᵢ ×[Z] Y ⟶ W` is the first projection, where the
first map is given by the lift of `W ×[X] Uᵢ ⟶ Uᵢ` and `W ×[X] Uᵢ ⟶ W ⟶ Y`.

It suffices to show that the two map agrees when restricted onto `Uⱼ ×[Z] Y`. In this case,
both maps factor through `V j i` via `pullback_fst_ι_to_V` -/
theorem lift_comp_ι (i : 𝒰.J) :
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (by rw [← pullback.condition_assoc, Category.assoc, p_comm]) ≫
        (gluing 𝒰 f g).ι i =
      (pullback.fst : pullback (p1 𝒰 f g) (𝒰.map i) ⟶ _) := by
  apply ((gluing 𝒰 f g).openCover.pullbackCover pullback.fst).hom_ext
  intro j
  dsimp only [OpenCover.pullbackCover]
  trans pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i ≫ (gluing 𝒰 f g).ι _
  · rw [← show _ = fV 𝒰 f g j i ≫ _ from (gluing 𝒰 f g).glue_condition j i]
    simp_rw [← Category.assoc]
    congr 1
    rw [gluing_f, gluing_t]
    apply pullback.hom_ext <;> simp_rw [Category.assoc]
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · rw [t_fst_fst, pullback.lift_fst, pullbackFstιToV_snd]; rfl
    · rw [t_fst_snd, pullback.lift_snd, pullbackFstιToV_fst_assoc, pullback.condition_assoc]
      erw [Multicoequalizer.π_desc]
      rfl
  · rw [pullback.condition, ← Category.assoc]
    congr 1
    apply pullback.hom_ext
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · simp only [pullbackFstιToV_fst]; rfl
    · 

Proof state:
case e_a.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
i : 𝒰.J
j : (OpenCover.pullbackCover (GlueData.openCover (gluing 𝒰 f g)) pullback.fst).J
⊢ (pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i) ≫ pullback.snd = pullback.snd ≫ pullback.snd

Next tactic:
simp only [pullbackFstιToV_fst]
/-- We show that the map `W ×[X] Uᵢ ⟶ Uᵢ ×[Z] Y ⟶ W` is the first projection, where the
first map is given by the lift of `W ×[X] Uᵢ ⟶ Uᵢ` and `W ×[X] Uᵢ ⟶ W ⟶ Y`.

It suffices to show that the two map agrees when restricted onto `Uⱼ ×[Z] Y`. In this case,
both maps factor through `V j i` via `pullback_fst_ι_to_V` -/
theorem lift_comp_ι (i : 𝒰.J) :
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (by rw [← pullback.condition_assoc, Category.assoc, p_comm]) ≫
        (gluing 𝒰 f g).ι i =
      (pullback.fst : pullback (p1 𝒰 f g) (𝒰.map i) ⟶ _) := by
  apply ((gluing 𝒰 f g).openCover.pullbackCover pullback.fst).hom_ext
  intro j
  dsimp only [OpenCover.pullbackCover]
  trans pullbackFstιToV 𝒰 f g i j ≫ fV 𝒰 f g j i ≫ (gluing 𝒰 f g).ι _
  · rw [← show _ = fV 𝒰 f g j i ≫ _ from (gluing 𝒰 f g).glue_condition j i]
    simp_rw [← Category.assoc]
    congr 1
    rw [gluing_f, gluing_t]
    apply pullback.hom_ext <;> simp_rw [Category.assoc]
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · rw [t_fst_fst, pullback.lift_fst, pullbackFstιToV_snd]; rfl
    · rw [t_fst_snd, pullback.lift_snd, pullbackFstιToV_fst_assoc, pullback.condition_assoc]
      erw [Multicoequalizer.π_desc]
      rfl
  · rw [pullback.condition, ← Category.assoc]
    congr 1
    apply pullback.hom_ext
    -- Porting note : in the following two bullet points, `rfl` was not necessary
    · simp only [pullbackFstιToV_fst]; rfl
    · simp only [pullbackFstιToV_fst]; 

Proof state:
case e_a.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
i : 𝒰.J
j : (OpenCover.pullbackCover (GlueData.openCover (gluing 𝒰 f g)) pullback.fst).J
⊢ pullback.snd ≫ pullback.snd = pullback.snd ≫ pullback.snd

Next tactic:
rfl
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ 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
i : 𝒰.J
⊢ pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i) ≅ pullback (OpenCover.map 𝒰 i ≫ f) g

Next tactic:
fconstructor
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  

Proof state:
case hom
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
i : 𝒰.J
⊢ pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i) ⟶ pullback (OpenCover.map 𝒰 i ≫ f) g
case inv
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
i : 𝒰.J
⊢ pullback (OpenCover.map 𝒰 i ≫ f) g ⟶ pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)
case hom_inv_id
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
i : 𝒰.J
⊢ autoParam (?hom ≫ ?inv = 𝟙 (pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i))) _auto✝
case inv_hom_id
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
i : 𝒰.J
⊢ autoParam (?inv ≫ ?hom = 𝟙 (pullback (OpenCover.map 𝒰 i ≫ f) g)) _auto✝

Next tactic:
exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 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
i : 𝒰.J
⊢ pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g

Next tactic:
rw [← pullback.condition_assoc, Category.assoc, p_comm]
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  

Proof state:
case inv
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
i : 𝒰.J
⊢ pullback (OpenCover.map 𝒰 i ≫ f) g ⟶ pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)
case hom_inv_id
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
i : 𝒰.J
⊢ autoParam
    (pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) ≫
        ?inv =
      𝟙 (pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)))
    _auto✝
case inv_hom_id
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
i : 𝒰.J
⊢ autoParam
    (?inv ≫
        pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) =
      𝟙 (pullback (OpenCover.map 𝒰 i ≫ f) g))
    _auto✝

Next tactic:
refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (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
i : 𝒰.J
⊢ GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i

Next tactic:
erw [Multicoequalizer.π_desc]
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · 

Proof state:
case hom_inv_id
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
i : 𝒰.J
⊢ autoParam
    (pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) ≫
        pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i) =
      𝟙 (pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)))
    _auto✝

Next tactic:
apply pullback.hom_ext
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · 

Proof state:
case hom_inv_id.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
i : 𝒰.J
⊢ (pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) ≫
        pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i)) ≫
      pullback.fst =
    𝟙 (pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)) ≫ pullback.fst

Next tactic:
simpa using lift_comp_ι 𝒰 f g i
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · simpa using lift_comp_ι 𝒰 f g i
    · 

Proof state:
case hom_inv_id.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
i : 𝒰.J
⊢ (pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) ≫
        pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i)) ≫
      pullback.snd =
    𝟙 (pullback (p1 𝒰 f g) (OpenCover.map 𝒰 i)) ≫ pullback.snd

Next tactic:
simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst, Category.id_comp]
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · simpa using lift_comp_ι 𝒰 f g i
    · simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst, Category.id_comp]
  · 

Proof state:
case inv_hom_id
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
i : 𝒰.J
⊢ autoParam
    (pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i) ≫
        pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g) =
      𝟙 (pullback (OpenCover.map 𝒰 i ≫ f) g))
    _auto✝

Next tactic:
apply pullback.hom_ext
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · simpa using lift_comp_ι 𝒰 f g i
    · simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst, Category.id_comp]
  · apply pullback.hom_ext
    · 

Proof state:
case inv_hom_id.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
i : 𝒰.J
⊢ (pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i) ≫
        pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g)) ≫
      pullback.fst =
    𝟙 (pullback (OpenCover.map 𝒰 i ≫ f) g) ≫ pullback.fst

Next tactic:
simp only [Category.assoc, pullback.lift_fst, pullback.lift_snd, Category.id_comp]
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · simpa using lift_comp_ι 𝒰 f g i
    · simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst, Category.id_comp]
  · apply pullback.hom_ext
    · simp only [Category.assoc, pullback.lift_fst, pullback.lift_snd, Category.id_comp]
    · 

Proof state:
case inv_hom_id.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
i : 𝒰.J
⊢ (pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
          (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i) ≫
        pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
          (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g)) ≫
      pullback.snd =
    𝟙 (pullback (OpenCover.map 𝒰 i ≫ f) g) ≫ pullback.snd

Next tactic:
simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst_assoc, Category.id_comp]
/-- The canonical isomorphism between `W ×[X] Uᵢ` and `Uᵢ ×[X] Y`. That is, the preimage of `Uᵢ` in
`W` along `p1` is indeed `Uᵢ ×[X] Y`. -/
def pullbackP1Iso (i : 𝒰.J) : pullback (p1 𝒰 f g) (𝒰.map i) ≅ pullback (𝒰.map i ≫ f) g := by
  fconstructor
  exact
    pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
      (by rw [← pullback.condition_assoc, Category.assoc, p_comm])
  refine' pullback.lift ((gluing 𝒰 f g).ι i) pullback.fst (by erw [Multicoequalizer.π_desc])
  · apply pullback.hom_ext
    · simpa using lift_comp_ι 𝒰 f g i
    · simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst, Category.id_comp]
  · apply pullback.hom_ext
    · simp only [Category.assoc, pullback.lift_fst, pullback.lift_snd, Category.id_comp]
    · simp only [Category.assoc, pullback.lift_snd, pullback.lift_fst_assoc, Category.id_comp]
      

Proof state:
case inv_hom_id.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
i : 𝒰.J
⊢ GlueData.ι (gluing 𝒰 f g) i ≫ p2 𝒰 f g = pullback.snd

Next tactic:
erw [Multicoequalizer.π_desc]
@[simp, reassoc]
theorem pullbackP1Iso_hom_fst (i : 𝒰.J) :
    (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.fst = pullback.snd := 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
i : 𝒰.J
⊢ (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.fst = pullback.snd

Next tactic:
delta pullbackP1Iso
@[simp, reassoc]
theorem pullbackP1Iso_hom_fst (i : 𝒰.J) :
    (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.fst = pullback.snd := by
  delta pullbackP1Iso
  

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
i : 𝒰.J
⊢ (Iso.mk
          (pullback.lift pullback.snd (pullback.fst ≫ p2 𝒰 f g)
            (_ : pullback.snd ≫ OpenCover.map 𝒰 i ≫ f = (pullback.fst ≫ p2 𝒰 f g) ≫ g))
          (pullback.lift (GlueData.ι (gluing 𝒰 f g) i) pullback.fst
            (_ : GlueData.ι (gluing 𝒰 f g) i ≫ p1 𝒰 f g = pullback.fst ≫ OpenCover.map 𝒰 i))).hom ≫
      pullback.fst =
    pullback.snd

Next tactic:
simp only [pullback.lift_fst]
@[simp, reassoc]
theorem pullbackP1Iso_hom_snd (i : 𝒰.J) :
    (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.snd = pullback.fst ≫ p2 𝒰 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
i : 𝒰.J
⊢ (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.snd = pullback.fst ≫ p2 𝒰 f g

Next tactic:
delta pullbackP1Iso