Skip to content

Commit d64a465

Browse files
chrisflaverdOne
andcommitted
feat(AlgebraicGeometry): essential image of tilde is quasi-coherent modules (#40052)
We show that for a quasi-coherent module `M` over `Spec R`, the counit `M.fromTildeΓ` is an isomorphism, i.e., `M` is isomorphic to the tilde of the global sections of `M`. Co-authored-by: Andrew Yang <the.erd.one@gmail.com> Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>
1 parent b12383c commit d64a465

1 file changed

Lines changed: 260 additions & 0 deletions

File tree

Mathlib/AlgebraicGeometry/Modules/Tilde.lean

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public import Mathlib.Algebra.Category.ModuleCat.Localization
1010
public import Mathlib.Algebra.Category.ModuleCat.Sheaf.Quasicoherent
1111
public import Mathlib.Algebra.Module.LocalizedModule.Away
1212
public import Mathlib.AlgebraicGeometry.Modules.Sheaf
13+
public import Mathlib.Data.Fintype.Order
1314

1415
/-!
1516
@@ -595,6 +596,265 @@ lemma Scheme.Modules.exists_affineOpenCover_presentation {X : Scheme.{u}} (M : X
595596
exact SheafOfModules.Presentation.ofIsIso.{u, u, u} ((restrictFunctorComp _ _).app M).inv <|
596597
(presentationRestrict (hU' i).isoSpec.inv (pres i))
597598

599+
namespace QuasicoherentTilde
600+
601+
variable (M : (Spec R).Modules)
602+
603+
/-- Auxiliary structure used in the proof of `Scheme.Modules.isIso_fromTildeΓ_of_isQuasicoherent`.
604+
These are conditions d1) and d2) from [Theoreme 1.4.1, grothendieck-1971]. -/
605+
-- TODO: Generalise this to a general scheme, replacing `f : R` by sections over a suitable set.
606+
private structure Aux (V : (Spec R).Opens) where
607+
existence (f : R) (hf : basicOpen f ≤ V) (s : Γ(M, basicOpen f)) :
608+
∃ (n : ℕ) (t : Γ(M, V)), M.presheaf.map (homOfLE hf).op t = f ^ n • s
609+
uniqueness (f : R) (hf : basicOpen f ≤ V) (t : Γ(M, V)) :
610+
M.presheaf.map (.op <| homOfLE hf) t = (0 : Γ(M, basicOpen f)) →
611+
∃ (n : ℕ), f ^ n • t = 0
612+
613+
set_option backward.isDefEq.respectTransparency false in
614+
private lemma Aux.of_le {M : (Spec R).Modules} {V : (Spec R).Opens} (g : R) (hg : basicOpen g ≤ V)
615+
(hV : Aux M V) :
616+
Aux M (basicOpen g) where
617+
existence f hfg s := by
618+
obtain ⟨n, t, ht⟩ := hV.existence f (le_trans hfg hg) s
619+
use n, M.presheaf.map (homOfLE hg).op t
620+
simp [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, ht]
621+
uniqueness f hfg t ht := by
622+
obtain ⟨n, t', ht'⟩ := hV.existence g hg t
623+
obtain ⟨m, hm⟩ := hV.uniqueness _ (le_trans hfg hg) t' <| by
624+
rw [← homOfLE_comp hfg hg, op_comp, M.presheaf.map_comp_apply, ht', M.map_smul_Spec, ht]
625+
simp
626+
refine ⟨m, ((M.isSMulRegular_of_le_basicOpen le_rfl).pow n).right_eq_zero_of_smul ?_⟩
627+
simp [smul_comm, ← ht', ← M.map_smul_Spec, hm]
628+
629+
set_option backward.isDefEq.respectTransparency false in
630+
/-- This is the key computation for the proof of
631+
`Scheme.Modules.isQuasicoherent_iff_isIso_fromTildeΓ`.
632+
[Lemme 1.4.1.1][grothendieck-1971] -/
633+
private lemma Aux.of_eq_iSup_basicOpen {M : (Spec R).Modules} (V : (Spec R).Opens)
634+
{ι : Type*} [Finite ι] (g : ι → R) (hg : V = ⨆ i, basicOpen (g i))
635+
(h₁ : ∀ (i : ι), Aux M (basicOpen (g i))) :
636+
Aux M V := by
637+
have h₂ (i j : ι) : Aux M (basicOpen (g i * g j)) :=
638+
.of_le _ (basicOpen_mul_le_left _ _) (h₁ i)
639+
have hgle (i : ι) : basicOpen (g i) ≤ V := by rw [hg]; exact le_iSup_of_le _ le_rfl
640+
have hug (i : ι) (m : ℕ) :
641+
IsUnit (algebraMap R (Module.End R Γ(M, basicOpen (g i))) (g i ^ m)) := by
642+
rw [map_pow]
643+
exact (Scheme.Modules.isUnit_algebraMap_end_of_le_basicOpen (g i) le_rfl).pow m
644+
-- We show existence and uniqueness separately.
645+
refine ⟨fun f hf s ↦ ?_, fun f hf t hs ↦ ?_⟩
646+
· have hfgi (i : ι) : basicOpen (f * g i) ≤ basicOpen (g i) := basicOpen_mul_le_right f (g i)
647+
let s' (i : ι) : Γ(M, basicOpen (f * g i)) :=
648+
M.presheaf.map (homOfLE <| basicOpen_mul_le_left f (g i)).op s
649+
/- By `h₁`, up to a factor of `f ^ N`, the restrictions of `s` to `D(f) ∩ D(gᵢ)` lift
650+
to sections `tᵢ` over `D(gᵢ)`. -/
651+
obtain ⟨N, t, ht⟩ : ∃ (N : ℕ) (t : ∀ i, Γ(M, basicOpen (g i))),
652+
∀ i, f ^ N • s' i = M.presheaf.map (homOfLE (basicOpen_mul_le_right f (g i))).op (t i) := by
653+
have (i : ι) : ∃ (n : ℕ) (t : Γ(M, basicOpen (g i))),
654+
f ^ n • s' i = M.presheaf.map (homOfLE (hfgi i)).op t := by
655+
obtain ⟨n, t', ht'⟩ := (h₁ i).existence (f * g i) (hfgi i) (s' i)
656+
rw [mul_pow, mul_smul, smul_comm] at ht'
657+
obtain ⟨ψ, hψ⟩ := IsUnit.exists_right_inv (hug i n)
658+
use n, ψ t'
659+
apply (M.isSMulRegular_of_le_basicOpen (basicOpen_mul_le_right f (g i))).pow n
660+
dsimp
661+
rw [← ht', ← Scheme.Modules.map_smul_Spec]
662+
congr 1
663+
exact congr($hψ t').symm
664+
choose n t' ht' using this
665+
have (i : ι) : n i ≤ ⨆ i, n i := le_ciSup (Finite.bddAbove_range _) _
666+
have hN (i : ι) : ⨆ i, n i = ((⨆ i, n i) - n i) + n i := by grind
667+
refine ⟨⨆ i, n i, fun i ↦ f ^ ((⨆ i, n i) - n i) • t' i, fun i ↦ ?_⟩
668+
conv_lhs => rw [hN i]
669+
rw [pow_add, mul_smul, ht', M.map_smul_Spec]
670+
/- By `h₂`, up to a factor of `f ^ K`, the restrictions of `tᵢ` and `tⱼ` to
671+
to `D(gᵢ) ∩ D(gⱼ)` agree. -/
672+
obtain ⟨K, hK⟩ : ∃ (K : ℕ), ∀ (i j : ι),
673+
M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (f ^ K • t i) =
674+
M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (f ^ K • t j) := by
675+
have (i j : ι) : ∃ (m : ℕ),
676+
M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (f ^ m • t i) =
677+
M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (f ^ m • t j) := by
678+
have := (h₂ i j).uniqueness (f * (g i * g j)) (basicOpen_mul_le_right _ _)
679+
(M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (t i) -
680+
M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (t j)) ?_
681+
· obtain ⟨m, hm⟩ := this
682+
use m
683+
apply (M.isSMulRegular_of_le_basicOpen le_rfl).pow m
684+
simpa [M.map_smul_Spec _ (f ^ m), ← mul_smul, ← mul_smul, ← mul_pow, ← mul_comm f,
685+
smul_sub, sub_eq_zero] using hm
686+
· have hfgigi : basicOpen (f * (g i * g j)) ≤ basicOpen (f * g i) := by
687+
rw [← mul_assoc]
688+
exact basicOpen_mul_le_left _ _
689+
have hfgigj : basicOpen (f * (g i * g j)) ≤ basicOpen (f * g j) := by
690+
rw [mul_comm (g i) (g j), ← mul_assoc]
691+
exact basicOpen_mul_le_left _ _
692+
rw [map_sub, ← M.presheaf.map_comp_apply, ← op_comp, ← M.presheaf.map_comp_apply,
693+
← op_comp, homOfLE_comp, homOfLE_comp, ← homOfLE_comp hfgigi (hfgi i),
694+
← homOfLE_comp hfgigj (hfgi j), op_comp, M.presheaf.map_comp_apply, ← ht i,
695+
M.map_smul_Spec, ← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, op_comp,
696+
M.presheaf.map_comp_apply, ← ht j, M.map_smul_Spec, ← M.presheaf.map_comp_apply,
697+
← op_comp, homOfLE_comp]
698+
simp
699+
choose m hm using this
700+
let K := ⨆ i, ⨆ j, m i j
701+
refine ⟨K, fun i j ↦ ?_⟩
702+
have : m i j ≤ K :=
703+
le_ciSup_of_le (Finite.bddAbove_range _) i (le_ciSup (Finite.bddAbove_range _) _)
704+
have : K = (K - m i j) + m i j := by lia
705+
rw [this, pow_add, mul_smul, mul_smul, M.map_smul_Spec, M.map_smul_Spec _ (f ^ (K - m i j)),
706+
hm i j]
707+
-- So up to a factor of `f ^ (N + K)`, the `tᵢ` glue.
708+
refine ⟨N + K, ?_⟩
709+
have := TopCat.Sheaf.existsUnique_gluing' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (g i)) V
710+
(fun i ↦ homOfLE (by rw [hg]; exact le_iSup_of_le _ le_rfl)) (by simp [hg])
711+
(fun i ↦ f ^ K • t i) ?_
712+
· obtain ⟨a, ha, -⟩ := this
713+
use a
714+
refine TopCat.Sheaf.eq_of_locally_eq' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (f * g i)) _
715+
(fun i ↦ homOfLE (basicOpen_mul_le_left f (g i))) ?_ _ _ ?_
716+
· rw [left_eq_inf.mpr hf, hg, inf_iSup_eq]
717+
simp_rw [basicOpen_mul]
718+
exact le_rfl
719+
· intro i
720+
rw [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp,
721+
← homOfLE_comp (basicOpen_mul_le_right _ _) (hgle i), op_comp, M.presheaf.map_comp_apply,
722+
M.map_smul_Spec, ha, M.map_smul_Spec, pow_add, mul_smul, smul_comm, ht i]
723+
· intro i j
724+
have : Function.Injective (M.presheaf.map (eqToHom <| (basicOpen_mul (g i) (g j))).op) :=
725+
ConcreteCategory.injective_of_mono_of_preservesPullback _
726+
apply this
727+
dsimp [Opens.infLELeft, Opens.infLERight]
728+
simp_rw [← M.presheaf.map_comp_apply, ← op_comp, eqToHom_comp_homOfLE]
729+
exact hK i j
730+
· have (i : ι) : ∃ (n : ℕ), M.presheaf.map (homOfLE (hgle i)).op (f ^ n • t) = 0 := by
731+
have := (h₁ i).uniqueness (f * g i) (basicOpen_mul_le_right f (g i))
732+
(M.presheaf.map (homOfLE (hgle i)).op t) ?_
733+
· obtain ⟨n, hn⟩ := this
734+
use n
735+
rw [mul_pow, mul_comm, mul_smul, ← Scheme.Modules.map_smul_Spec] at hn
736+
exact ((M.isSMulRegular_of_le_basicOpen le_rfl).pow n).right_eq_zero_of_smul hn
737+
· rw [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp,
738+
← homOfLE_comp ((basicOpen_mul_le_left f (g i))) hf, op_comp, M.presheaf.map_comp_apply]
739+
simp [hs]
740+
choose n hn using this
741+
use ⨆ i, n i
742+
apply TopCat.Sheaf.eq_of_locally_eq' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (g i)) _
743+
(fun i ↦ homOfLE (by rw [hg]; exact le_iSup_of_le _ le_rfl))
744+
· simp [hg]
745+
· intro i
746+
have : n i ≤ ⨆ i, n i := le_ciSup (Finite.bddAbove_range _) _
747+
have : ⨆ i, n i = ((⨆ i, n i) - n i) + n i := by lia
748+
rw [this, pow_add, mul_smul, Scheme.Modules.map_smul_Spec, hn i]
749+
simp
750+
751+
private lemma isLocalizing_iff_aux (M : (Spec R).Modules) :
752+
IsLocalizing (modulesSpecToSheaf.obj M) ↔ Aux M ⊤ := by
753+
let φ (f : R) := ((modulesSpecToSheaf.obj M).obj.map (basicOpen f).leTop.op).hom
754+
refine ⟨fun h ↦ ?_, fun h f ↦ IsLocalizedModule.Away.mk_of_addCommGroup ?_ ?_ ?_⟩
755+
· have hf (f : R) : IsLocalizedModule.Away f (φ f) := h f
756+
refine ⟨fun f hle s ↦ ?_, fun f hle s hs ↦ ?_⟩
757+
· obtain ⟨n, y, hy⟩ := (hf f).surj _ _ s
758+
use n, y, hy.symm
759+
· obtain ⟨⟨_, n, rfl⟩, hn⟩ := (IsLocalizedModule.eq_zero_iff (.powers f) (φ f)).mp hs
760+
use n, hn
761+
· exact Scheme.Modules.isUnit_algebraMap_end_of_le_basicOpen f le_rfl
762+
· intro x
763+
obtain ⟨n, t, ht⟩ := h.existence _ _ x
764+
use n, t, ht.symm
765+
· intro x hx
766+
obtain ⟨n, hn⟩ := h.uniqueness _ _ _ hx
767+
use n, hn
768+
769+
set_option backward.defeqAttrib.useBackward true in
770+
set_option backward.isDefEq.respectTransparency false in
771+
private lemma aux_basicOpen_of_aux_restrict (M : (Spec R).Modules) (g : R)
772+
(h : Aux (M.restrict <|
773+
Spec.map <| CommRingCat.ofHom <| algebraMap R <| Localization.Away g) ⊤) :
774+
Aux M (basicOpen g) := by
775+
let a : R ⟶ CommRingCat.of (Localization.Away g) :=
776+
CommRingCat.ofHom <| algebraMap R _
777+
set ψ : Spec (.of <| Localization.Away g) ⟶ Spec (.of R) := Spec.map a
778+
set M' : (Spec (.of <| Localization.Away g)).Modules := M.restrict ψ
779+
have heq (f : R) (hf : basicOpen f ≤ basicOpen g) :
780+
basicOpen f = ψ ''ᵁ basicOpen (a f) := by
781+
rw [← SpecMap_preimage_basicOpen, Scheme.Hom.image_preimage_eq_opensRange_inf]
782+
simp [a, ψ, hf]
783+
let iso : Γ(M.restrict ψ, ⊤) ≅ Γ(M, basicOpen g) :=
784+
M.restrictAppIso _ _ ≪≫ M.presheaf.mapIso (eqToIso <| by simp [ψ, a]).op
785+
let e (f : R) (hf : basicOpen f ≤ basicOpen g) : Γ(M', basicOpen (a f)) ≅ Γ(M, basicOpen f) :=
786+
M.restrictAppIso ψ (basicOpen (a f)) ≪≫ M.presheaf.mapIso (eqToIso <| heq f hf).op
787+
refine ⟨fun f hf s ↦ ?_, fun f hf t ht ↦ ?_⟩
788+
· obtain ⟨n, t, ht⟩ := h.existence (a f) le_top ((e _ hf).inv s)
789+
use n, iso.hom t
790+
have := congr((e _ hf).hom $ht)
791+
dsimp [M'] at this
792+
rw [← ConcreteCategory.comp_apply] at this
793+
simp only [homOfLE_leOfHom, Iso.trans_hom, Functor.mapIso_hom, Iso.op_hom, eqToIso.hom,
794+
eqToHom_op, Iso.trans_inv, Functor.mapIso_inv, Iso.op_inv, eqToIso.inv, e, iso] at this ⊢
795+
simp only [homOfLE_leOfHom, Scheme.Modules.map_restrictAppIso_hom_assoc, AddCommGrpCat.hom_comp,
796+
AddMonoidHom.coe_comp, Function.comp_apply, ← map_pow, ψ] at this
797+
rw [Scheme.Modules.restrictAppIso_smul_Spec] at this
798+
simpa [← Functor.map_comp_apply, eqToHom_comp_homOfLE_op, homOfLE_op_comp_eqToHom] using this
799+
· obtain ⟨n, hn⟩ := h.uniqueness (a f) le_top (iso.inv t) <| by
800+
simpa [M', iso, ← M.presheaf.map_comp_apply, homOfLE_op_comp_eqToHom, e] using
801+
congr((e _ hf).inv $ht)
802+
use n
803+
have := congr(iso.hom $hn)
804+
dsimp [iso, ψ] at this
805+
rw [eqToHom_op, map_zero, ← map_pow, Scheme.Modules.restrictAppIso_smul_Spec,
806+
M.map_smul_Spec, Iso.inv_hom_id_apply] at this
807+
simpa using this
808+
809+
end QuasicoherentTilde
810+
811+
open QuasicoherentTilde in
812+
set_option backward.defeqAttrib.useBackward true in
813+
set_option backward.isDefEq.respectTransparency false in
814+
/-- If `M` is a quasi-coherent `𝒪_{Spec R}` module, it is isomorphic to `Γ(M)^~`. -/
815+
instance Scheme.Modules.isIso_fromTildeΓ_of_isQuasicoherent (M : (Spec R).Modules)
816+
[M.IsQuasicoherent] : IsIso M.fromTildeΓ := by
817+
rw [isIso_fromTildeΓ_iff_isLocalizing, isLocalizing_iff_aux]
818+
obtain ⟨ι, U, pres, hU, hU'⟩ := M.exists_isOpenCover_presentation
819+
obtain ⟨s, hs⟩ := hU.exists_finite_of_compactSpace
820+
choose κ hκ a ha using fun i : s ↦
821+
PrimeSpectrum.isBasis_basic_opens.exists_iSup_eq_of_isCompact (U i) (hU' i).isCompact
822+
refine Aux.of_eq_iSup_basicOpen _ (fun i : Sigma κ ↦ a _ i.2) ?_ ?_
823+
· rw [IsOpenCover] at hs
824+
rw [eq_comm, iSup_sigma, ← hs]
825+
exact iSup_congr fun i ↦ (ha i).symm
826+
· intro i
827+
let t := (Spec R).homOfLE (U := PrimeSpectrum.basicOpen (a _ i.2)) (V := U i.1)
828+
(by rw [ha]; exact le_iSup_of_le _ le_rfl)
829+
let iso : restrictFunctor (U i.1).ι ⋙ restrictFunctor ((basicOpenIsoSpecAway _).inv ≫ t) ≅
830+
restrictFunctor (Spec.map (CommRingCat.ofHom <| algebraMap _ _)) :=
831+
(restrictFunctorComp _ _).symm ≪≫
832+
restrictFunctorCongr (by simp [t, basicOpenIsoSpecAway])
833+
let pres := SheafOfModules.Presentation.ofIsIso.{u, u, u} (iso.app M).hom <|
834+
presentationRestrict ((basicOpenIsoSpecAway _).inv ≫ t) (pres i.1)
835+
have : IsIso _ := isIso_fromTildeΓ_of_presentation (M.restrict _) pres
836+
rw [isIso_fromTildeΓ_iff_isLocalizing, isLocalizing_iff_aux] at this
837+
exact aux_basicOpen_of_aux_restrict _ _ this
838+
839+
set_option backward.isDefEq.respectTransparency false in
840+
/-- An `𝒪_{Spec R}` module `M` is quasicoherent if and only if it is isomorphic to `Γ(M)^~`. -/
841+
theorem isQuasicoherent_iff_isIso_fromTildeΓ (M : (Spec R).Modules) :
842+
M.IsQuasicoherent ↔ IsIso M.fromTildeΓ := by
843+
refine ⟨fun h ↦ inferInstance, fun h ↦ ?_⟩
844+
exact (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).prop_of_iso
845+
(asIso <| M.fromTildeΓ) inferInstance
846+
847+
set_option backward.defeqAttrib.useBackward true in
848+
set_option backward.isDefEq.respectTransparency false in
849+
lemma essImage_tilde : (tilde.functor R).essImage =
850+
SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf := by
851+
refine le_antisymm ?_ ?_
852+
· intro M ⟨N, ⟨e⟩⟩
853+
exact (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).prop_of_iso e
854+
(by dsimp; infer_instance)
855+
· intro M (h : M.IsQuasicoherent)
856+
exact ⟨((modulesSpecToSheaf.obj M).presheaf.obj (.op ⊤)), ⟨asIso <| M.fromTildeΓ⟩⟩
857+
598858
end IsQuasicoherent
599859

600860
end AlgebraicGeometry

0 commit comments

Comments
 (0)