l3lab/ntp-mathlib huggingface dataset:
/-- If a section `f` is a unit in each stalk, `f` must be a unit. -/
theorem isUnit_of_isUnit_germ (U : Opens X) (f : X.presheaf.obj (op U))
    (h : ∀ x : U, IsUnit (X.presheaf.germ x f)) : IsUnit f := by
  -- We pick a cover of `U` by open sets `V x`, such that `f` is a unit on each `V x`.
  choose V iVU m h_unit using fun x : U => X.isUnit_res_of_isUnit_germ U f x (h x)
  have hcover : U ≤ iSup V
  · intro x hxU
    -- Porting note : in Lean3 `rw` is sufficient
    erw [Opens.mem_iSup]
    exact ⟨⟨x, hxU⟩, m ⟨x, hxU⟩⟩
  -- Let `g x` denote the inverse of `f` in `U x`.
  choose g hg using fun x : U => IsUnit.exists_right_inv (h_unit x)
  have ic : IsCompatible (sheaf X).val V g
  -- swap
  · intro x y
    apply section_ext X.sheaf (V x ⊓ V y)
    rintro ⟨z, hzVx, hzVy⟩
    erw [germ_res_apply, germ_res_apply]
    apply (IsUnit.mul_right_inj (h ⟨z, (iVU x).le hzVx⟩)).mp
    -- Porting note : now need explicitly typing the rewrites
    rw [← show X.presheaf.germ ⟨z, hzVx⟩ (X.presheaf.map (iVU x).op f) =
      X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from
      X.presheaf.germ_res_apply (iVU x) ⟨z, hzVx⟩ f]
    -- Porting note : change was not necessary in Lean3
    change X.presheaf.germ ⟨z, hzVx⟩ _ * (X.presheaf.germ ⟨z, hzVx⟩ _) =
      X.presheaf.germ ⟨z, hzVx⟩ _ * X.presheaf.germ ⟨z, hzVy⟩ (g y)
    rw [← RingHom.map_mul,
      congr_arg (X.presheaf.germ (⟨z, hzVx⟩ : V x)) (hg x),
      -- Porting note : now need explicitly typing the rewrites
      show X.presheaf.germ ⟨z, hzVx⟩ (X.presheaf.map (iVU x).op f) =
        X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from X.presheaf.germ_res_apply _ _ f,
      -- Porting note : now need explicitly typing the rewrites
      ← show X.presheaf.germ ⟨z, hzVy⟩ (X.presheaf.map (iVU y).op f) =
          X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from
          X.presheaf.germ_res_apply (iVU y) ⟨z, hzVy⟩ f,
      ← RingHom.map_mul,
      congr_arg (X.presheaf.germ (⟨z, hzVy⟩ : V y)) (hg y), RingHom.map_one, RingHom.map_one]
  -- We claim that these local inverses glue together to a global inverse of `f`.
  obtain ⟨gl, gl_spec, -⟩ := X.sheaf.existsUnique_gluing' V U iVU hcover g ic
  apply isUnit_of_mul_eq_one f gl
  apply X.sheaf.eq_of_locally_eq' V U iVU hcover
  intro i
  rw [RingHom.map_one, RingHom.map_mul, gl_spec]
  

Proof state:
case intro.intro.h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
h : ∀ (x : ↥U), IsUnit ((germ X.presheaf x) f)
V : ↥U → Opens ↑↑X.toPresheafedSpace
iVU : (x : ↥U) → V x ⟶ U
m : ∀ (x : ↥U), ↑x ∈ V x
h_unit : ∀ (x : ↥U), IsUnit ((X.presheaf.map (iVU x).op) f)
hcover : U ≤ iSup V
g : (x : ↥U) → (CategoryTheory.forget CommRingCat).obj (X.presheaf.obj (op (V x)))
hg : ∀ (x : ↥U), (X.presheaf.map (iVU x).op) f * g x = 1
ic : IsCompatible (sheaf X).val V g
gl : (CategoryTheory.forget CommRingCat).obj ((sheaf X).val.obj (op U))
gl_spec : ∀ (i : ↥U), ((sheaf X).val.map (iVU i).op) gl = g i
i : ↥U
⊢ ((sheaf X).val.map (iVU i).op) f * g i = 1

