l3lab/ntp-mathlib huggingface dataset:
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  

Proof state:
case right
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
⊢ const R (f * c) (h ^ (n + 1)) (PrimeSpectrum.basicOpen (h ^ (n + 1)))
      (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1)), y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1))) =
    ((structureSheaf R).val.map i_basic_open.op) (((structureSheaf R).val.map iVU.op) s)

Next tactic:
rw [← s_eq, res_const]
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  rw [← s_eq, res_const]
  -- Note that the last rewrite here generated an additional goal, which was a parameter
  -- of `res_const`. We prove this goal first
  swap
  · 

Proof state:
case right.hv
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
⊢ ∀ x ∈ PrimeSpectrum.basicOpen (h ^ (n + 1)), g ∈ Ideal.primeCompl x.asIdeal

Next tactic:
intro y hy
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  rw [← s_eq, res_const]
  -- Note that the last rewrite here generated an additional goal, which was a parameter
  -- of `res_const`. We prove this goal first
  swap
  · intro y hy
    

Proof state:
case right.hv
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
y : ↑(PrimeSpectrum.Top R)
hy : y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1))
⊢ g ∈ Ideal.primeCompl y.asIdeal

Next tactic:
rw [basic_opens_eq] at hy
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  rw [← s_eq, res_const]
  -- Note that the last rewrite here generated an additional goal, which was a parameter
  -- of `res_const`. We prove this goal first
  swap
  · intro y hy
    rw [basic_opens_eq] at hy
    

Proof state:
case right.hv
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
y : ↑(PrimeSpectrum.Top R)
hy : y ∈ PrimeSpectrum.basicOpen h
⊢ g ∈ Ideal.primeCompl y.asIdeal

Next tactic:
exact (Set.Subset.trans hDhV hVDg : _) hy
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  rw [← s_eq, res_const]
  -- Note that the last rewrite here generated an additional goal, which was a parameter
  -- of `res_const`. We prove this goal first
  swap
  · intro y hy
    rw [basic_opens_eq] at hy
    exact (Set.Subset.trans hDhV hVDg : _) hy
  -- All that is left is a simple calculation
  

Proof state:
case right
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
⊢ const R (f * c) (h ^ (n + 1)) (PrimeSpectrum.basicOpen (h ^ (n + 1)))
      (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1)), y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1))) =
    const R f g (PrimeSpectrum.basicOpen (h ^ (n + 1)))
      (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h ^ (n + 1)), y ∈ ↑(PrimeSpectrum.basicOpen g))

Next tactic:
apply const_ext
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2
  -- The problem is of course, that `g` and `h` don't need to coincide.
  -- But, since `basicOpen h ≤ basicOpen g`, some power of `h` must be a multiple of `g`
  cases' (PrimeSpectrum.basicOpen_le_basicOpen_iff h g).mp (Set.Subset.trans hDhV hVDg) with n hn
  -- Actually, we will need a *nonzero* power of `h`.
  -- This is because we will need the equality `basicOpen (h ^ n) = basicOpen h`, which only
  -- holds for a nonzero power `n`. We therefore artificially increase `n` by one.
  replace hn := Ideal.mul_mem_left (Ideal.span {g}) h hn
  rw [← pow_succ, Ideal.mem_span_singleton'] at hn
  cases' hn with c hc
  have basic_opens_eq := PrimeSpectrum.basicOpen_pow h (n + 1) (by linarith)
  have i_basic_open := eqToHom basic_opens_eq ≫ homOfLE hDhV
  -- We claim that `(f * c) / h ^ (n+1)` is our desired representation
  use f * c, h ^ (n + 1), i_basic_open ≫ iVU, (basic_opens_eq.symm.le : _) hxDh
  rw [op_comp, Functor.map_comp] --, comp_apply, ← s_eq, res_const]
  -- Porting note : `comp_apply` can't be rewritten, so use a change
  change const R _ _ _ _ = (structureSheaf R).1.map i_basic_open.op
    ((structureSheaf R).1.map iVU.op s)
  rw [← s_eq, res_const]
  -- Note that the last rewrite here generated an additional goal, which was a parameter
  -- of `res_const`. We prove this goal first
  swap
  · intro y hy
    rw [basic_opens_eq] at hy
    exact (Set.Subset.trans hDhV hVDg : _) hy
  -- All that is left is a simple calculation
  apply const_ext
  

