l3lab/ntp-mathlib huggingface dataset:
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · 

Proof state:
case hcover
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ V ≤ ⨆ t, if t.down = true then U₁ else U₂

Next tactic:
refine' le_trans hcover _
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      

Proof state:
case hcover
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ U₁ ⊔ U₂ ≤ ⨆ t, if t.down = true then U₁ else U₂

Next tactic:
rw [sup_le_iff]
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      

Proof state:
case hcover
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (U₁ ≤ ⨆ t, if t.down = true then U₁ else U₂) ∧ U₂ ≤ ⨆ t, if t.down = true then U₁ else U₂

Next tactic:
constructor
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · 

Proof state:
case hcover.left
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ U₁ ≤ ⨆ t, if t.down = true then U₁ else U₂

Next tactic:
convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · 

Proof state:
case hcover.right
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ U₂ ≤ ⨆ t, if t.down = true then U₁ else U₂

Next tactic:
convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · 

Proof state:
case h
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ ∀ (i : ULift.{v, 0} Bool),
    (F.val.map
          (if h : i.down = true then eqToHom (_ : (if i.down = true then U₁ else U₂) = U₁) ≫ i₁
            else eqToHom (_ : (if i.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
        s =
      (F.val.map
          (if h : i.down = true then eqToHom (_ : (if i.down = true then U₁ else U₂) = U₁) ≫ i₁
            else eqToHom (_ : (if i.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
        t

Next tactic:
rintro ⟨_ | _⟩
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · rintro ⟨_ | _⟩
      

Proof state:
case h.up.false
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t
case h.up.true
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := true }.down = true then
            eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := true }.down = true then
            eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t

Next tactic:
any_goals exact h₁
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · rintro ⟨_ | _⟩
      any_goals 

Proof state:
case h.up.false
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t

Next tactic:
exact h₁
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · rintro ⟨_ | _⟩
      any_goals 

Proof state:
case h.up.true
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := true }.down = true then
            eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := true }.down = true then
            eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := true }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t

Next tactic:
exact h₁
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · rintro ⟨_ | _⟩
      any_goals exact h₁
      

Proof state:
case h.up.false
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t

Next tactic:
any_goals exact h₂
theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂)
    (s t : F.1.obj (op V)) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t)
    (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by
  classical
    fapply F.eq_of_locally_eq' fun t : ULift Bool => if t.1 then U₁ else U₂
    · exact fun i => if h : i.1 then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂
    · refine' le_trans hcover _
      rw [sup_le_iff]
      constructor
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up true)
      · convert le_iSup (fun t : ULift Bool => if t.1 then U₁ else U₂) (ULift.up false)
    · rintro ⟨_ | _⟩
      any_goals exact h₁
      any_goals 

Proof state:
case h.up.false
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasLimits C
inst✝¹ : ReflectsIsomorphisms ConcreteCategory.forget
inst✝ : PreservesLimits ConcreteCategory.forget
X : TopCat
F : Sheaf C X
ι : Type v
U : ι → Opens ↑X
U₁ U₂ V : Opens ↑X
i₁ : U₁ ⟶ V
i₂ : U₂ ⟶ V
hcover : V ≤ U₁ ⊔ U₂
s t : (CategoryTheory.forget C).obj (F.val.obj (op V))
h₁ : (F.val.map i₁.op) s = (F.val.map i₁.op) t
h₂ : (F.val.map i₂.op) s = (F.val.map i₂.op) t
⊢ (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      s =
    (F.val.map
        (if h : { down := false }.down = true then
            eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₁) ≫ i₁
          else eqToHom (_ : (if { down := false }.down = true then U₁ else U₂) = U₂) ≫ i₂).op)
      t

Next tactic:
exact h₂
theorem objSupIsoProdEqLocus_inv_eq_iff {X : TopCat.{u}} (F : X.Sheaf CommRingCat.{u})
    {U V W UW VW : Opens X} (e : W ≤ U ⊔ V) (x) (y : F.1.obj (op W))
    (h₁ : UW = U ⊓ W) (h₂ : VW = V ⊓ W) :
    F.1.map (homOfLE e).op ((F.objSupIsoProdEqLocus U V).inv x) = y ↔
    F.1.map (homOfLE (h₁ ▸ inf_le_left : UW ≤ U)).op x.1.1 =
      F.1.map (homOfLE <| h₁ ▸ inf_le_right).op y ∧
    F.1.map (homOfLE (h₂ ▸ inf_le_left : VW ≤ V)).op x.1.2 =
      F.1.map (homOfLE <| h₂ ▸ inf_le_right).op y := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : ConcreteCategory C
X : TopCat
F : Sheaf CommRingCat X
U V W UW VW : Opens ↑X
e : W ≤ U ⊔ V
x :
  (CategoryTheory.forget CommRingCat).obj
    (CommRingCat.of
      ↥(RingHom.eqLocus
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ U)).op) (RingHom.fst ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ V)).op)
            (RingHom.snd ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))))