Next tactic:
exact hg i
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    

Proof state:
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
⊢ IsOpen (Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)})

Next tactic:
rw [isOpen_iff_forall_mem_open]
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    

Proof state:
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
⊢ ∀ x ∈ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)},
    ∃ t ⊆ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)}, IsOpen t ∧ x ∈ t

Next tactic:
rintro _ ⟨x, hx, rfl⟩
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    

Proof state:
case intro.intro
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
⊢ ∃ t ⊆ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)}, IsOpen t ∧ ↑x ∈ t

Next tactic:
obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    

Proof state:
case intro.intro.intro.intro.intro
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
⊢ ∃ t ⊆ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)}, IsOpen t ∧ ↑x ∈ t

Next tactic:
use V.1
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
⊢ V.carrier ⊆ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)} ∧ IsOpen V.carrier ∧ ↑x ∈ V.carrier

Next tactic:
refine' ⟨_, V.2, hxV⟩
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
⊢ V.carrier ⊆ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)}

Next tactic:
intro y hy
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ y ∈ Subtype.val '' {x | IsUnit ((germ X.presheaf x) f)}

Next tactic:
use (⟨y, i.le hy⟩ : U)
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    use (⟨y, i.le hy⟩ : U)
    

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ { val := y, property := (_ : y ∈ ↑U) } ∈ {x | IsUnit ((germ X.presheaf x) f)} ∧
    ↑{ val := y, property := (_ : y ∈ ↑U) } = y

Next tactic:
rw [Set.mem_setOf_eq]
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    use (⟨y, i.le hy⟩ : U)
    rw [Set.mem_setOf_eq]
    

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ IsUnit ((germ X.presheaf { val := y, property := (_ : y ∈ ↑U) }) f) ∧ ↑{ val := y, property := (_ : y ∈ ↑U) } = y

Next tactic:
constructor
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    use (⟨y, i.le hy⟩ : U)
    rw [Set.mem_setOf_eq]
    constructor
    · 

Proof state:
case h.left
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ IsUnit ((germ X.presheaf { val := y, property := (_ : y ∈ ↑U) }) f)

Next tactic:
convert RingHom.isUnit_map (X.presheaf.germ ⟨y, hy⟩) hf
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    use (⟨y, i.le hy⟩ : U)
    rw [Set.mem_setOf_eq]
    constructor
    · convert RingHom.isUnit_map (X.presheaf.germ ⟨y, hy⟩) hf
      

Proof state:
case h.e'_3
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ (germ X.presheaf { val := y, property := (_ : y ∈ ↑U) }) f =
    (germ X.presheaf { val := y, property := hy }) ((X.presheaf.map i.op) f)

Next tactic:
exact (X.presheaf.germ_res_apply i ⟨y, hy⟩ f).symm
/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at
`x` is a unit.
-/
def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where
  -- Porting note : `coe` does not work
  carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) }
  is_open' := by
    rw [isOpen_iff_forall_mem_open]
    rintro _ ⟨x, hx, rfl⟩
    obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx
    use V.1
    refine' ⟨_, V.2, hxV⟩
    intro y hy
    use (⟨y, i.le hy⟩ : U)
    rw [Set.mem_setOf_eq]
    constructor
    · convert RingHom.isUnit_map (X.presheaf.germ ⟨y, hy⟩) hf
      exact (X.presheaf.germ_res_apply i ⟨y, hy⟩ f).symm
    · 

Proof state:
case h.right
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
V : Opens ↑↑X.toPresheafedSpace
i : V ⟶ U
hxV : ↑x ∈ V
hf : IsUnit ((X.presheaf.map i.op) f)
y : ↑↑X.toPresheafedSpace
hy : y ∈ V.carrier
⊢ ↑{ val := y, property := (_ : y ∈ ↑U) } = y

Next tactic:
rfl
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  

Proof state:
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
⊢ ↑x ∈ basicOpen X f ↔ IsUnit ((germ X.presheaf x) f)

Next tactic:
constructor
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  constructor
  · 

Proof state:
case mp
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
⊢ ↑x ∈ basicOpen X f → IsUnit ((germ X.presheaf x) f)

Next tactic:
rintro ⟨x, hx, a⟩
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  constructor
  · rintro ⟨x, hx, a⟩; 