Proof state:
case right.h
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
h : R
hxDh : ↑x ∈ (fun r => ↑(PrimeSpectrum.basicOpen r)) h
hDhV : PrimeSpectrum.basicOpen h ≤ V
n : ℕ
c : R
hc : c * g = h ^ (n + 1)
basic_opens_eq : PrimeSpectrum.basicOpen (h ^ (n + 1)) = PrimeSpectrum.basicOpen h
i_basic_open : PrimeSpectrum.basicOpen (h ^ (n + 1)) ⟶ V
⊢ f * c * g = f * h ^ (n + 1)

Next tactic:
rw [mul_assoc f c g, hc]
theorem normalize_finite_fraction_representation (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) {ι : Type*} (t : Finset ι) (a h : ι → R)
    (iDh : ∀ i : ι, PrimeSpectrum.basicOpen (h i) ⟶ U)
    (h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i))
    (hs :
      ∀ i : ι,
        (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun y hy => hy) =
          (structureSheaf R).1.map (iDh i).op s) :
    ∃ (a' h' : ι → R) (iDh' : ∀ i : ι, PrimeSpectrum.basicOpen (h' i) ⟶ U),
      (U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i)) ∧
        (∀ (i) (_ : i ∈ t) (j) (_ : j ∈ t), a' i * h' j = h' i * a' j) ∧
          ∀ i ∈ t,
            (structureSheaf R).1.map (iDh' i).op s =
              const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun y hy => hy := by
  -- First we show that the fractions `(a i * h j) / (h i * h j)` and `(h i * a j) / (h i * h j)`
  -- coincide in the localization of `R` at `h i * h j`
  

Proof state:
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
ι : Type u_1
t : Finset ι
a h : ι → R
iDh : (i : ι) → PrimeSpectrum.basicOpen (h i) ⟶ U
h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i)
hs :
  ∀ (i : ι),
    const R (a i) (h i) (PrimeSpectrum.basicOpen (h i))
        (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h i), y ∈ PrimeSpectrum.basicOpen (h i)) =
      ((structureSheaf R).val.map (iDh i).op) s
⊢ ∃ a' h' iDh',
    U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i) ∧
      (∀ i ∈ t, ∀ j ∈ t, a' i * h' j = h' i * a' j) ∧
        ∀ i ∈ t,
          ((structureSheaf R).val.map (iDh' i).op) s =
            const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i))
              (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h' i), y ∈ PrimeSpectrum.basicOpen (h' i))

Next tactic:
have fractions_eq :
    ∀ i j : ι,
      IsLocalization.mk' (Localization.Away (h i * h j))
        (a i * h j) ⟨h i * h j, Submonoid.mem_powers _⟩ =
      IsLocalization.mk' _ (h i * a j) ⟨h i * h j, Submonoid.mem_powers _⟩ := by
    intro i j
    let D := PrimeSpectrum.basicOpen (h i * h j)
    let iDi : D ⟶ PrimeSpectrum.basicOpen (h i) := homOfLE (PrimeSpectrum.basicOpen_mul_le_left _ _)
    let iDj : D ⟶ PrimeSpectrum.basicOpen (h j) :=
      homOfLE (PrimeSpectrum.basicOpen_mul_le_right _ _)
    -- Crucially, we need injectivity of `toBasicOpen`
    apply toBasicOpen_injective R (h i * h j)
    rw [toBasicOpen_mk', toBasicOpen_mk']
    simp only []
    -- Here, both sides of the equation are equal to a restriction of `s`
    trans
    convert congr_arg ((structureSheaf R).1.map iDj.op) (hs j).symm using 1
    convert congr_arg ((structureSheaf R).1.map iDi.op) (hs i) using 1; swap
    all_goals rw [res_const]; apply const_ext; ring
    -- The remaining two goals were generated during the rewrite of `res_const`
    -- These can be solved immediately
    exacts [PrimeSpectrum.basicOpen_mul_le_right _ _, PrimeSpectrum.basicOpen_mul_le_left _ _]