y : ↑(F.val.obj (op W))
h₁ : UW = U ⊓ W
h₂ : VW = V ⊓ W
⊢ (F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x) = y ↔
    (F.val.map (homOfLE (_ : UW ≤ U)).op) (↑x).1 = (F.val.map (homOfLE (_ : UW ≤ W)).op) y ∧
      (F.val.map (homOfLE (_ : VW ≤ V)).op) (↑x).2 = (F.val.map (homOfLE (_ : VW ≤ W)).op) y

Next tactic:
subst h₁ h₂
theorem objSupIsoProdEqLocus_inv_eq_iff {X : TopCat.{u}} (F : X.Sheaf CommRingCat.{u})
    {U V W UW VW : Opens X} (e : W ≤ U ⊔ V) (x) (y : F.1.obj (op W))
    (h₁ : UW = U ⊓ W) (h₂ : VW = V ⊓ W) :
    F.1.map (homOfLE e).op ((F.objSupIsoProdEqLocus U V).inv x) = y ↔
    F.1.map (homOfLE (h₁ ▸ inf_le_left : UW ≤ U)).op x.1.1 =
      F.1.map (homOfLE <| h₁ ▸ inf_le_right).op y ∧
    F.1.map (homOfLE (h₂ ▸ inf_le_left : VW ≤ V)).op x.1.2 =
      F.1.map (homOfLE <| h₂ ▸ inf_le_right).op y := by
  subst h₁ h₂
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : ConcreteCategory C
X : TopCat
F : Sheaf CommRingCat X
U V W : Opens ↑X
e : W ≤ U ⊔ V
x :
  (CategoryTheory.forget CommRingCat).obj
    (CommRingCat.of
      ↥(RingHom.eqLocus
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ U)).op) (RingHom.fst ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ V)).op)
            (RingHom.snd ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))))
y : ↑(F.val.obj (op W))
⊢ (F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x) = y ↔
    (F.val.map (homOfLE (_ : U ⊓ W ≤ U)).op) (↑x).1 = (F.val.map (homOfLE (_ : U ⊓ W ≤ W)).op) y ∧
      (F.val.map (homOfLE (_ : V ⊓ W ≤ V)).op) (↑x).2 = (F.val.map (homOfLE (_ : V ⊓ W ≤ W)).op) y

Next tactic:
constructor
theorem objSupIsoProdEqLocus_inv_eq_iff {X : TopCat.{u}} (F : X.Sheaf CommRingCat.{u})
    {U V W UW VW : Opens X} (e : W ≤ U ⊔ V) (x) (y : F.1.obj (op W))
    (h₁ : UW = U ⊓ W) (h₂ : VW = V ⊓ W) :
    F.1.map (homOfLE e).op ((F.objSupIsoProdEqLocus U V).inv x) = y ↔
    F.1.map (homOfLE (h₁ ▸ inf_le_left : UW ≤ U)).op x.1.1 =
      F.1.map (homOfLE <| h₁ ▸ inf_le_right).op y ∧
    F.1.map (homOfLE (h₂ ▸ inf_le_left : VW ≤ V)).op x.1.2 =
      F.1.map (homOfLE <| h₂ ▸ inf_le_right).op y := by
  subst h₁ h₂
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : ConcreteCategory C
X : TopCat
F : Sheaf CommRingCat X
U V W : Opens ↑X
e : W ≤ U ⊔ V
x :
  (CategoryTheory.forget CommRingCat).obj
    (CommRingCat.of
      ↥(RingHom.eqLocus
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ U)).op) (RingHom.fst ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ V)).op)
            (RingHom.snd ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))))
y : ↑(F.val.obj (op W))
⊢ (F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x) = y →
    (F.val.map (homOfLE (_ : U ⊓ W ≤ U)).op) (↑x).1 = (F.val.map (homOfLE (_ : U ⊓ W ≤ W)).op) y ∧
      (F.val.map (homOfLE (_ : V ⊓ W ≤ V)).op) (↑x).2 = (F.val.map (homOfLE (_ : V ⊓ W ≤ W)).op) y

