The most important technique in scheme theory is certainly the reduction to
affine situations and commutative algebra. We first explain a few of the
basic tools for this and then give an example how these can be used
to prove a standard fact.
The goal of this section is to define flat morphisms of schemes and to prove
that a morphism is flat if it is stalkwise flat.
Here is a definition of a flat morphism of schemes: A morphism of schemes f : X \to Y
is flat if for every affine open U \subseteq Y and V \subseteq f^{-1}(U), the
induced ring homomorphism \mathcal{O}_Y(U) \to \mathcal{O}_X(V) is flat.
To connect flat morphisms of schemes to ring homomorphism, we need to provide
an instance of HasRingHomProperty:
instance:HasRingHomProperty@FlatRingHom.FlatwhereisLocal_ringHomProperty:=RingHom.Flat.propertyIsLocaleq_affineLocally':=R:TypeS:TypeT:Typeinst✝¹:CommRingRinst✝:CommRingSP:MorphismPropertySchemeX:SchemeY:Scheme⊢ @Flat=affineLocallyfun{RS}[CommRingR][CommRingS]=>RingHom.FlatR:TypeS:TypeT:Typeinst✝¹:CommRingRinst✝:CommRingSP:MorphismPropertySchemeX✝:SchemeY✝:SchemeX:SchemeY:Schemef:X⟶Y⊢ Flatf↔affineLocally(fun{RS}[CommRingR][CommRingS]=>RingHom.Flat)fR:TypeS:TypeT:Typeinst✝¹:CommRingRinst✝:CommRingSP:MorphismPropertySchemeX✝:SchemeY✝:SchemeX:SchemeY:Schemef:X⟶Y⊢ (∀(U:Y.Opens)(V:X.Opens)(e:V≤f⁻¹ᵁU),IsAffineOpenU→IsAffineOpenV→(CommRingCat.Hom.hom(Scheme.Hom.appLEfUVe)).Flat)↔∀(U:↑Y.affineOpens)(V:↑X.affineOpens)(e:↑V≤f⁻¹ᵁ↑U),(CommRingCat.Hom.hom(Scheme.Hom.appLEf(↑U)(↑V)e)).Flatsimponly[Scheme.affineOpens,`Set.mem_setOf_eq` has been deprecated: Use `Set.mem_ofPred_eq` insteadHint: Replace the deprecated name:S̵e̵t̵.̵m̵e̵m̵_̵s̵e̵t̵O̵f̵_̵e̵q̵S̲e̲t̲.̲m̲e̲m̲_̲o̲f̲P̲r̲e̲d̲_̲e̲q̲Set.mem_setOf_eq,Subtype.forall]R:TypeS:TypeT:Typeinst✝¹:CommRingRinst✝:CommRingSP:MorphismPropertySchemeX✝:SchemeY✝:SchemeX:SchemeY:Schemef:X⟶Y⊢ (∀(U:Y.Opens)(V:X.Opens)(e:V≤f⁻¹ᵁU),IsAffineOpenU→IsAffineOpenV→(CommRingCat.Hom.hom(Scheme.Hom.appLEfUVe)).Flat)↔∀(a:Y.Opens)(b:IsAffineOpena)(a_1:X.Opens)(b_1:IsAffineOpena_1)(e:a_1≤f⁻¹ᵁa),(CommRingCat.Hom.hom(Scheme.Hom.appLEfaa_1e)).FlatgrindAll goals completed! 🐙
After this, we get some meta properties for free, for example that flat is local
on the target:
-- This is the same defeq issue with `MorphismProperty`,-- as the `set_option` above.set_optionbackward.isDefEq.respectTransparency.typesfalseinexample:IsZariskiLocalAtTarget@Flat:=inferInstance
With these preparations, we can now prove that a morphism that is stalkwise flat is flat:
theoremflat_of_flat_stalkMap(f:X⟶Y)(H:∀x,(f.stalkMapx).hom.Flat):Flatf:=byX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat⊢ Flatf-- We may assume `Y` is of the form `Spec R`wloghY:∃R,Y=SpecRgeneralizingXYfisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecR⊢ FlatfX✝:SchemeY✝:SchemeX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).FlathY:∃R,Y=SpecR⊢ Flatf·isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecR⊢ Flatfrw[IsZariskiLocalAtTarget.iff_of_openCover(P:=@Flat)Y.affineCoverisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecR⊢ ∀(i:Y.affineCover.toPreZeroHypercover.1),Flat(Scheme.Cover.pullbackHomY.affineCoverfi)]isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecR⊢ ∀(i:Y.affineCover.toPreZeroHypercover.1),Flat(Scheme.Cover.pullbackHomY.affineCoverfi)introiisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1⊢ Flat(Scheme.Cover.pullbackHomY.affineCoverfi)refinethis_?_⟨_,rfl⟩isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1⊢ ∀(x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Scheme.Cover.pullbackHomY.affineCoverfi)x)).FlatintroxisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ (CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Scheme.Cover.pullbackHomY.affineCoverfi)x)).Flatrw[RingHom.Flat.respectsIso.arrow_mk_iso_iffisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ (CommRingCat.Hom.hom?m.57).FlatisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ Arrow.mk(Scheme.Hom.stalkMap(Scheme.Cover.pullbackHomY.affineCoverfi)x)≅Arrow.mk?m.57X:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ CommRingCatX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ CommRingCatX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ ?m.54⟶?m.55]isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ (CommRingCat.Hom.hom?m.57).FlatisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ Arrow.mk(Scheme.Hom.stalkMap(Scheme.Cover.pullbackHomY.affineCoverfi)x)≅Arrow.mk?m.57X:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ CommRingCatX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ CommRingCatX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ ?m.54⟶?m.55·isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ (CommRingCat.Hom.hom?m.57).FlatapplyHisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ ↥XbdsimpatxisFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥(pullbackf(Y.affineCover.fi))⊢ ↥Xexactpullback.fstf_xAll goals completed! 🐙·isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ Arrow.mk(Scheme.Hom.stalkMap(Scheme.Cover.pullbackHomY.affineCoverfi)x)≅Arrow.mk(Scheme.Hom.stalkMapf((pullback.fstf(Y.affineCover.fi))x))dsimp[Scheme.Cover.pullbackHom]isFalseX:SchemeY:Schemef:X⟶YH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{XY:Scheme}(f:X⟶Y),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃R,Y=SpecR)→FlatfhY:¬∃R,Y=SpecRi:Y.affineCover.toPreZeroHypercover.1x:↥((Precoverage.ZeroHypercover.pullback₁fY.affineCover).Xi)⊢ Arrow.mk(Scheme.Hom.stalkMap(pullback.sndf(Y.affineCover.fi))x)≅Arrow.mk(Scheme.Hom.stalkMapf((pullback.fstf(Y.affineCover.fi))x))applyIso.symm<|Scheme.stalkMapIsoOfIsPullback(IsPullback.of_hasPullback_(Y.affineCover.fi))_All goals completed! 🐙-- Replace `Y` by `Spec R` in the context and goal.obtain⟨R,rfl⟩:=hYX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat⊢ FlatfwloghX:∃S,X=SpecSgeneralizingXfisFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecS⊢ FlatfX✝:SchemeY:SchemeR:CommRingCatX:Schemef:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).FlathX:∃S,X=SpecS⊢ Flatf·isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecS⊢ Flatfrw[IsZariskiLocalAtSource.iff_of_openCover(P:=@Flat)X.affineCoverisFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecS⊢ ∀(i:X.affineCover.I₀),Flat(X.affineCover.fi≫f)]isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecS⊢ ∀(i:X.affineCover.I₀),Flat(X.affineCover.fi≫f)introiisFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀⊢ Flat(X.affineCover.fi≫f)refinethis_?_⟨_,rfl⟩isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀⊢ ∀(x:↥(X.affineCover.Xi)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(X.affineCover.fi≫f)x)).FlatintroxisFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀x:↥(X.affineCover.Xi)⊢ (CommRingCat.Hom.hom(Scheme.Hom.stalkMap(X.affineCover.fi≫f)x)).Flatrw[Scheme.Hom.stalkMap_comp,isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀x:↥(X.affineCover.Xi)⊢ (CommRingCat.Hom.hom(Scheme.Hom.stalkMapf((X.affineCover.fi)x)≫Scheme.Hom.stalkMap(X.affineCover.fi)x)).FlatCommRingCat.hom_comp,isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀x:↥(X.affineCover.Xi)⊢ ((CommRingCat.Hom.hom(Scheme.Hom.stalkMap(X.affineCover.fi)x)).comp(CommRingCat.Hom.hom(Scheme.Hom.stalkMapf((X.affineCover.fi)x)))).FlatRingHom.Flat.respectsIso.cancel_right_isIsoisFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀x:↥(X.affineCover.Xi)⊢ (CommRingCat.Hom.hom(Scheme.Hom.stalkMapf((X.affineCover.fi)x))).Flat]isFalseX✝:SchemeY:SchemeX:SchemeR:CommRingCatf:X⟶SpecRH:∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flatthis:∀{X:Scheme}(f:X⟶SpecR),(∀(x:↥X),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat)→(∃S,X=SpecS)→FlatfhX:¬∃S,X=SpecSi:X.affineCover.I₀x:↥(X.affineCover.Xi)⊢ (CommRingCat.Hom.hom(Scheme.Hom.stalkMapf((X.affineCover.fi)x))).FlatapplyHAll goals completed! 🐙-- Replace `X` by `Spec S` in the context and goal.obtain⟨S,rfl⟩:=hXX:SchemeY:SchemeR:CommRingCatS:CommRingCatf:SpecS⟶SpecRH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMapfx)).Flat⊢ Flatf-- Replace `f` by `Spec.map φ` in the context and goal.obtain⟨φ,rfl⟩:=Spec.map_surjectivefX:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ)x)).Flat⊢ Flat(Spec.mapφ)/- Since we have shown before that flat morphisms of
schemes correspond to flat ring homomorphisms, we can now
turn the goal into commutative algebra. -/rw[HasRingHomProperty.Spec_iff(P:=@Flat)X:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ)x)).Flat⊢ (CommRingCat.Hom.homφ).Flat]X:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ)x)).Flat⊢ (CommRingCat.Hom.homφ).Flat/- Finally, use the fact from commutative algebra, that
flatness of ring maps can be checked on stalks. -/applyRingHom.Flat.ofLocalizationPrimeX:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ)x)).Flat⊢ ∀(J:Ideal↑S)(x:J.IsPrime),(fun{RS}[CommRingR][CommRingS]=>RingHom.Flat)(Localization.localRingHom(Ideal.comap(CommRingCat.Hom.homφ)J)J(CommRingCat.Hom.homφ)⋯)introPhPX:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SH:∀(x:↥(SpecS)),(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ)x)).FlatP:Ideal↑ShP:P.IsPrime⊢ (Localization.localRingHom(Ideal.comap(CommRingCat.Hom.homφ)P)P(CommRingCat.Hom.homφ)⋯).FlatspecializeH⟨P,hP⟩X:SchemeY:SchemeR:CommRingCatS:CommRingCatφ:R⟶SP:Ideal↑ShP:P.IsPrimeH:(CommRingCat.Hom.hom(Scheme.Hom.stalkMap(Spec.mapφ){asIdeal:=P,isPrime:=hP})).Flat⊢ (Localization.localRingHom(Ideal.comap(CommRingCat.Hom.homφ)P)P(CommRingCat.Hom.homφ)⋯).Flatrwa[RingHom.Flat.respectsIso.arrow_mk_iso_iff(Scheme.arrowStalkMapSpecIsoφ_)]atHAll goals completed! 🐙