theorem normalize_finite_fraction_representation (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) {ι : Type*} (t : Finset ι) (a h : ι → R)
    (iDh : ∀ i : ι, PrimeSpectrum.basicOpen (h i) ⟶ U)
    (h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i))
    (hs :
      ∀ i : ι,
        (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun y hy => hy) =
          (structureSheaf R).1.map (iDh i).op s) :
    ∃ (a' h' : ι → R) (iDh' : ∀ i : ι, PrimeSpectrum.basicOpen (h' i) ⟶ U),
      (U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i)) ∧
        (∀ (i) (_ : i ∈ t) (j) (_ : j ∈ t), a' i * h' j = h' i * a' j) ∧
          ∀ i ∈ t,
            (structureSheaf R).1.map (iDh' i).op s =
              const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun y hy => hy := by
  -- First we show that the fractions `(a i * h j) / (h i * h j)` and `(h i * a j) / (h i * h j)`
  -- coincide in the localization of `R` at `h i * h j`
  have fractions_eq :
    ∀ i j : ι,
      IsLocalization.mk' (Localization.Away (h i * h j))
        (a i * h j) ⟨h i * h j, Submonoid.mem_powers _⟩ =
      IsLocalization.mk' _ (h i * a j) ⟨h i * h j, Submonoid.mem_powers _⟩ := by
    

Proof state:
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
ι : Type u_1
t : Finset ι
a h : ι → R
iDh : (i : ι) → PrimeSpectrum.basicOpen (h i) ⟶ U
h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i)
hs :
  ∀ (i : ι),
    const R (a i) (h i) (PrimeSpectrum.basicOpen (h i))
        (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h i), y ∈ PrimeSpectrum.basicOpen (h i)) =
      ((structureSheaf R).val.map (iDh i).op) s
⊢ ∀ (i j : ι),
    IsLocalization.mk' (Localization.Away (h i * h j)) (a i * h j)
        { val := h i * h j, property := (_ : h i * h j ∈ Submonoid.powers (h i * h j)) } =
      IsLocalization.mk' (Localization.Away (h i * h j)) (h i * a j)
        { val := h i * h j, property := (_ : h i * h j ∈ Submonoid.powers (h i * h j)) }

Next tactic:
intro i j
theorem normalize_finite_fraction_representation (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) {ι : Type*} (t : Finset ι) (a h : ι → R)
    (iDh : ∀ i : ι, PrimeSpectrum.basicOpen (h i) ⟶ U)
    (h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i))
    (hs :
      ∀ i : ι,
        (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun y hy => hy) =
          (structureSheaf R).1.map (iDh i).op s) :
    ∃ (a' h' : ι → R) (iDh' : ∀ i : ι, PrimeSpectrum.basicOpen (h' i) ⟶ U),
      (U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i)) ∧
        (∀ (i) (_ : i ∈ t) (j) (_ : j ∈ t), a' i * h' j = h' i * a' j) ∧
          ∀ i ∈ t,
            (structureSheaf R).1.map (iDh' i).op s =
              const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun y hy => hy := by
  -- First we show that the fractions `(a i * h j) / (h i * h j)` and `(h i * a j) / (h i * h j)`
  -- coincide in the localization of `R` at `h i * h j`
  have fractions_eq :
    ∀ i j : ι,
      IsLocalization.mk' (Localization.Away (h i * h j))
        (a i * h j) ⟨h i * h j, Submonoid.mem_powers _⟩ =
      IsLocalization.mk' _ (h i * a j) ⟨h i * h j, Submonoid.mem_powers _⟩ := by
    intro i j
    

Proof state:
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
ι : Type u_1
t : Finset ι
a h : ι → R
iDh : (i : ι) → PrimeSpectrum.basicOpen (h i) ⟶ U
h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i)
hs :
  ∀ (i : ι),
    const R (a i) (h i) (PrimeSpectrum.basicOpen (h i))
        (_ : ∀ y ∈ PrimeSpectrum.basicOpen (h i), y ∈ PrimeSpectrum.basicOpen (h i)) =
      ((structureSheaf R).val.map (iDh i).op) s
i j : ι
⊢ IsLocalization.mk' (Localization.Away (h i * h j)) (a i * h j)
      { val := h i * h j, property := (_ : h i * h j ∈ Submonoid.powers (h i * h j)) } =
    IsLocalization.mk' (Localization.Away (h i * h j)) (h i * a j)
      { val := h i * h j, property := (_ : h i * h j ∈ Submonoid.powers (h i * h j)) }

Next tactic:
let D := PrimeSpectrum.basicOpen (h i * h j)