Next tactic:
rintro rfl
theorem objSupIsoProdEqLocus_inv_eq_iff {X : TopCat.{u}} (F : X.Sheaf CommRingCat.{u})
    {U V W UW VW : Opens X} (e : W ≤ U ⊔ V) (x) (y : F.1.obj (op W))
    (h₁ : UW = U ⊓ W) (h₂ : VW = V ⊓ W) :
    F.1.map (homOfLE e).op ((F.objSupIsoProdEqLocus U V).inv x) = y ↔
    F.1.map (homOfLE (h₁ ▸ inf_le_left : UW ≤ U)).op x.1.1 =
      F.1.map (homOfLE <| h₁ ▸ inf_le_right).op y ∧
    F.1.map (homOfLE (h₂ ▸ inf_le_left : VW ≤ V)).op x.1.2 =
      F.1.map (homOfLE <| h₂ ▸ inf_le_right).op y := by
  subst h₁ h₂
  constructor
  · rintro rfl
    

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : ConcreteCategory C
X : TopCat
F : Sheaf CommRingCat X
U V W : Opens ↑X
e : W ≤ U ⊔ V
x :
  (CategoryTheory.forget CommRingCat).obj
    (CommRingCat.of
      ↥(RingHom.eqLocus
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ U)).op) (RingHom.fst ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ V)).op)
            (RingHom.snd ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))))
⊢ (F.val.map (homOfLE (_ : U ⊓ W ≤ U)).op) (↑x).1 =
      (F.val.map (homOfLE (_ : U ⊓ W ≤ W)).op) ((F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x)) ∧
    (F.val.map (homOfLE (_ : V ⊓ W ≤ V)).op) (↑x).2 =
      (F.val.map (homOfLE (_ : V ⊓ W ≤ W)).op) ((F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x))

Next tactic:
rw [← TopCat.Sheaf.objSupIsoProdEqLocus_inv_fst, ← TopCat.Sheaf.objSupIsoProdEqLocus_inv_snd]
theorem objSupIsoProdEqLocus_inv_eq_iff {X : TopCat.{u}} (F : X.Sheaf CommRingCat.{u})
    {U V W UW VW : Opens X} (e : W ≤ U ⊔ V) (x) (y : F.1.obj (op W))
    (h₁ : UW = U ⊓ W) (h₂ : VW = V ⊓ W) :
    F.1.map (homOfLE e).op ((F.objSupIsoProdEqLocus U V).inv x) = y ↔
    F.1.map (homOfLE (h₁ ▸ inf_le_left : UW ≤ U)).op x.1.1 =
      F.1.map (homOfLE <| h₁ ▸ inf_le_right).op y ∧
    F.1.map (homOfLE (h₂ ▸ inf_le_left : VW ≤ V)).op x.1.2 =
      F.1.map (homOfLE <| h₂ ▸ inf_le_right).op y := by
  subst h₁ h₂
  constructor
  · rintro rfl
    rw [← TopCat.Sheaf.objSupIsoProdEqLocus_inv_fst, ← TopCat.Sheaf.objSupIsoProdEqLocus_inv_snd]
    

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : ConcreteCategory C
X : TopCat
F : Sheaf CommRingCat X
U V W : Opens ↑X
e : W ≤ U ⊔ V
x :
  (CategoryTheory.forget CommRingCat).obj
    (CommRingCat.of
      ↥(RingHom.eqLocus
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ U)).op) (RingHom.fst ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))
          (RingHom.comp (F.val.map (homOfLE (_ : U ⊓ V ≤ V)).op)
            (RingHom.snd ↑(F.val.obj (op U)) ↑(F.val.obj (op V))))))
⊢ (F.val.map (homOfLE (_ : U ⊓ W ≤ U)).op)
        ((F.val.map (homOfLE (_ : U ≤ U ⊔ V)).op) ((objSupIsoProdEqLocus F U V).inv x)) =
      (F.val.map (homOfLE (_ : U ⊓ W ≤ W)).op) ((F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x)) ∧
    (F.val.map (homOfLE (_ : V ⊓ W ≤ V)).op)
        ((F.val.map (homOfLE (_ : V ≤ U ⊔ V)).op) ((objSupIsoProdEqLocus F U V).inv x)) =
      (F.val.map (homOfLE (_ : V ⊓ W ≤ W)).op) ((F.val.map (homOfLE e).op) ((objSupIsoProdEqLocus F U V).inv x))

Next tactic:
simp only [← comp_apply, ← Functor.map_comp, ← op_comp, Category.assoc, homOfLE_comp, and_self]