Proof state:
case mp.intro.intro
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x✝ x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
a : ↑x = ↑x✝
⊢ IsUnit ((germ X.presheaf x✝) f)

Next tactic:
cases Subtype.eq a
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  constructor
  · rintro ⟨x, hx, a⟩; cases Subtype.eq a; 

Proof state:
case mp.intro.intro.refl
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
a : ↑x = ↑x
⊢ IsUnit ((germ X.presheaf x) f)

Next tactic:
exact hx
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  constructor
  · rintro ⟨x, hx, a⟩; cases Subtype.eq a; exact hx
  · 

Proof state:
case mpr
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
⊢ IsUnit ((germ X.presheaf x) f) → ↑x ∈ basicOpen X f

Next tactic:
intro h
@[simp]
theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) :
    ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by
  constructor
  · rintro ⟨x, hx, a⟩; cases Subtype.eq a; exact hx
  · intro h; 

Proof state:
case mpr
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
h : IsUnit ((germ X.presheaf x) f)
⊢ ↑x ∈ basicOpen X f

Next tactic:
exact ⟨x, h, rfl⟩
@[simp]
theorem mem_top_basicOpen (f : X.presheaf.obj (op ⊤)) (x : X) :
    x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ ⟨x, show x ∈ (⊤ : Opens X) by 

Proof state:
X : RingedSpace
f : ↑(X.presheaf.obj (op ⊤))
x : ↑↑X.toPresheafedSpace
⊢ x ∈ ⊤

Next tactic:
trivial
theorem basicOpen_le {U : Opens X} (f : X.presheaf.obj (op U)) : X.basicOpen f ≤ U := by
  

Proof state:
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
⊢ basicOpen X f ≤ U

Next tactic:
rintro _ ⟨x, _, rfl⟩
theorem basicOpen_le {U : Opens X} (f : X.presheaf.obj (op U)) : X.basicOpen f ≤ U := by
  rintro _ ⟨x, _, rfl⟩; 

Proof state:
case intro.intro
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
left✝ : x ∈ {x | IsUnit ((germ X.presheaf x) f)}
⊢ ↑x ∈ ↑U

Next tactic:
exact x.2
/-- The restriction of a section `f` to the basic open of `f` is a unit. -/
theorem isUnit_res_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) :
    IsUnit (X.presheaf.map (@homOfLE (Opens X) _ _ _ (X.basicOpen_le f)).op f) := by
  

Proof state:
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
⊢ IsUnit ((X.presheaf.map (homOfLE (_ : basicOpen X f ≤ U)).op) f)

Next tactic:
apply isUnit_of_isUnit_germ
/-- The restriction of a section `f` to the basic open of `f` is a unit. -/
theorem isUnit_res_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) :
    IsUnit (X.presheaf.map (@homOfLE (Opens X) _ _ _ (X.basicOpen_le f)).op f) := by
  apply isUnit_of_isUnit_germ
  

Proof state:
case h
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
⊢ ∀ (x : ↥(basicOpen X f)), IsUnit ((germ X.presheaf x) ((X.presheaf.map (homOfLE (_ : basicOpen X f ≤ U)).op) f))

Next tactic:
rintro ⟨_, ⟨x, (hx : IsUnit _), rfl⟩⟩
/-- The restriction of a section `f` to the basic open of `f` is a unit. -/
theorem isUnit_res_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) :
    IsUnit (X.presheaf.map (@homOfLE (Opens X) _ _ _ (X.basicOpen_le f)).op f) := by
  apply isUnit_of_isUnit_germ
  rintro ⟨_, ⟨x, (hx : IsUnit _), rfl⟩⟩
  

Proof state:
case h.mk.intro.intro
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : IsUnit ((germ X.presheaf x) f)
⊢ IsUnit
    ((germ X.presheaf { val := ↑x, property := (_ : ∃ a ∈ {x | IsUnit ((germ X.presheaf x) f)}, ↑a = ↑x) })
      ((X.presheaf.map (homOfLE (_ : basicOpen X f ≤ U)).op) f))

Next tactic:
convert hx
/-- The restriction of a section `f` to the basic open of `f` is a unit. -/
theorem isUnit_res_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) :
    IsUnit (X.presheaf.map (@homOfLE (Opens X) _ _ _ (X.basicOpen_le f)).op f) := by
  apply isUnit_of_isUnit_germ
  rintro ⟨_, ⟨x, (hx : IsUnit _), rfl⟩⟩
  convert hx
  

Proof state:
case h.e'_3
X : RingedSpace
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↥U
hx : IsUnit ((germ X.presheaf x) f)
⊢ (germ X.presheaf { val := ↑x, property := (_ : ∃ a ∈ {x | IsUnit ((germ X.presheaf x) f)}, ↑a = ↑x) })
      ((X.presheaf.map (homOfLE (_ : basicOpen X f ≤ U)).op) f) =
    (germ X.presheaf x) f

Next tactic:
convert X.presheaf.germ_res_apply _ _ _
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  

Proof state:
X : RingedSpace
U V : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
i : U ⟶ V
f : ↑(X.presheaf.obj U)
⊢ basicOpen X ((X.presheaf.map i) f) = V.unop ⊓ basicOpen X f

Next tactic:
induction U using Opposite.rec'
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  

Proof state:
case h
X : RingedSpace
V : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
X✝ : Opens ↑↑X.toPresheafedSpace
i : op X✝ ⟶ V
f : ↑(X.presheaf.obj (op X✝))
⊢ basicOpen X ((X.presheaf.map i) f) = V.unop ⊓ basicOpen X f

Next tactic:
induction V using Opposite.rec'
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  

Proof state:
case h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
i : op X✝¹ ⟶ op X✝
⊢ basicOpen X ((X.presheaf.map i) f) = (op X✝).unop ⊓ basicOpen X f

Next tactic:
let g := i.unop
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; 

Proof state:
case h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
i : op X✝¹ ⟶ op X✝
g : (op X✝).unop ⟶ (op X✝¹).unop := i.unop
⊢ basicOpen X ((X.presheaf.map i) f) = (op X✝).unop ⊓ basicOpen X f

Next tactic:
have : i = g.op := rfl
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; have : i = g.op := rfl; 

Proof state:
case h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
i : op X✝¹ ⟶ op X✝
g : (op X✝).unop ⟶ (op X✝¹).unop := i.unop
this : i = g.op
⊢ basicOpen X ((X.presheaf.map i) f) = (op X✝).unop ⊓ basicOpen X f

Next tactic:
clear_value g
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; have : i = g.op := rfl; clear_value g; 

Proof state:
case h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
i : op X✝¹ ⟶ op X✝
g : (op X✝).unop ⟶ (op X✝¹).unop
this : i = g.op
⊢ basicOpen X ((X.presheaf.map i) f) = (op X✝).unop ⊓ basicOpen X f

Next tactic:
subst this
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; have : i = g.op := rfl; clear_value g; subst this
  

Proof state:
case h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
g : (op X✝).unop ⟶ (op X✝¹).unop
⊢ basicOpen X ((X.presheaf.map g.op) f) = (op X✝).unop ⊓ basicOpen X f

Next tactic:
ext
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; have : i = g.op := rfl; clear_value g; subst this
  ext; 

Proof state:
case h.h.h.h
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
g : (op X✝).unop ⟶ (op X✝¹).unop
x✝ : ↑↑X.toPresheafedSpace
⊢ x✝ ∈ ↑(basicOpen X ((X.presheaf.map g.op) f)) ↔ x✝ ∈ ↑((op X✝).unop ⊓ basicOpen X f)

Next tactic:
constructor
@[simp]
theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) :
    @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by
  induction U using Opposite.rec'
  induction V using Opposite.rec'
  let g := i.unop; have : i = g.op := rfl; clear_value g; subst this
  ext; constructor
  · 

Proof state:
case h.h.h.h.mp
X : RingedSpace
X✝¹ : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op X✝¹))
X✝ : Opens ↑↑X.toPresheafedSpace
g : (op X✝).unop ⟶ (op X✝¹).unop
x✝ : ↑↑X.toPresheafedSpace
⊢ x✝ ∈ ↑(basicOpen X ((X.presheaf.map g.op) f)) → x✝ ∈ ↑((op X✝).unop ⊓ basicOpen X f)

Next tactic:
rintro ⟨x, hx : IsUnit _, rfl⟩