Definitions/Def_EllipticCurve_FunctionFieldPullback.lean
Generic point and function-field pull-backs for elliptic curves
Throughout, W is a Weierstrass curve over a field R and K an R-algebra which is a field; E = W_{/K} denotes the base-changed affine curve, K[E] its Mathlib coordinate ring K[X][Y]/(\,W\text{-polynomial}) and L = K(E) its function field (the fraction field of K[E]). A first group of results concerns K[E] as a K[X]-algebra: it is finite and integral over K[X], every nonzero prime ideal of it is maximal, and for K algebraically closed every nonzero prime equals \mathrm{XYIdeal}(a, C\,b) = (X-a,\;Y-b) for some solution (a,b) of the affine equation, these ideals being maximal. Point.xc, Point.yc read off the coordinates of an affine point (value 0 at the point at infinity). The generic point is the L-point \gamma whose coordinates genericX, genericY are the images in L of the classes of X and Y; that it satisfies the equation, hence is nonsingular when W is elliptic, is proved here. For a nonzero point Q \in E(L), pointHom Q is the K-algebra map K[E] \to L determined by X \mapsto x(Q), Y \mapsto y(Q); it is injective whenever K is algebraically closed and Q is not the base change of a K-point, and pointPull Q is then its extension L \to L along the fraction field. Specialising Q gives transPull/transEquiv (pull-back along translation by a K-point S, i.e. the map sending \gamma to \gamma + S), negPull/negEquiv (pull-back along inversion), and mulPull W K n, defined from the point n\cdot\gamma when the predicate MulGood W K n holds — namely n\cdot\gamma \ne 0 and n\cdot\gamma is not the base change of any K-point — and as the identity otherwise. The expected identities are proved: additivity and injectivity of S \mapsto \tau_S^{*}, \iota^{*}\circ\iota^{*} = \mathrm{id}, [m]^{*}[n]^{*} = [nm]^{*}, and \tau_S^{*}\circ[n]^{*} = [n]^{*} when nS = 0. placeOf W K P packages (X-x(P),\,Y-y(P)) as a height-one prime of K[E]; it is injective, and surjective onto the height-one spectrum for K algebraically closed and W elliptic, with CoordinateRing.evalAt the evaluation homomorphism K[E] \to K at a solution of the equation. Finally, Valuation.Cong v a b is the relation v(a-b) < 1 — congruence modulo the valuation ideal, not an identity — shown stable under sums, products and powers of elements of valuation \le 1, under inversion and division by elements of valuation 1, and under two-variable polynomial evaluation; from it and a valuation-transfer lemma for a ring map between fraction fields of Dedekind domains, the module deduces that v_P(\mathrm{pointPull}\,Q\,(h)) \le e^{-k} whenever v_{P'}(h) \le e^{-k}, for points whose coordinates are congruent at P, and the corresponding statement for mulPull in terms of polynomials \Phi, \Psi, \omega, \psi expressing the coordinates of n\cdot\gamma and of n\cdot P as rational functions of the coordinates.
Relation to Mathlib
Mathlib supplies the affine Weierstrass curve, its coordinate ring with XClass, YClass, XYIdeal, the function field, the group of affine points and base change of points; the generic point, the homomorphisms pointHom/pointPull and their translation, inversion and multiplication-by-n specialisations, the map from points to the height-one spectrum, and the valuation congruence relation Valuation.Cong are the project's own.
Where it is used
The material sets up the action of translations, inversion and multiplication by n on the function field of an elliptic curve, together with the dictionary between affine points over an algebraically closed field and height-one places of the coordinate ring, and a valuation comparison between a point P and its multiple n\cdot P.
References
- J. H. Silverman, The Arithmetic of Elliptic Curves, Graduate Texts in Mathematics 106, Springer, 2nd ed., 2009
- J.-P. Serre, Local Fields, Graduate Texts in Mathematics 67, Springer, 1979
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 1,219 lines
- 138 declarations
- used in the statements of 10 theorems and imported by 11 proofs
- imports 0 definition modules
Source file: Definitions/Def_EllipticCurve_FunctionFieldPullback.lean
Imports
- only Mathlib
Imported by
Declarations
- instance
WeierstrassCurve.Affine.CoordinateRing.moduleFinite - instance
WeierstrassCurve.Affine.CoordinateRing.isIntegral - theorem
WeierstrassCurve.Affine.CoordinateRing.algebraMap_eq_mk_C - theorem
WeierstrassCurve.Affine.CoordinateRing.isMaximal_of_isPrime - theorem
WeierstrassCurve.Affine.CoordinateRing.exists_comap_eq_span - theorem
WeierstrassCurve.Affine.CoordinateRing.XClass_mem_of_comap_eq - theorem
WeierstrassCurve.Affine.CoordinateRing.mk_C_mem_iff - theorem
WeierstrassCurve.Affine.CoordinateRing.XYIdeal_isMaximal - theorem
WeierstrassCurve.Affine.CoordinateRing.algebraMap_quot_apply - theorem
WeierstrassCurve.Affine.CoordinateRing.algebraMap_quot_eq_comp_eval - theorem
WeierstrassCurve.Affine.CoordinateRing.exists_eq_XYIdeal - def
WeierstrassCurve.Affine.Point.xc - def
WeierstrassCurve.Affine.Point.yc - lemma
WeierstrassCurve.Affine.Point.xc_some - lemma
WeierstrassCurve.Affine.Point.yc_some - lemma
WeierstrassCurve.Affine.Point.nonsingular_xc_yc - lemma
WeierstrassCurve.Affine.Point.eq_some_xc_yc - instance
WeierstrassCurve.Affine.instDecidableEqFunctionField - def
WeierstrassCurve.Affine.genericX - def
WeierstrassCurve.Affine.genericY - theorem
WeierstrassCurve.Affine.evalEval_baseChange_polynomial - theorem
WeierstrassCurve.Affine.algebraMap_comp_of - theorem
WeierstrassCurve.Affine.generic_equation - theorem
WeierstrassCurve.Affine.generic_nonsingular - def
WeierstrassCurve.Affine.genericPoint - theorem
WeierstrassCurve.Affine.eval₂_polynomial_of_point - def
WeierstrassCurve.Affine.pointHom - theorem
WeierstrassCurve.Affine.pointHom_mk - theorem
WeierstrassCurve.Affine.pointHom_mk_C_C - theorem
WeierstrassCurve.Affine.pointHom_mk_C_X - theorem
WeierstrassCurve.Affine.pointHom_mk_Y - theorem
WeierstrassCurve.Affine.CoordinateRing.algHom_ext' - theorem
WeierstrassCurve.Affine.pointHom_genericPoint - theorem
WeierstrassCurve.Affine.Point.xc_map - theorem
WeierstrassCurve.Affine.Point.yc_map - theorem
WeierstrassCurve.Affine.pointHom_injective_of_ne_baseChange - def
WeierstrassCurve.Affine.pointPull - theorem
WeierstrassCurve.Affine.pointPull_algebraMap - theorem
WeierstrassCurve.Affine.map_pointPull_genericPoint - theorem
WeierstrassCurve.Affine.pointPull_comp_pointHom - theorem
WeierstrassCurve.Affine.pointHom_congr - theorem
WeierstrassCurve.Affine.pointPull_comp_algebraMap - theorem
WeierstrassCurve.Affine.FunctionField.algHom_ext - theorem
WeierstrassCurve.Affine.exists_eq_baseChange_of_isIntegral_xc - theorem
WeierstrassCurve.Affine.not_isIntegral_xc_of_ne_baseChange - theorem
WeierstrassCurve.Affine.genericPoint_ne_baseChange - theorem
WeierstrassCurve.Affine.genericPoint_add_baseChange_ne_zero - theorem
WeierstrassCurve.Affine.genericPoint_add_baseChange_ne_baseChange - theorem
WeierstrassCurve.Affine.transHom_injective - def
WeierstrassCurve.Affine.transPull - theorem
WeierstrassCurve.Affine.map_transPull_genericPoint - theorem
WeierstrassCurve.Affine.map_transPull_genericPoint_add - theorem
WeierstrassCurve.Affine.transPull_comp_algebraMap - theorem
WeierstrassCurve.Affine.transPull_comp_pointHom - theorem
WeierstrassCurve.Affine.transPull_comp_transHom - theorem
WeierstrassCurve.Affine.transPull_comp - theorem
WeierstrassCurve.Affine.transPull_zero - def
WeierstrassCurve.Affine.transEquiv - theorem
WeierstrassCurve.Affine.transEquiv_apply - theorem
WeierstrassCurve.Affine.coe_transEquiv - theorem
WeierstrassCurve.Affine.transEquiv_algebraMap - theorem
WeierstrassCurve.Affine.transEquiv_genericX - theorem
WeierstrassCurve.Affine.transEquiv_genericY - theorem
WeierstrassCurve.Affine.map_transEquiv_genericPoint - theorem
WeierstrassCurve.Affine.transEquiv_add - theorem
WeierstrassCurve.Affine.transEquiv_zero - theorem
WeierstrassCurve.Affine.transEquiv_injective - theorem
WeierstrassCurve.Affine.neg_genericPoint_ne_baseChange - theorem
WeierstrassCurve.Affine.negHom_injective - def
WeierstrassCurve.Affine.negPull - theorem
WeierstrassCurve.Affine.map_negPull_genericPoint - theorem
WeierstrassCurve.Affine.negPull_algebraMap - theorem
WeierstrassCurve.Affine.negPull_comp_algebraMap - theorem
WeierstrassCurve.Affine.negPull_comp_pointHom - theorem
WeierstrassCurve.Affine.negPull_comp_negPull - def
WeierstrassCurve.Affine.negEquiv - theorem
WeierstrassCurve.Affine.coe_negEquiv - theorem
WeierstrassCurve.Affine.negEquiv_apply - theorem
WeierstrassCurve.Affine.map_negEquiv_genericPoint - theorem
WeierstrassCurve.Affine.negEquiv_genericX - theorem
WeierstrassCurve.Affine.negEquiv_genericY - theorem
WeierstrassCurve.Affine.negEquiv_symm - def
WeierstrassCurve.Affine.MulGood - theorem
WeierstrassCurve.Affine.mulHom_injective - def
WeierstrassCurve.Affine.mulPull - theorem
WeierstrassCurve.Affine.mulPull_eq - theorem
WeierstrassCurve.Affine.mulPull_algebraMap - theorem
WeierstrassCurve.Affine.mulPull_comp_algebraMap - theorem
WeierstrassCurve.Affine.mulPull_genericX' - theorem
WeierstrassCurve.Affine.mulPull_genericY' - theorem
WeierstrassCurve.Affine.map_mulPull_genericPoint' - theorem
WeierstrassCurve.Affine.mulPull_comp_pointHom - theorem
WeierstrassCurve.Affine.transEquiv_mulPull' - theorem
WeierstrassCurve.Affine.mulPull_comp' - theorem
WeierstrassCurve.Affine.exists_point_xc_eq - theorem
WeierstrassCurve.Affine.infinite_point - theorem
WeierstrassCurve.Affine.map_negEquiv_zsmul_genericPoint - theorem
WeierstrassCurve.Affine.negEquiv_mulPull_genericX' - theorem
WeierstrassCurve.Affine.negEquiv_mulPull_genericY' - theorem
WeierstrassCurve.Affine.mulPull_injective - def
WeierstrassCurve.Affine.placeOf - theorem
WeierstrassCurve.Affine.placeOf_asIdeal - theorem
WeierstrassCurve.Affine.placeOf_surjective - def
WeierstrassCurve.Affine.CoordinateRing.evalAt - theorem
WeierstrassCurve.Affine.CoordinateRing.evalAt_mk - theorem
WeierstrassCurve.Affine.CoordinateRing.evalAt_XYIdeal - theorem
WeierstrassCurve.Affine.placeOf_injective - def
Valuation.Cong - theorem
Valuation.cong_iff - theorem
Valuation.Cong.refl - theorem
Valuation.Cong.rfl - theorem
Valuation.Cong.symm - theorem
Valuation.Cong.trans - theorem
Valuation.Cong.add - theorem
Valuation.Cong.neg - theorem
Valuation.Cong.sub - theorem
Valuation.Cong.le_one - theorem
Valuation.Cong.mul - theorem
Valuation.Cong.pow - theorem
Valuation.Cong.eq_of_eq_one - theorem
Valuation.Cong.lt_one_iff - theorem
Valuation.cong_zero_iff - theorem
Valuation.Cong.inv - theorem
Valuation.Cong.div - theorem
Valuation.Cong.eval₂ - theorem
Valuation.Cong.eval₂_eval₂ - theorem
IsDedekindDomain.HeightOneSpectrum.valuation_map_le_exp_neg_of_mem_pow - theorem
IsDedekindDomain.HeightOneSpectrum.valuation_map_le_of_valuation_le - theorem
WithZero.lt_one_iff_le_exp_neg_one - theorem
WeierstrassCurve.Affine.valuation_algebraMap_le_one - theorem
WeierstrassCurve.Affine.valuation_algebraMap_eq_one - theorem
WeierstrassCurve.Affine.mem_placeOf_iff - theorem
WeierstrassCurve.Affine.cong_genericX - theorem
WeierstrassCurve.Affine.cong_genericY - theorem
WeierstrassCurve.Affine.algebraMap_evalEval - theorem
WeierstrassCurve.Affine.pointHom_mk_eq_eval₂ - theorem
WeierstrassCurve.Affine.valuation_pointPull_le - theorem
WeierstrassCurve.Affine.valuation_mulPull_le
Source
import Mathlib.AlgebraicGeometry.EllipticCurve.Affine.Point ↗ import Mathlib.RingTheory.DedekindDomain.Dvr ↗ import Mathlib.RingTheory.DedekindDomain.AdicValuation ↗ import Mathlib.RingTheory.DiscreteValuationRing.TFAE ↗ import Mathlib.FieldTheory.IsAlgClosed.Basic ↗ import Mathlib.RingTheory.Ideal.GoingUp ↗ import Mathlib.RingTheory.Localization.FractionRing ↗ import Mathlib.Tactic.FieldSimp ↗ open Polynomial open scoped Polynomial.Bivariate namespace WeierstrassCurve.Affine.CoordinateRing variable {K : Type*} [Field K] {W : Affine K} instance moduleFinite : Module.Finite K[X] W.CoordinateRing := Module.Finite.of_basis (CoordinateRing.basis W) instance isIntegral : Algebra.IsIntegral K[X] W.CoordinateRing := Algebra.IsIntegral.of_finite K[X] W.CoordinateRing theorem algebraMap_eq_mk_C (p : K[X]) : algebraMap K[X] W.CoordinateRing p = mk W (C p) := rfl theorem isMaximal_of_isPrime {P : Ideal W.CoordinateRing} (hP : P ≠ ⊥) [P.IsPrime] : P.IsMaximal := by have hc : (P.comap (algebraMap K[X] W.CoordinateRing)) ≠ ⊥ := fun h => hP (Ideal.eq_bot_of_comap_eq_bot h) haveI : (P.comap (algebraMap K[X] W.CoordinateRing)).IsMaximal := IsPrime.to_maximal_ideal hc exact Ideal.isMaximal_of_isIntegral_of_isMaximal_comap (R := K[X]) P inferInstance theorem exists_comap_eq_span [IsAlgClosed K] {P : Ideal W.CoordinateRing} (hP : P ≠ ⊥) [P.IsPrime] : ∃ a : K, P.comap (algebraMap K[X] W.CoordinateRing) = Ideal.span {X - C a} := by set p := P.comap (algebraMap K[X] W.CoordinateRing) with hp have hp0 : p ≠ ⊥ := fun h => hP (Ideal.eq_bot_of_comap_eq_bot h) haveI : p.IsPrime := Ideal.comap_isPrime _ P haveI hpmax : p.IsMaximal := IsPrime.to_maximal_ideal hp0 set g := Submodule.IsPrincipal.generator p with hg have hgp : Ideal.span {g} = p := Ideal.span_singleton_generator p have hgprime : Prime g := Submodule.IsPrincipal.prime_generator_of_isPrime p hp0 have hdeg : g.degree = 1 := IsAlgClosed.degree_eq_one_of_irreducible K hgprime.irreducible obtain ⟨a, ha⟩ := Polynomial.exists_root_of_degree_eq_one hdeg refine ⟨a, ?_⟩ have hle : p ≤ Ideal.span {X - C a} := by rw [← hgp, Ideal.span_singleton_le_span_singleton] exact ⟨g /ₘ (X - C a), (Polynomial.mul_divByMonic_eq_iff_isRoot.mpr ha).symm⟩ exact (hpmax.eq_of_le (Ideal.span_singleton_ne_top (Polynomial.not_isUnit_X_sub_C a)) hle).symm |>.symm theorem XClass_mem_of_comap_eq {P : Ideal W.CoordinateRing} {a : K} (h : P.comap (algebraMap K[X] W.CoordinateRing) = Ideal.span {X - C a}) : XClass W a ∈ P := by have : X - C a ∈ P.comap (algebraMap K[X] W.CoordinateRing) := by rw [h]; exact Ideal.mem_span_singleton_self _ exact this theorem mk_C_mem_iff {P : Ideal W.CoordinateRing} {a : K} (h : P.comap (algebraMap K[X] W.CoordinateRing) = Ideal.span {X - C a}) (q : K[X]) : mk W (C q) ∈ P ↔ q.IsRoot a := by change q ∈ P.comap (algebraMap K[X] W.CoordinateRing) ↔ _ rw [h, Ideal.mem_span_singleton, Polynomial.dvd_iff_isRoot] theorem XYIdeal_isMaximal {a b : K} (h : W.Equation a b) : (XYIdeal W a (C b)).IsMaximal := by apply Ideal.Quotient.maximal_of_isField exact MulEquiv.isField (Field.toIsField K) (quotientXYIdealEquiv (W' := W) (x := a) (y := C b) h).toMulEquiv theorem algebraMap_quot_apply (P : Ideal W.CoordinateRing) (c : K) : algebraMap K (W.CoordinateRing ⧸ P) c = Ideal.Quotient.mk P (mk W (C (C c))) := rfl theorem algebraMap_quot_eq_comp_eval {P : Ideal W.CoordinateRing} {a : K} (h : P.comap (algebraMap K[X] W.CoordinateRing) = Ideal.span {X - C a}) : algebraMap K[X] (W.CoordinateRing ⧸ P) = (algebraMap K (W.CoordinateRing ⧸ P)).comp (evalRingHom a) := by apply Polynomial.ringHom_ext · intro c simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_C] rfl · simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_X] rw [algebraMap_quot_apply, IsScalarTower.algebraMap_apply K[X] W.CoordinateRing (W.CoordinateRing ⧸ P), Ideal.Quotient.algebraMap_eq, eq_comm, Ideal.Quotient.mk_eq_mk_iff_sub_mem] have : mk W (C (C a)) - algebraMap K[X] W.CoordinateRing X = -XClass W a := by simp only [algebraMap_eq_mk_C, XClass, map_sub]; abel rw [this] exact P.neg_mem (XClass_mem_of_comap_eq h) theorem exists_eq_XYIdeal [IsAlgClosed K] {P : Ideal W.CoordinateRing} (hP : P ≠ ⊥) [P.IsPrime] : ∃ a b : K, W.Equation a b ∧ P = XYIdeal W a (C b) := by obtain ⟨a, ha⟩ := exists_comap_eq_span hP haveI hPmax : P.IsMaximal := isMaximal_of_isPrime hP set L := W.CoordinateRing ⧸ P set π := Ideal.Quotient.mk P have hθ := algebraMap_quot_eq_comp_eval ha haveI : Algebra.IsIntegral K L := ⟨fun z => by obtain ⟨m, hm, hm0⟩ := Algebra.IsIntegral.isIntegral (R := K[X]) z refine ⟨m.map (evalRingHom a), hm.map _, ?_⟩ rw [eval₂_map, ← hθ] exact hm0⟩ obtain ⟨b, hb⟩ := (IsAlgClosed.algebraMap_bijective_of_isIntegral (k := K) (K := L)).2 (π (mk W Y)) have hYmem : YClass W (C b) ∈ P := by rw [YClass, map_sub, ← Ideal.Quotient.mk_eq_mk_iff_sub_mem] exact hb.symm have heq : W.Equation a b := by have hψ : π.comp (mk W) = (algebraMap K L).comp (evalEvalRingHom a b) := by apply Polynomial.ringHom_ext · intro q change algebraMap K[X] L q = _ rw [hθ] simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_C] rfl · simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_X, eval_C] exact hb.symm have h0 : (π.comp (mk W)) W.polynomial = 0 := by rw [RingHom.comp_apply, AdjoinRoot.mk_self, map_zero] rw [hψ, RingHom.comp_apply, coe_evalEvalRingHom, map_eq_zero] at h0 exact h0 refine ⟨a, b, heq, ?_⟩ have hle : XYIdeal W a (C b) ≤ P := by rw [XYIdeal, Ideal.span_le] rintro z (rfl | rfl) · exact XClass_mem_of_comap_eq ha · exact hYmem exact ((XYIdeal_isMaximal heq).eq_of_le hPmax.ne_top hle).symm end WeierstrassCurve.Affine.CoordinateRing namespace WeierstrassCurve.Affine namespace Point variable {S : Type*} [CommRing S] {V : Affine S} def xc : V.Point → S | 0 => 0 | some x _ _ => x def yc : V.Point → S | 0 => 0 | some _ y _ => y @[simp] lemma xc_some {x y : S} (h : V.Nonsingular x y) : (some x y h).xc = x := rfl @[simp] lemma yc_some {x y : S} (h : V.Nonsingular x y) : (some x y h).yc = y := rfl lemma nonsingular_xc_yc {P : V.Point} (hP : P ≠ 0) : V.Nonsingular P.xc P.yc := by rcases P with _ | ⟨x, y, h⟩ · exact absurd rfl hP · exact h lemma eq_some_xc_yc {P : V.Point} (hP : P ≠ 0) : P = some P.xc P.yc (nonsingular_xc_yc hP) := by rcases P with _ | ⟨x, y, h⟩ · exact absurd rfl hP · rfl end Point section Generic variable {R : Type*} [Field R] (W : WeierstrassCurve R) (K : Type*) [Field K] [Algebra R K] noncomputable instance instDecidableEqFunctionField : DecidableEq (W⁄K).FunctionField := Classical.decEq _ noncomputable def genericX : (W⁄K).FunctionField := algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField (CoordinateRing.mk (W⁄K) (C X)) noncomputable def genericY : (W⁄K).FunctionField := algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField (CoordinateRing.mk (W⁄K) Y) theorem evalEval_baseChange_polynomial (x y : (W⁄K).FunctionField) : (W⁄(W⁄K).FunctionField).polynomial.evalEval x y = (W⁄K).polynomial.eval₂ (aeval (R := K) x).toRingHom y := by rw [baseChange_polynomial W (Algebra.ofId K (W⁄K).FunctionField), evalEval, eval_map] have h := hom_eval₂ (W⁄K).polynomial (mapRingHom (Algebra.ofId K (W⁄K).FunctionField : K →+* _)) (evalRingHom x) (C y) simp only [coe_evalRingHom, eval_C] at h rw [h] congr 1 apply Polynomial.ringHom_ext · intro c simp only [RingHom.coe_comp, Function.comp_apply, coe_mapRingHom, map_C, coe_evalRingHom, eval_C, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_C] rfl · simp only [RingHom.coe_comp, Function.comp_apply, coe_mapRingHom, map_X, coe_evalRingHom, eval_X, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_X] theorem algebraMap_comp_of : (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField).comp (AdjoinRoot.of (W⁄K).polynomial) = (aeval (R := K) (genericX W K)).toRingHom := by apply Polynomial.ringHom_ext · intro c simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_C] rw [← AdjoinRoot.algebraMap_eq, ← IsScalarTower.algebraMap_apply] change (algebraMap K[X] (W⁄K).FunctionField) (algebraMap K K[X] c) = _ exact (IsScalarTower.algebraMap_apply K K[X] (W⁄K).FunctionField c).symm · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_X] rfl theorem generic_equation : (W⁄(W⁄K).FunctionField).Equation (genericX W K) (genericY W K) := by rw [Equation, evalEval_baseChange_polynomial, ← algebraMap_comp_of] have h0 := congrArg (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) (AdjoinRoot.eval₂_root (W⁄K).polynomial) rw [map_zero, hom_eval₂] at h0 exact h0 theorem generic_nonsingular [W.IsElliptic] : (W⁄(W⁄K).FunctionField).Nonsingular (genericX W K) (genericY W K) := by haveI : (W⁄(W⁄K).FunctionField).IsElliptic := by dsimp only [Affine.baseChange, WeierstrassCurve.baseChange]; infer_instance exact (equation_iff_nonsingular (W := W⁄(W⁄K).FunctionField)).mp (generic_equation W K) noncomputable def genericPoint [W.IsElliptic] : (W⁄(W⁄K).FunctionField).Point := .some _ _ (generic_nonsingular W K) end Generic section PointHom variable {R : Type*} [Field R] {W : WeierstrassCurve R} {K : Type*} [Field K] [Algebra R K] theorem eval₂_polynomial_of_point (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) : (W⁄K).polynomial.eval₂ (aeval (R := K) Q.xc).toRingHom Q.yc = 0 := by rw [← evalEval_baseChange_polynomial] exact (Point.nonsingular_xc_yc hQ).left noncomputable def pointHom (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) : (W⁄K).CoordinateRing →ₐ[K] (W⁄K).FunctionField := { AdjoinRoot.lift (aeval (R := K) Q.xc).toRingHom Q.yc (eval₂_polynomial_of_point Q hQ) with commutes' := fun c => by simp only [RingHom.toMonoidHom_eq_coe, OneHom.toFun_eq_coe, MonoidHom.toOneHom_coe, MonoidHom.coe_coe] rw [IsScalarTower.algebraMap_apply K (Polynomial K) (W⁄K).CoordinateRing, AdjoinRoot.algebraMap_eq, AdjoinRoot.lift_of, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, Polynomial.algebraMap_apply, aeval_C, Algebra.algebraMap_self, RingHom.id_apply] } theorem pointHom_mk (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (g : (Polynomial K)[X]) : pointHom Q hQ (CoordinateRing.mk (W⁄K) g) = g.eval₂ (aeval (R := K) Q.xc).toRingHom Q.yc := AdjoinRoot.lift_mk (eval₂_polynomial_of_point Q hQ) g @[simp] theorem pointHom_mk_C_C (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (c : K) : pointHom Q hQ (CoordinateRing.mk (W⁄K) (C (C c))) = algebraMap K _ c := (pointHom Q hQ).commutes c @[simp] theorem pointHom_mk_C_X (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) : pointHom Q hQ (CoordinateRing.mk (W⁄K) (C X)) = Q.xc := by rw [pointHom_mk, eval₂_C, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_X] @[simp] theorem pointHom_mk_Y (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) : pointHom Q hQ (CoordinateRing.mk (W⁄K) Y) = Q.yc := by rw [pointHom_mk, eval₂_X] theorem CoordinateRing.algHom_ext' {A : Type*} [Semiring A] [Algebra K A] {f g : (W⁄K).CoordinateRing →ₐ[K] A} (hX : f (CoordinateRing.mk (W⁄K) (C X)) = g (CoordinateRing.mk (W⁄K) (C X))) (hY : f (CoordinateRing.mk (W⁄K) Y) = g (CoordinateRing.mk (W⁄K) Y)) : f = g := by apply AlgHom.coe_ringHom_injective apply Ideal.Quotient.ringHom_ext apply Polynomial.ringHom_ext · intro q change f (CoordinateRing.mk (W⁄K) (C q)) = g (CoordinateRing.mk (W⁄K) (C q)) have hf : (f : (W⁄K).CoordinateRing →+* A).comp ((CoordinateRing.mk (W⁄K)).comp C) = (g : (W⁄K).CoordinateRing →+* A).comp ((CoordinateRing.mk (W⁄K)).comp C) := by apply Polynomial.ringHom_ext · intro c change f (algebraMap K _ c) = g (algebraMap K _ c) rw [AlgHom.commutes, AlgHom.commutes] · exact hX exact RingHom.congr_fun hf q · exact hY theorem pointHom_genericPoint [W.IsElliptic] : pointHom (genericPoint W K) (Point.some_ne_zero _) = IsScalarTower.toAlgHom K (W⁄K).CoordinateRing (W⁄K).FunctionField := by apply CoordinateRing.algHom_ext' · rw [pointHom_mk_C_X, IsScalarTower.coe_toAlgHom', genericPoint, Point.xc_some]; rfl · rw [pointHom_mk_Y, IsScalarTower.coe_toAlgHom', genericPoint, Point.yc_some]; rfl theorem Point.xc_map {F' L' : Type*} [Field F'] [Field L'] [Algebra R F'] [Algebra K F'] [IsScalarTower R K F'] [Algebra R L'] [Algebra K L'] [IsScalarTower R K L'] [DecidableEq F'] [DecidableEq L'] (f : F' →ₐ[K] L') (P : (W⁄F').Point) : (Point.map (W' := W) f P).xc = f P.xc := by cases P with | zero => exact (_root_.map_zero f).symm | some x y h => rfl theorem Point.yc_map {F' L' : Type*} [Field F'] [Field L'] [Algebra R F'] [Algebra K F'] [IsScalarTower R K F'] [Algebra R L'] [Algebra K L'] [IsScalarTower R K L'] [DecidableEq F'] [DecidableEq L'] (f : F' →ₐ[K] L') (P : (W⁄F').Point) : (Point.map (W' := W) f P).yc = f P.yc := by cases P with | zero => exact (_root_.map_zero f).symm | some x y h => rfl theorem pointHom_injective_of_ne_baseChange [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hQK : ∀ P : (W⁄K).Point, Q ≠ Point.baseChange K (W⁄K).FunctionField P) : Function.Injective (pointHom Q hQ) := by rw [injective_iff_map_eq_zero] by_contra hcon push Not at hcon have hker : RingHom.ker (pointHom Q hQ) ≠ ⊥ := by obtain ⟨a, ha, ha0⟩ := hcon intro h have hm : a ∈ RingHom.ker (pointHom Q hQ) := (RingHom.mem_ker).mpr ha rw [h, Ideal.mem_bot] at hm exact ha0 hm haveI : (RingHom.ker (pointHom Q hQ)).IsPrime := RingHom.ker_isPrime _ obtain ⟨a, b, hab, hker'⟩ := CoordinateRing.exists_eq_XYIdeal hker haveI : (W⁄K).IsElliptic := by dsimp only [Affine.baseChange, WeierstrassCurve.baseChange]; infer_instance have hns : (W⁄K).Nonsingular a b := (equation_iff_nonsingular (W := W⁄K)).mp hab have hx : Q.xc = algebraMap K _ a := by have : CoordinateRing.XClass (W⁄K) a ∈ RingHom.ker (pointHom Q hQ) := by rw [hker']; exact Ideal.subset_span (Set.mem_insert _ _) rw [RingHom.mem_ker, CoordinateRing.XClass, map_sub, map_sub, map_sub, pointHom_mk_C_X, pointHom_mk_C_C, sub_eq_zero] at this exact this have hy : Q.yc = algebraMap K _ b := by have : CoordinateRing.YClass (W⁄K) (C b) ∈ RingHom.ker (pointHom Q hQ) := by rw [hker']; exact Ideal.subset_span (Set.mem_insert_of_mem _ rfl) rw [RingHom.mem_ker, CoordinateRing.YClass, map_sub, map_sub, pointHom_mk_Y, pointHom_mk_C_C, sub_eq_zero] at this exact this apply hQK (.some a b hns) rw [Point.eq_some_xc_yc hQ, Point.baseChange, Point.map_some] congr 1 noncomputable def pointPull (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField := IsFractionRing.liftAlgHom hinj @[simp] theorem pointPull_algebraMap (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) (h : (W⁄K).CoordinateRing) : pointPull Q hQ hinj (algebraMap _ _ h) = pointHom Q hQ h := by rw [pointPull, IsFractionRing.liftAlgHom_apply] exact IsFractionRing.lift_algebraMap hinj h theorem map_pointPull_genericPoint [W.IsElliptic] (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) : Point.map (pointPull Q hQ hinj) (genericPoint W K) = Q := by conv_rhs => rw [Point.eq_some_xc_yc hQ] rw [genericPoint, Point.map_some] congr 1 · rw [genericX, pointPull_algebraMap, pointHom_mk_C_X] · rw [genericY, pointPull_algebraMap, pointHom_mk_Y] theorem pointPull_comp_pointHom (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) (P : (W⁄(W⁄K).FunctionField).Point) (hP : P ≠ 0) (hP' : Point.map (pointPull Q hQ hinj) P ≠ 0) : (pointPull Q hQ hinj).comp (pointHom P hP) = pointHom (Point.map (pointPull Q hQ hinj) P) hP' := by apply CoordinateRing.algHom_ext' · rw [AlgHom.comp_apply, pointHom_mk_C_X, pointHom_mk_C_X, Point.xc_map] · rw [AlgHom.comp_apply, pointHom_mk_Y, pointHom_mk_Y, Point.yc_map] theorem pointHom_congr {Q Q' : (W⁄(W⁄K).FunctionField).Point} (h : Q = Q') (hQ : Q ≠ 0) (hQ' : Q' ≠ 0) : pointHom Q hQ = pointHom Q' hQ' := by subst h; rfl theorem pointPull_comp_algebraMap (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) : (pointPull Q hQ hinj : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) = pointHom Q hQ := RingHom.ext fun h => pointPull_algebraMap Q hQ hinj h theorem FunctionField.algHom_ext {φ ψ : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField} (h : (φ : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) = (ψ : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField)) : φ = ψ := AlgHom.coe_ringHom_injective (IsLocalization.ringHom_ext (nonZeroDivisors (W⁄K).CoordinateRing) h) theorem exists_eq_baseChange_of_isIntegral_xc [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hx : _root_.IsIntegral K Q.xc) : ∃ P : (W⁄K).Point, Q = Point.baseChange K (W⁄K).FunctionField P := by haveI : (W⁄K).IsElliptic := by dsimp only [Affine.baseChange, WeierstrassCurve.baseChange]; infer_instance have hdx : (minpoly K Q.xc).degree = 1 := IsAlgClosed.degree_eq_one_of_irreducible K (minpoly.irreducible hx) obtain ⟨a, ha⟩ : Q.xc ∈ (algebraMap K (W⁄K).FunctionField).range := minpoly.mem_range_of_degree_eq_one K _ hdx have heq := (Point.nonsingular_xc_yc hQ).left rw [equation_iff] at heq have hy : _root_.IsIntegral K Q.yc := by refine ⟨X ^ 2 + C ((W⁄K).a₁ * a + (W⁄K).a₃) * X - C (a ^ 3 + (W⁄K).a₂ * a ^ 2 + (W⁄K).a₄ * a + (W⁄K).a₆), ?_, ?_⟩ · have hlt : (C ((W⁄K).a₁ * a + (W⁄K).a₃) * X - C (a ^ 3 + (W⁄K).a₂ * a ^ 2 + (W⁄K).a₄ * a + (W⁄K).a₆) : K[X]).degree < ((X : K[X]) ^ 2).degree := by rw [degree_X_pow] refine (degree_sub_le _ _).trans_lt (max_lt ((degree_C_mul_X_le _).trans_lt ?_) (degree_C_le.trans_lt ?_)) · exact WithBot.coe_lt_coe.mpr (by norm_num) · exact WithBot.coe_lt_coe.mpr (by norm_num) rw [add_sub_assoc] exact (monic_X_pow 2).add_of_left hlt · simp only [eval₂_add, eval₂_sub, eval₂_pow, eval₂_X, eval₂_mul, eval₂_C, map_add, map_mul, map_pow] rw [ha] have e1 : (algebraMap K (W⁄K).FunctionField) (W⁄K).a₁ = (W⁄(W⁄K).FunctionField).a₁ := (IsScalarTower.algebraMap_apply R K (W⁄K).FunctionField W.a₁).symm have e2 : (algebraMap K (W⁄K).FunctionField) (W⁄K).a₂ = (W⁄(W⁄K).FunctionField).a₂ := (IsScalarTower.algebraMap_apply R K (W⁄K).FunctionField W.a₂).symm have e3 : (algebraMap K (W⁄K).FunctionField) (W⁄K).a₃ = (W⁄(W⁄K).FunctionField).a₃ := (IsScalarTower.algebraMap_apply R K (W⁄K).FunctionField W.a₃).symm have e4 : (algebraMap K (W⁄K).FunctionField) (W⁄K).a₄ = (W⁄(W⁄K).FunctionField).a₄ := (IsScalarTower.algebraMap_apply R K (W⁄K).FunctionField W.a₄).symm have e6 : (algebraMap K (W⁄K).FunctionField) (W⁄K).a₆ = (W⁄(W⁄K).FunctionField).a₆ := (IsScalarTower.algebraMap_apply R K (W⁄K).FunctionField W.a₆).symm rw [e1, e2, e3, e4, e6] linear_combination heq have hdy : (minpoly K Q.yc).degree = 1 := IsAlgClosed.degree_eq_one_of_irreducible K (minpoly.irreducible hy) obtain ⟨b, hb⟩ : Q.yc ∈ (algebraMap K (W⁄K).FunctionField).range := minpoly.mem_range_of_degree_eq_one K _ hdy have hab : (W⁄K).Equation a b := by rw [← baseChange_equation W (Algebra.ofId K (W⁄K).FunctionField).injective a b] change (W⁄(W⁄K).FunctionField).Equation (algebraMap K _ a) (algebraMap K _ b) rw [ha, hb] exact (Point.nonsingular_xc_yc hQ).left have hns : (W⁄K).Nonsingular a b := (equation_iff_nonsingular (W := W⁄K)).mp hab refine ⟨.some a b hns, ?_⟩ rw [Point.eq_some_xc_yc hQ, Point.baseChange, Point.map_some] congr 1 <;> [exact ha.symm; exact hb.symm] theorem not_isIntegral_xc_of_ne_baseChange [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hQK : ∀ P : (W⁄K).Point, Q ≠ Point.baseChange K (W⁄K).FunctionField P) : ¬ _root_.IsIntegral K Q.xc := fun hx => by obtain ⟨P, hP⟩ := exists_eq_baseChange_of_isIntegral_xc Q hQ hx; exact hQK P hP end PointHom section TransMul variable {R : Type*} [Field R] (W : WeierstrassCurve R) (K : Type*) [Field K] [Algebra R K] [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] omit [IsAlgClosed K] in theorem genericPoint_ne_baseChange (P : (W⁄K).Point) : genericPoint W K ≠ Point.baseChange K (W⁄K).FunctionField P := by intro h cases P with | zero => exact Point.some_ne_zero _ (h.trans (map_zero _)) | some a b hab => rw [genericPoint, Point.baseChange, Point.map_some, Point.some.injEq] at h apply CoordinateRing.XClass_ne_zero (W' := W⁄K) a apply IsFractionRing.injective (W⁄K).CoordinateRing (W⁄K).FunctionField rw [CoordinateRing.XClass, map_sub, map_sub, map_sub, _root_.map_zero] have h1 : algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField (CoordinateRing.mk (W⁄K) (C X)) = genericX W K := rfl have h2 : algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField (CoordinateRing.mk (W⁄K) (C (C a))) = algebraMap K (W⁄K).FunctionField a := (IsScalarTower.algebraMap_apply K (W⁄K).CoordinateRing (W⁄K).FunctionField a).symm rw [h1, h2, h.1, sub_eq_zero] rfl omit [IsAlgClosed K] in theorem genericPoint_add_baseChange_ne_zero (S : (W⁄K).Point) : genericPoint W K + Point.baseChange K _ S ≠ 0 := by intro h apply genericPoint_ne_baseChange W K (-S) rw [map_neg] exact eq_neg_of_add_eq_zero_left h omit [IsAlgClosed K] in theorem genericPoint_add_baseChange_ne_baseChange (S P : (W⁄K).Point) : genericPoint W K + Point.baseChange K _ S ≠ Point.baseChange K _ P := by intro h apply genericPoint_ne_baseChange W K (P - S) rw [map_sub, ← h, add_sub_cancel_right] theorem transHom_injective (S : (W⁄K).Point) : Function.Injective (pointHom (genericPoint W K + Point.baseChange K _ S) (genericPoint_add_baseChange_ne_zero W K S)) := pointHom_injective_of_ne_baseChange _ _ (genericPoint_add_baseChange_ne_baseChange W K S) noncomputable def transPull (S : (W⁄K).Point) : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField := pointPull _ (genericPoint_add_baseChange_ne_zero W K S) (transHom_injective W K S) theorem map_transPull_genericPoint (S : (W⁄K).Point) : Point.map (transPull W K S) (genericPoint W K) = genericPoint W K + Point.baseChange K _ S := map_pointPull_genericPoint _ _ _ theorem map_transPull_genericPoint_add (S T : (W⁄K).Point) : Point.map (transPull W K S) (genericPoint W K + Point.baseChange K _ T) = genericPoint W K + Point.baseChange K _ (S + T) := by rw [map_add, map_transPull_genericPoint, Point.map_baseChange, add_assoc, ← map_add] theorem transPull_comp_algebraMap (S : (W⁄K).Point) : (transPull W K S : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) = pointHom (genericPoint W K + Point.baseChange K _ S) (genericPoint_add_baseChange_ne_zero W K S) := pointPull_comp_algebraMap _ (genericPoint_add_baseChange_ne_zero W K S) (transHom_injective W K S) theorem transPull_comp_pointHom (S : (W⁄K).Point) (P : (W⁄(W⁄K).FunctionField).Point) (hP : P ≠ 0) (hP' : Point.map (transPull W K S) P ≠ 0) : (transPull W K S).comp (pointHom P hP) = pointHom (Point.map (transPull W K S) P) hP' := pointPull_comp_pointHom _ _ _ P hP hP' theorem transPull_comp_transHom (S T : (W⁄K).Point) : (transPull W K S).comp (pointHom (genericPoint W K + Point.baseChange K _ T) (genericPoint_add_baseChange_ne_zero W K T)) = pointHom (genericPoint W K + Point.baseChange K _ (S + T)) (genericPoint_add_baseChange_ne_zero W K (S + T)) := by apply CoordinateRing.algHom_ext' · rw [AlgHom.comp_apply, pointHom_mk_C_X, pointHom_mk_C_X, ← map_transPull_genericPoint_add, Point.xc_map] · rw [AlgHom.comp_apply, pointHom_mk_Y, pointHom_mk_Y, ← map_transPull_genericPoint_add, Point.yc_map] theorem transPull_comp (S T : (W⁄K).Point) : (transPull W K S).comp (transPull W K T) = transPull W K (S + T) := by apply FunctionField.algHom_ext rw [AlgHom.comp_toRingHom, RingHom.comp_assoc, transPull_comp_algebraMap W K T, transPull_comp_algebraMap W K (S + T), ← AlgHom.comp_toRingHom, transPull_comp_transHom] theorem transPull_zero : transPull W K 0 = AlgHom.id K _ := by apply FunctionField.algHom_ext rw [transPull_comp_algebraMap] have h0 : genericPoint W K + Point.baseChange K (W⁄K).FunctionField (0 : (W⁄K).Point) = genericPoint W K := by rw [map_zero, add_zero] rw [pointHom_congr h0 _ (Point.some_ne_zero _), pointHom_genericPoint] exact RingHom.ext fun x => rfl noncomputable def transEquiv (S : (W⁄K).Point) : (W⁄K).FunctionField ≃ₐ[K] (W⁄K).FunctionField := AlgEquiv.ofAlgHom (transPull W K S) (transPull W K (-S)) (by rw [transPull_comp, add_neg_cancel, transPull_zero]) (by rw [transPull_comp, neg_add_cancel, transPull_zero]) theorem transEquiv_apply (S : (W⁄K).Point) (h : (W⁄K).FunctionField) : transEquiv W K S h = transPull W K S h := rfl theorem coe_transEquiv (S : (W⁄K).Point) : (transEquiv W K S : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField) = transPull W K S := rfl theorem transEquiv_algebraMap (S : (W⁄K).Point) (h : (W⁄K).CoordinateRing) : transEquiv W K S (algebraMap _ _ h) = pointHom (genericPoint W K + Point.baseChange K _ S) (genericPoint_add_baseChange_ne_zero W K S) h := pointPull_algebraMap _ (genericPoint_add_baseChange_ne_zero W K S) (transHom_injective W K S) h theorem transEquiv_genericX (S : (W⁄K).Point) : transEquiv W K S (genericX W K) = (genericPoint W K + Point.baseChange K _ S).xc := by rw [genericX, transEquiv_algebraMap, pointHom_mk_C_X] theorem transEquiv_genericY (S : (W⁄K).Point) : transEquiv W K S (genericY W K) = (genericPoint W K + Point.baseChange K _ S).yc := by rw [genericY, transEquiv_algebraMap, pointHom_mk_Y] theorem map_transEquiv_genericPoint (S : (W⁄K).Point) : Point.map (transEquiv W K S : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField) (genericPoint W K) = genericPoint W K + Point.baseChange K _ S := by rw [coe_transEquiv, map_transPull_genericPoint] theorem transEquiv_add (S T : (W⁄K).Point) : transEquiv W K (S + T) = (transEquiv W K T).trans (transEquiv W K S) := by apply AlgEquiv.ext intro h rw [AlgEquiv.trans_apply, transEquiv_apply, transEquiv_apply, transEquiv_apply, ← AlgHom.comp_apply, transPull_comp] theorem transEquiv_zero : transEquiv W K 0 = AlgEquiv.refl := by apply AlgEquiv.ext intro h rw [transEquiv_apply, transPull_zero] rfl theorem transEquiv_injective : Function.Injective (transEquiv W K) := by intro S T h have hx := transEquiv_genericX W K S have hy := transEquiv_genericY W K S rw [h, transEquiv_genericX] at hx rw [h, transEquiv_genericY] at hy have hpt : genericPoint W K + Point.baseChange K _ T = genericPoint W K + Point.baseChange K _ S := by rw [Point.eq_some_xc_yc (genericPoint_add_baseChange_ne_zero W K T), Point.eq_some_xc_yc (genericPoint_add_baseChange_ne_zero W K S)] congr 1 exact (Point.map_injective _ (add_left_cancel hpt)).symm omit [IsAlgClosed K] in theorem neg_genericPoint_ne_baseChange (P : (W⁄K).Point) : -genericPoint W K ≠ Point.baseChange K (W⁄K).FunctionField P := by intro h apply genericPoint_ne_baseChange W K (-P) rw [map_neg, ← h, neg_neg] theorem negHom_injective : Function.Injective (pointHom (-genericPoint W K) (neg_ne_zero.mpr (Point.some_ne_zero _))) := pointHom_injective_of_ne_baseChange _ _ (neg_genericPoint_ne_baseChange W K) noncomputable def negPull : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField := pointPull _ (neg_ne_zero.mpr (Point.some_ne_zero _)) (negHom_injective W K) theorem map_negPull_genericPoint : Point.map (negPull W K) (genericPoint W K) = -genericPoint W K := map_pointPull_genericPoint _ _ _ theorem negPull_algebraMap (g : (W⁄K).CoordinateRing) : negPull W K (algebraMap _ _ g) = pointHom (-genericPoint W K) (neg_ne_zero.mpr (Point.some_ne_zero _)) g := pointPull_algebraMap _ _ _ g theorem negPull_comp_algebraMap : (negPull W K : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) = pointHom (-genericPoint W K) (neg_ne_zero.mpr (Point.some_ne_zero _)) := pointPull_comp_algebraMap _ _ _ theorem negPull_comp_pointHom (P : (W⁄(W⁄K).FunctionField).Point) (hP : P ≠ 0) (hP' : Point.map (negPull W K) P ≠ 0) : (negPull W K).comp (pointHom P hP) = pointHom (Point.map (negPull W K) P) hP' := pointPull_comp_pointHom _ _ _ P hP hP' theorem negPull_comp_negPull : (negPull W K).comp (negPull W K) = AlgHom.id K _ := by apply FunctionField.algHom_ext have hP' : Point.map (negPull W K) (-genericPoint W K) = genericPoint W K := by rw [map_neg, map_negPull_genericPoint, neg_neg] rw [AlgHom.comp_toRingHom, RingHom.comp_assoc, negPull_comp_algebraMap, ← AlgHom.comp_toRingHom, negPull_comp_pointHom W K _ _ (by rw [hP']; exact Point.some_ne_zero _), pointHom_congr hP' _ (Point.some_ne_zero _), pointHom_genericPoint] exact RingHom.ext fun x => rfl noncomputable def negEquiv : (W⁄K).FunctionField ≃ₐ[K] (W⁄K).FunctionField := AlgEquiv.ofAlgHom (negPull W K) (negPull W K) (negPull_comp_negPull W K) (negPull_comp_negPull W K) theorem coe_negEquiv : (negEquiv W K : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField) = negPull W K := rfl theorem negEquiv_apply (h : (W⁄K).FunctionField) : negEquiv W K h = negPull W K h := rfl theorem map_negEquiv_genericPoint : Point.map (negEquiv W K : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField) (genericPoint W K) = -genericPoint W K := by rw [coe_negEquiv, map_negPull_genericPoint] theorem negEquiv_genericX : negEquiv W K (genericX W K) = genericX W K := by rw [negEquiv_apply, genericX, negPull_algebraMap, pointHom_mk_C_X] simp only [genericPoint, Point.neg_some, Point.xc_some] rfl theorem negEquiv_genericY : negEquiv W K (genericY W K) = (W⁄(W⁄K).FunctionField).negY (genericX W K) (genericY W K) := by rw [negEquiv_apply, genericY, negPull_algebraMap, pointHom_mk_Y] simp only [genericPoint, Point.neg_some, Point.yc_some] rfl theorem negEquiv_symm : (negEquiv W K).symm = negEquiv W K := rfl def MulGood (n : ℤ) : Prop := n • genericPoint W K ≠ 0 ∧ ∀ P : (W⁄K).Point, n • genericPoint W K ≠ Point.baseChange K (W⁄K).FunctionField P theorem mulHom_injective {n : ℤ} (h : MulGood W K n) : Function.Injective (pointHom (n • genericPoint W K) h.1) := pointHom_injective_of_ne_baseChange _ _ h.2 open Classical in noncomputable def mulPull (n : ℤ) : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField := if h : MulGood W K n then pointPull (n • genericPoint W K) h.1 (mulHom_injective W K h) else AlgHom.id K _ theorem mulPull_eq {n : ℤ} (h : MulGood W K n) : mulPull W K n = pointPull (n • genericPoint W K) h.1 (mulHom_injective W K h) := by rw [mulPull, dif_pos h] theorem mulPull_algebraMap {n : ℤ} (h : MulGood W K n) (g : (W⁄K).CoordinateRing) : mulPull W K n (algebraMap _ _ g) = pointHom (n • genericPoint W K) h.1 g := by rw [mulPull_eq W K h, pointPull_algebraMap] theorem mulPull_comp_algebraMap {n : ℤ} (h : MulGood W K n) : (mulPull W K n : (W⁄K).FunctionField →+* (W⁄K).FunctionField).comp (algebraMap (W⁄K).CoordinateRing (W⁄K).FunctionField) = pointHom (n • genericPoint W K) h.1 := RingHom.ext fun g => mulPull_algebraMap W K h g theorem mulPull_genericX' {n : ℤ} (h : MulGood W K n) : mulPull W K n (genericX W K) = (n • genericPoint W K).xc := by rw [genericX, mulPull_algebraMap W K h, pointHom_mk_C_X] theorem mulPull_genericY' {n : ℤ} (h : MulGood W K n) : mulPull W K n (genericY W K) = (n • genericPoint W K).yc := by rw [genericY, mulPull_algebraMap W K h, pointHom_mk_Y] theorem map_mulPull_genericPoint' {n : ℤ} (h : MulGood W K n) : Point.map (mulPull W K n) (genericPoint W K) = n • genericPoint W K := by rw [mulPull_eq W K h, map_pointPull_genericPoint] theorem mulPull_comp_pointHom {n : ℤ} (h : MulGood W K n) (P : (W⁄(W⁄K).FunctionField).Point) (hP : P ≠ 0) (hP' : Point.map (mulPull W K n) P ≠ 0) : (mulPull W K n).comp (pointHom P hP) = pointHom (Point.map (mulPull W K n) P) hP' := by have hP'' : Point.map (pointPull (n • genericPoint W K) h.1 (mulHom_injective W K h)) P ≠ 0 := by rw [← mulPull_eq W K h]; exact hP' rw [pointHom_congr (congrArg (fun φ => Point.map φ P) (mulPull_eq W K h)) hP' hP'', mulPull_eq W K h] exact pointPull_comp_pointHom _ _ _ P hP hP'' theorem transEquiv_mulPull' {n : ℤ} (h : MulGood W K n) {S : (W⁄K).Point} (hS : n • S = 0) (g : (W⁄K).FunctionField) : transEquiv W K S (mulPull W K n g) = mulPull W K n g := by rw [transEquiv_apply, ← AlgHom.comp_apply] congr 1 apply FunctionField.algHom_ext have hP' : Point.map (transPull W K S) (n • genericPoint W K) = n • genericPoint W K := by rw [map_zsmul, map_transPull_genericPoint, smul_add, ← map_zsmul, hS, map_zero, add_zero] rw [AlgHom.comp_toRingHom, RingHom.comp_assoc, mulPull_comp_algebraMap W K h, ← AlgHom.comp_toRingHom, transPull_comp_pointHom W K S _ _ (by rw [hP']; exact h.1)] exact congrArg _ (pointHom_congr hP' _ _) theorem mulPull_comp' {m n : ℤ} (hm : MulGood W K m) (hn : MulGood W K n) (hnm : MulGood W K (n * m)) : (mulPull W K m).comp (mulPull W K n) = mulPull W K (n * m) := by apply FunctionField.algHom_ext have hP' : Point.map (mulPull W K m) (n • genericPoint W K) = (n * m) • genericPoint W K := by rw [map_zsmul, map_mulPull_genericPoint' W K hm, smul_smul] rw [AlgHom.comp_toRingHom, RingHom.comp_assoc, mulPull_comp_algebraMap W K hn, mulPull_comp_algebraMap W K hnm, ← AlgHom.comp_toRingHom, mulPull_comp_pointHom W K hm _ _ (by rw [hP']; exact hnm.1)] exact congrArg _ (pointHom_congr hP' _ _) omit [DecidableEq K] in theorem exists_point_xc_eq (x : K) : ∃ P : (W⁄K).Point, P ≠ 0 ∧ P.xc = x := by haveI : (W⁄K).IsElliptic := by dsimp only [Affine.baseChange, WeierstrassCurve.baseChange]; infer_instance set c := (W⁄K).a₁ * x + (W⁄K).a₃ with hc set d := -(x ^ 3 + (W⁄K).a₂ * x ^ 2 + (W⁄K).a₄ * x + (W⁄K).a₆) with hd have hlt : (C c * X + C d : K[X]).degree < ((X : K[X]) ^ 2).degree := by rw [degree_X_pow] refine (degree_add_le _ _).trans_lt (max_lt ((degree_C_mul_X_le c).trans_lt ?_) (degree_C_le.trans_lt ?_)) · exact WithBot.coe_lt_coe.mpr (by norm_num) · exact WithBot.coe_lt_coe.mpr (by norm_num) have hdeg : ((X : K[X]) ^ 2 + (C c * X + C d)).degree = 2 := by rw [degree_add_eq_left_of_degree_lt hlt, degree_X_pow]; rfl obtain ⟨y, hy⟩ := IsAlgClosed.exists_root ((X : K[X]) ^ 2 + (C c * X + C d)) (by rw [hdeg]; exact two_ne_zero) have hroot : y ^ 2 + (c * y + d) = 0 := by have := hy.eq_zero simpa only [eval_add, eval_pow, eval_X, eval_mul, eval_C] using this have heq : (W⁄K).Equation x y := by rw [equation_iff] rw [hc, hd] at hroot linear_combination hroot exact ⟨.some x y ((equation_iff_nonsingular (W := W⁄K)).mp heq), Point.some_ne_zero _, rfl⟩ omit [DecidableEq K] in theorem infinite_point : Infinite (W⁄K).Point := by choose f hf0 hfx using exists_point_xc_eq W K exact Infinite.of_injective f fun x y h => by rw [← hfx x, ← hfx y, h] theorem map_negEquiv_zsmul_genericPoint (n : ℤ) : Point.map (negEquiv W K : (W⁄K).FunctionField →ₐ[K] (W⁄K).FunctionField) (n • genericPoint W K) = -(n • genericPoint W K) := by rw [map_zsmul, map_negEquiv_genericPoint, smul_neg] theorem negEquiv_mulPull_genericX' {n : ℤ} (h : MulGood W K n) : negEquiv W K (mulPull W K n (genericX W K)) = (n • genericPoint W K).xc := by rw [mulPull_genericX' W K h, ← AlgEquiv.coe_algHom, ← Point.xc_map (W := W) (K := K), map_negEquiv_zsmul_genericPoint, Point.eq_some_xc_yc h.1, Point.neg_some, Point.xc_some, Point.xc_some] theorem negEquiv_mulPull_genericY' {n : ℤ} (h : MulGood W K n) : negEquiv W K (mulPull W K n (genericY W K)) = (W⁄(W⁄K).FunctionField).negY (n • genericPoint W K).xc (n • genericPoint W K).yc := by rw [mulPull_genericY' W K h, ← AlgEquiv.coe_algHom, ← Point.yc_map (W := W) (K := K), map_negEquiv_zsmul_genericPoint] conv_lhs => rw [Point.eq_some_xc_yc h.1, Point.neg_some, Point.yc_some] omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem mulPull_injective [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] (n : ℤ) : Function.Injective (mulPull W K n) := (mulPull W K n).injective end TransMul section Places variable {R : Type*} [Field R] (W : WeierstrassCurve R) (K : Type*) [Field K] [Algebra R K] [DecidableEq K] noncomputable def placeOf (P : (W⁄K).Point) (hP : P ≠ 0) : IsDedekindDomain.HeightOneSpectrum (W⁄K).CoordinateRing where asIdeal := CoordinateRing.XYIdeal (W⁄K) P.xc (C P.yc) isPrime := (CoordinateRing.XYIdeal_isMaximal (Point.nonsingular_xc_yc hP).left).isPrime ne_bot h := CoordinateRing.XClass_ne_zero (W' := W⁄K) P.xc (by rw [← Ideal.mem_bot, ← h]; exact Ideal.subset_span (Set.mem_insert _ _)) omit [DecidableEq K] in @[simp] theorem placeOf_asIdeal (P : (W⁄K).Point) (hP : P ≠ 0) : (placeOf W K P hP).asIdeal = CoordinateRing.XYIdeal (W⁄K) P.xc (C P.yc) := rfl omit [DecidableEq K] in theorem placeOf_surjective [IsAlgClosed K] [W.IsElliptic] (v : IsDedekindDomain.HeightOneSpectrum (W⁄K).CoordinateRing) : ∃ (P : (W⁄K).Point) (hP : P ≠ 0), placeOf W K P hP = v := by haveI : (W⁄K).IsElliptic := by dsimp only [Affine.baseChange, WeierstrassCurve.baseChange]; infer_instance haveI := v.isPrime obtain ⟨a, b, hab, hv⟩ := CoordinateRing.exists_eq_XYIdeal v.ne_bot refine ⟨.some a b ((equation_iff_nonsingular (W := W⁄K)).mp hab), Point.some_ne_zero _, ?_⟩ exact IsDedekindDomain.HeightOneSpectrum.ext hv.symm noncomputable def CoordinateRing.evalAt {a b : K} (h : (W⁄K).Equation a b) : (W⁄K).CoordinateRing →+* K := AdjoinRoot.evalEval h omit [DecidableEq K] in theorem CoordinateRing.evalAt_mk {a b : K} (h : (W⁄K).Equation a b) (g : K[X][Y]) : CoordinateRing.evalAt W K h (CoordinateRing.mk (W⁄K) g) = g.evalEval a b := AdjoinRoot.evalEval_mk h g omit [DecidableEq K] in theorem CoordinateRing.evalAt_XYIdeal {a b : K} (h : (W⁄K).Equation a b) : ∀ g ∈ CoordinateRing.XYIdeal (W⁄K) a (C b), CoordinateRing.evalAt W K h g = 0 := by intro g hg rw [← RingHom.mem_ker] revert hg g rw [← SetLike.le_def, CoordinateRing.XYIdeal, Ideal.span_le] rintro g (rfl | rfl) · rw [SetLike.mem_coe, RingHom.mem_ker, CoordinateRing.XClass, CoordinateRing.evalAt_mk, evalEval_C, eval_sub, eval_X, eval_C, sub_self] · rw [SetLike.mem_coe, RingHom.mem_ker, CoordinateRing.YClass, CoordinateRing.evalAt_mk, evalEval_sub, evalEval_X, evalEval_C, eval_C, sub_self] omit [DecidableEq K] in theorem placeOf_injective {P Q : (W⁄K).Point} (hP : P ≠ 0) (hQ : Q ≠ 0) (h : placeOf W K P hP = placeOf W K Q hQ) : P = Q := by have hI : CoordinateRing.XYIdeal (W⁄K) P.xc (C P.yc) = CoordinateRing.XYIdeal (W⁄K) Q.xc (C Q.yc) := congrArg IsDedekindDomain.HeightOneSpectrum.asIdeal h have hev := CoordinateRing.evalAt_XYIdeal W K (Point.nonsingular_xc_yc hP).left rw [hI] at hev have hx : P.xc = Q.xc := by have := hev _ (Ideal.subset_span (Set.mem_insert _ _)) rw [CoordinateRing.XClass, CoordinateRing.evalAt_mk, evalEval_C, eval_sub, eval_X, eval_C, sub_eq_zero] at this exact this have hy : P.yc = Q.yc := by have := hev _ (Ideal.subset_span (Set.mem_insert_of_mem _ rfl)) rw [CoordinateRing.YClass, CoordinateRing.evalAt_mk, evalEval_sub, evalEval_X, evalEval_C, eval_C, sub_eq_zero] at this exact this rw [Point.eq_some_xc_yc hP, Point.eq_some_xc_yc hQ] congr 1 end Places end WeierstrassCurve.Affine open Polynomial namespace Valuation variable {L : Type*} [CommRing L] {Γ₀ : Type*} [LinearOrderedCommGroupWithZero Γ₀] (v : Valuation L Γ₀) def Cong (a b : L) : Prop := v (a - b) < 1 variable {v} theorem cong_iff {a b : L} : v.Cong a b ↔ v (a - b) < 1 := Iff.rfl @[refl] theorem Cong.refl (a : L) : v.Cong a a := by simp [Cong] theorem Cong.rfl {a : L} : v.Cong a a := Cong.refl a @[symm] theorem Cong.symm {a b : L} (h : v.Cong a b) : v.Cong b a := by rw [Cong, ← Valuation.map_neg, neg_sub]; exact h theorem Cong.trans {a b c : L} (h₁ : v.Cong a b) (h₂ : v.Cong b c) : v.Cong a c := by have : a - c = (a - b) + (b - c) := by ring rw [Cong, this] exact (v.map_add _ _).trans_lt (max_lt h₁ h₂) theorem Cong.add {a b a' b' : L} (h₁ : v.Cong a a') (h₂ : v.Cong b b') : v.Cong (a + b) (a' + b') := by have : a + b - (a' + b') = (a - a') + (b - b') := by ring rw [Cong, this] exact (v.map_add _ _).trans_lt (max_lt h₁ h₂) theorem Cong.neg {a a' : L} (h : v.Cong a a') : v.Cong (-a) (-a') := by have : -a - -a' = -(a - a') := by ring rw [Cong, this, Valuation.map_neg]; exact h theorem Cong.sub {a b a' b' : L} (h₁ : v.Cong a a') (h₂ : v.Cong b b') : v.Cong (a - b) (a' - b') := by rw [sub_eq_add_neg, sub_eq_add_neg]; exact h₁.add h₂.neg theorem Cong.le_one {a a' : L} (h : v.Cong a a') (ha' : v a' ≤ 1) : v a ≤ 1 := by have : a = (a - a') + a' := by ring rw [this] exact (v.map_add _ _).trans (max_le h.le ha') theorem Cong.mul {a b a' b' : L} (h₁ : v.Cong a a') (h₂ : v.Cong b b') (ha' : v a' ≤ 1) (hb' : v b' ≤ 1) : v.Cong (a * b) (a' * b') := by have ha : v a ≤ 1 := h₁.le_one ha' have : a * b - a' * b' = a * (b - b') + (a - a') * b' := by ring rw [Cong, this] refine (v.map_add _ _).trans_lt (max_lt ?_ ?_) · rw [Valuation.map_mul] calc v a * v (b - b') ≤ 1 * v (b - b') := mul_le_mul' ha le_rfl _ < 1 := by rw [one_mul]; exact h₂ · rw [Valuation.map_mul] calc v (a - a') * v b' ≤ v (a - a') * 1 := mul_le_mul' le_rfl hb' _ < 1 := by rw [mul_one]; exact h₁ theorem Cong.pow {a a' : L} (h : v.Cong a a') (ha' : v a' ≤ 1) (n : ℕ) : v.Cong (a ^ n) (a' ^ n) := by induction n with | zero => simp only [pow_zero]; exact Cong.rfl | succ n ih => rw [pow_succ, pow_succ] exact ih.mul h (by rw [Valuation.map_pow]; exact pow_le_one' ha' n) ha' theorem Cong.eq_of_eq_one {a a' : L} (h : v.Cong a a') (ha' : v a' = 1) : v a = 1 := by have : a = a' + (a - a') := by ring rw [this, Valuation.map_add_eq_of_lt_left] · exact ha' · rw [ha']; exact h theorem Cong.lt_one_iff {a a' : L} (h : v.Cong a a') : v a < 1 ↔ v a' < 1 := by constructor · intro ha have : a' = a - (a - a') := by ring rw [this] exact (v.map_sub _ _).trans_lt (max_lt ha h) · intro ha' have : a = (a - a') + a' := by ring rw [this] exact (v.map_add _ _).trans_lt (max_lt h ha') theorem cong_zero_iff {a : L} : v.Cong a 0 ↔ v a < 1 := by rw [Cong, sub_zero] section Field variable {F : Type*} [Field F] {Γ : Type*} [LinearOrderedCommGroupWithZero Γ] {w : Valuation F Γ} theorem Cong.inv {d d' : F} (h : w.Cong d d') (hd' : w d' = 1) : w.Cong d⁻¹ d'⁻¹ := by have hd : w d = 1 := h.eq_of_eq_one hd' have hd0 : d ≠ 0 := fun h0 => by rw [h0, Valuation.map_zero] at hd; exact zero_ne_one hd have hd0' : d' ≠ 0 := fun h0 => by rw [h0, Valuation.map_zero] at hd'; exact zero_ne_one hd' have : d⁻¹ - d'⁻¹ = -(d - d') * (d⁻¹ * d'⁻¹) := by field_simp ring rw [Cong, this, Valuation.map_mul, Valuation.map_neg, Valuation.map_mul, map_inv₀, map_inv₀, hd, hd', inv_one, mul_one, mul_one] exact h theorem Cong.div {a d a' d' : F} (h₁ : w.Cong a a') (h₂ : w.Cong d d') (ha' : w a' ≤ 1) (hd' : w d' = 1) : w.Cong (a / d) (a' / d') := by rw [div_eq_mul_inv, div_eq_mul_inv] exact h₁.mul (h₂.inv hd') ha' (by rw [map_inv₀, hd', inv_one]) end Field section Eval variable {K : Type*} [CommRing K] (f : K →+* L) theorem Cong.eval₂ (hf : ∀ c, v (f c) ≤ 1) {a a' : L} (h : v.Cong a a') (ha' : v a' ≤ 1) (p : K[X]) : v.Cong (p.eval₂ f a) (p.eval₂ f a') ∧ v (p.eval₂ f a') ≤ 1 := by induction p using Polynomial.induction_on' with | add p q hp hq => rw [eval₂_add, eval₂_add] exact ⟨hp.1.add hq.1, (v.map_add _ _).trans (max_le hp.2 hq.2)⟩ | monomial n c => rw [eval₂_monomial, eval₂_monomial] have hpow : v (a' ^ n) ≤ 1 := by rw [Valuation.map_pow]; exact pow_le_one' ha' n exact ⟨(Cong.refl (f c)).mul (h.pow ha' n) (hf c) hpow, by rw [Valuation.map_mul]; exact mul_le_one' (hf c) hpow⟩ theorem Cong.eval₂_eval₂ (hf : ∀ c, v (f c) ≤ 1) {a a' b b' : L} (ha : v.Cong a a') (ha' : v a' ≤ 1) (hb : v.Cong b b') (hb' : v b' ≤ 1) (p : K[X][X]) : v.Cong (p.eval₂ (eval₂RingHom f a) b) (p.eval₂ (eval₂RingHom f a') b') ∧ v (p.eval₂ (eval₂RingHom f a') b') ≤ 1 := by induction p using Polynomial.induction_on' with | add p q hp hq => rw [eval₂_add, eval₂_add] exact ⟨hp.1.add hq.1, (v.map_add _ _).trans (max_le hp.2 hq.2)⟩ | monomial n q => rw [eval₂_monomial, eval₂_monomial, coe_eval₂RingHom, coe_eval₂RingHom] have hq := Cong.eval₂ f hf ha ha' q have hpow : v (b' ^ n) ≤ 1 := by rw [Valuation.map_pow]; exact pow_le_one' hb' n exact ⟨hq.1.mul (hb.pow hb' n) hq.2 hpow, by rw [Valuation.map_mul]; exact mul_le_one' hq.2 hpow⟩ end Eval end Valuation open IsDedekindDomain IsDedekindDomain.HeightOneSpectrum WithZero namespace IsDedekindDomain.HeightOneSpectrum variable {R : Type*} [CommRing R] [IsDedekindDomain R] {K : Type*} [Field K] [Algebra R K] [IsFractionRing R K] {R' : Type*} [CommRing R'] [IsDedekindDomain R'] {K' : Type*} [Field K'] [Algebra R' K'] [IsFractionRing R' K'] omit [IsDedekindDomain R] [IsFractionRing R K] in theorem valuation_map_le_exp_neg_of_mem_pow (ψ : K →+* K') (w : HeightOneSpectrum R) (v : HeightOneSpectrum R') (h0 : ∀ b : R, v.valuation K' (ψ (algebraMap R K b)) ≤ 1) (h1 : ∀ b : R, b ∈ w.asIdeal → v.valuation K' (ψ (algebraMap R K b)) ≤ exp (-1 : ℤ)) (m : ℕ) : ∀ a ∈ w.asIdeal ^ m, v.valuation K' (ψ (algebraMap R K a)) ≤ exp (-(m : ℤ)) := by induction m with | zero => intro a _ rw [Nat.cast_zero, neg_zero, exp_zero] exact h0 a | succ m ih => intro a ha rw [pow_succ'] at ha refine Submodule.mul_induction_on ha ?_ ?_ · intro c hc a' ha' rw [map_mul, map_mul, map_mul, Nat.cast_succ, neg_add, add_comm, exp_add] exact mul_le_mul' (h1 c hc) (ih a' ha') · intro z₁ z₂ hz₁ hz₂ rw [map_add, map_add] exact (Valuation.map_add _ _ _).trans (max_le hz₁ hz₂) theorem valuation_map_le_of_valuation_le (ψ : K →+* K') (w : HeightOneSpectrum R) (v : HeightOneSpectrum R') (h1 : ∀ b : R, b ∈ w.asIdeal → v.valuation K' (ψ (algebraMap R K b)) ≤ exp (-1 : ℤ)) (h2 : ∀ b : R, b ∉ w.asIdeal → v.valuation K' (ψ (algebraMap R K b)) = 1) (x : K) (k : ℕ) (hx : w.valuation K x ≤ exp (-(k : ℤ))) : v.valuation K' (ψ x) ≤ exp (-(k : ℤ)) := by have h0 : ∀ b : R, v.valuation K' (ψ (algebraMap R K b)) ≤ 1 := by intro b by_cases hb : b ∈ w.asIdeal · exact (h1 b hb).trans (by rw [← exp_zero, exp_le_exp]; norm_num) · exact (h2 b hb).le have hx1 : w.valuation K x ≤ 1 := hx.trans (by rw [← exp_zero, exp_le_exp, neg_nonpos]; exact Nat.cast_nonneg k) obtain ⟨n, d, hnd⟩ := exists_primeCompl_mul_eq_of_integer (v := w) x hx1 have hd : (d : R) ∉ w.asIdeal := d.2 have hwn : w.valuation K (algebraMap R K n) ≤ exp (-(k : ℤ)) := by rw [← hnd, map_mul, (valuation_eq_one_iff_notMem (K := K) w).mpr hd, mul_one] exact hx rw [valuation_of_algebraMap, intValuation_le_pow_iff_mem] at hwn have hψn := valuation_map_le_exp_neg_of_mem_pow ψ w v h0 h1 k n hwn have := congrArg (fun t => v.valuation K' (ψ t)) hnd simp only [map_mul, h2 d hd, mul_one] at this rw [this] exact hψn end IsDedekindDomain.HeightOneSpectrum namespace WeierstrassCurve.Affine open IsDedekindDomain IsDedekindDomain.HeightOneSpectrum WithZero Polynomial section Transport variable {R : Type*} [Field R] (W : WeierstrassCurve R) (K : Type*) [Field K] [Algebra R K] [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] [IsDedekindDomain (W⁄K).CoordinateRing] theorem _root_.WithZero.lt_one_iff_le_exp_neg_one {y : ℤᵐ⁰} : y < 1 ↔ y ≤ exp (-1 : ℤ) := by by_cases hy : y = 0 · subst hy; simp · rw [← exp_log hy, ← exp_zero, exp_lt_exp, exp_le_exp]; omega omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem valuation_algebraMap_le_one (P : (W⁄K).Point) (hP : P ≠ 0) (c : K) : (placeOf W K P hP).valuation (W⁄K).FunctionField (algebraMap K (W⁄K).FunctionField c) ≤ 1 := by rw [IsScalarTower.algebraMap_apply K (W⁄K).CoordinateRing (W⁄K).FunctionField] exact valuation_le_one _ _ omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem valuation_algebraMap_eq_one (P : (W⁄K).Point) (hP : P ≠ 0) {c : K} (hc : c ≠ 0) : (placeOf W K P hP).valuation (W⁄K).FunctionField (algebraMap K (W⁄K).FunctionField c) = 1 := by apply le_antisymm (valuation_algebraMap_le_one W K P hP c) have h := valuation_algebraMap_le_one W K P hP c⁻¹ rw [map_inv₀, map_inv₀, inv_le_one₀] at h · exact h · rw [Valuation.pos_iff] exact (_root_.map_ne_zero _).mpr hc omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] [IsDedekindDomain (W⁄K).CoordinateRing] in theorem mem_placeOf_iff (P : (W⁄K).Point) (hP : P ≠ 0) (b : (W⁄K).CoordinateRing) : b ∈ (placeOf W K P hP).asIdeal ↔ CoordinateRing.evalAt W K (Point.nonsingular_xc_yc hP).left b = 0 := by constructor · exact CoordinateRing.evalAt_XYIdeal W K _ b · intro hb have hker : RingHom.ker (CoordinateRing.evalAt W K (Point.nonsingular_xc_yc hP).left) = (placeOf W K P hP).asIdeal := by refine ((CoordinateRing.XYIdeal_isMaximal (Point.nonsingular_xc_yc hP).left).eq_of_le (RingHom.ker_ne_top _) ?_).symm intro g hg exact (RingHom.mem_ker).mpr (CoordinateRing.evalAt_XYIdeal W K _ g hg) rw [← hker] exact (RingHom.mem_ker).mpr hb omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem cong_genericX (P : (W⁄K).Point) (hP : P ≠ 0) : ((placeOf W K P hP).valuation (W⁄K).FunctionField).Cong (genericX W K) (algebraMap K (W⁄K).FunctionField P.xc) := by rw [Valuation.cong_iff, IsScalarTower.algebraMap_apply K (W⁄K).CoordinateRing (W⁄K).FunctionField, genericX, ← map_sub] apply (valuation_lt_one_iff_mem _ _).mpr rw [placeOf_asIdeal] have : CoordinateRing.mk (W⁄K) (C X) - algebraMap K (W⁄K).CoordinateRing P.xc = CoordinateRing.XClass (W⁄K) P.xc := by rw [CoordinateRing.XClass, map_sub, map_sub]; rfl rw [this] exact Ideal.subset_span (Set.mem_insert _ _) omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem cong_genericY (P : (W⁄K).Point) (hP : P ≠ 0) : ((placeOf W K P hP).valuation (W⁄K).FunctionField).Cong (genericY W K) (algebraMap K (W⁄K).FunctionField P.yc) := by rw [Valuation.cong_iff, IsScalarTower.algebraMap_apply K (W⁄K).CoordinateRing (W⁄K).FunctionField, genericY, ← map_sub] apply (valuation_lt_one_iff_mem _ _).mpr rw [placeOf_asIdeal] have : CoordinateRing.mk (W⁄K) Y - algebraMap K (W⁄K).CoordinateRing P.yc = CoordinateRing.YClass (W⁄K) (C P.yc) := by rw [CoordinateRing.YClass, map_sub]; rfl rw [this] exact Ideal.subset_span (Set.mem_insert_of_mem _ rfl) omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] [IsDedekindDomain (W⁄K).CoordinateRing] in theorem algebraMap_evalEval (g : K[X][Y]) (a b : K) : algebraMap K (W⁄K).FunctionField (g.evalEval a b) = g.eval₂ (eval₂RingHom (algebraMap K (W⁄K).FunctionField) (algebraMap K _ a)) (algebraMap K _ b) := by have hφ : (algebraMap K (W⁄K).FunctionField).comp (evalEvalRingHom a b) = eval₂RingHom (eval₂RingHom (algebraMap K (W⁄K).FunctionField) (algebraMap K _ a)) (algebraMap K _ b) := by apply Polynomial.ringHom_ext · intro q simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_C, coe_eval₂RingHom, eval₂_C, eval₂_at_apply] · simp only [RingHom.coe_comp, Function.comp_apply, coe_evalRingHom, eval_X, eval_C, coe_eval₂RingHom, eval₂_X] exact RingHom.congr_fun hφ g omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] [IsDedekindDomain (W⁄K).CoordinateRing] in theorem pointHom_mk_eq_eval₂ (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (g : K[X][Y]) : pointHom Q hQ (CoordinateRing.mk (W⁄K) g) = g.eval₂ (eval₂RingHom (algebraMap K (W⁄K).FunctionField) Q.xc) Q.yc := by rw [pointHom_mk] congr 1 omit [DecidableEq K] [IsAlgClosed K] [W.IsElliptic] in theorem valuation_pointPull_le (Q : (W⁄(W⁄K).FunctionField).Point) (hQ : Q ≠ 0) (hinj : Function.Injective (pointHom Q hQ)) {P : (W⁄K).Point} (hP : P ≠ 0) {P' : (W⁄K).Point} (hP' : P' ≠ 0) (hx : ((placeOf W K P hP).valuation (W⁄K).FunctionField).Cong Q.xc (algebraMap K _ P'.xc)) (hy : ((placeOf W K P hP).valuation (W⁄K).FunctionField).Cong Q.yc (algebraMap K _ P'.yc)) (h : (W⁄K).FunctionField) (k : ℕ) (hh : (placeOf W K P' hP').valuation (W⁄K).FunctionField h ≤ exp (-(k : ℤ))) : (placeOf W K P hP).valuation (W⁄K).FunctionField (pointPull Q hQ hinj h) ≤ exp (-(k : ℤ)) := by set v := (placeOf W K P hP).valuation (W⁄K).FunctionField with hv have hc : ∀ g : K[X][Y], v.Cong (pointHom Q hQ (CoordinateRing.mk (W⁄K) g)) (algebraMap K _ (g.evalEval P'.xc P'.yc)) := by intro g rw [pointHom_mk_eq_eval₂, algebraMap_evalEval] exact (Valuation.Cong.eval₂_eval₂ (v := v) (algebraMap K _) (valuation_algebraMap_le_one W K P hP) hx (valuation_algebraMap_le_one W K P hP _) hy (valuation_algebraMap_le_one W K P hP _) g).1 refine valuation_map_le_of_valuation_le (pointPull Q hQ hinj : (W⁄K).FunctionField →+* (W⁄K).FunctionField) (placeOf W K P' hP') (placeOf W K P hP) ?_ ?_ h k hh · intro b hb obtain ⟨g, rfl⟩ := Ideal.Quotient.mk_surjective b change v (pointPull Q hQ hinj (algebraMap _ _ (CoordinateRing.mk (W⁄K) g))) ≤ _ rw [pointPull_algebraMap, ← lt_one_iff_le_exp_neg_one, ← Valuation.cong_zero_iff] have h0 : g.evalEval P'.xc P'.yc = 0 := by rw [← CoordinateRing.evalAt_mk W K (Point.nonsingular_xc_yc hP').left] exact (mem_placeOf_iff W K P' hP' _).mp hb simpa only [h0, map_zero] using hc g · intro b hb obtain ⟨g, rfl⟩ := Ideal.Quotient.mk_surjective b change v (pointPull Q hQ hinj (algebraMap _ _ (CoordinateRing.mk (W⁄K) g))) = 1 rw [pointPull_algebraMap] have h0 : g.evalEval P'.xc P'.yc ≠ 0 := by rw [← CoordinateRing.evalAt_mk W K (Point.nonsingular_xc_yc hP').left] exact fun h => hb ((mem_placeOf_iff W K P' hP' _).mpr h) exact (hc g).eq_of_eq_one (valuation_algebraMap_eq_one W K P hP h0) theorem valuation_mulPull_le {n : ℤ} (hgood : MulGood W K n) (Φ Ψ : K[X]) (ω ψ : K[X][Y]) (hξ : (n • genericPoint W K).xc = Φ.eval₂ (algebraMap K (W⁄K).FunctionField) (genericX W K) / Ψ.eval₂ (algebraMap K (W⁄K).FunctionField) (genericX W K)) (hη : (n • genericPoint W K).yc = ω.eval₂ (eval₂RingHom (algebraMap K (W⁄K).FunctionField) (genericX W K)) (genericY W K) / ψ.eval₂ (eval₂RingHom (algebraMap K (W⁄K).FunctionField) (genericX W K)) (genericY W K) ^ 3) {P : (W⁄K).Point} (hP : P ≠ 0) (hnP : n • P ≠ 0) (hxP : (n • P).xc = Φ.eval P.xc / Ψ.eval P.xc) (hΨ : Ψ.eval P.xc ≠ 0) (hyP : (n • P).yc = ω.evalEval P.xc P.yc / ψ.evalEval P.xc P.yc ^ 3) (hψ : ψ.evalEval P.xc P.yc ≠ 0) (h : (W⁄K).FunctionField) (k : ℕ) (hh : (placeOf W K (n • P) hnP).valuation (W⁄K).FunctionField h ≤ exp (-(k : ℤ))) : (placeOf W K P hP).valuation (W⁄K).FunctionField (mulPull W K n h) ≤ exp (-(k : ℤ)) := by set v := (placeOf W K P hP).valuation (W⁄K).FunctionField with hv have hc1 := valuation_algebraMap_le_one W K P hP have hX := cong_genericX W K P hP have hY := cong_genericY W K P hP have hx : v.Cong (n • genericPoint W K).xc (algebraMap K _ (n • P).xc) := by rw [hξ, hxP, map_div₀, ← eval₂_at_apply, ← eval₂_at_apply] have hΦ := Valuation.Cong.eval₂ (v := v) (algebraMap K _) hc1 hX (hc1 _) Φ have hΨc := Valuation.Cong.eval₂ (v := v) (algebraMap K _) hc1 hX (hc1 _) Ψ refine hΦ.1.div hΨc.1 hΦ.2 ?_ rw [eval₂_at_apply] exact valuation_algebraMap_eq_one W K P hP hΨ have hy : v.Cong (n • genericPoint W K).yc (algebraMap K _ (n • P).yc) := by rw [hη, hyP, map_div₀, map_pow, algebraMap_evalEval, algebraMap_evalEval] have hω := Valuation.Cong.eval₂_eval₂ (v := v) (algebraMap K _) hc1 hX (hc1 _) hY (hc1 _) ω have hψc := Valuation.Cong.eval₂_eval₂ (v := v) (algebraMap K _) hc1 hX (hc1 _) hY (hc1 _) ψ refine hω.1.div (hψc.1.pow hψc.2 3) hω.2 ?_ rw [← algebraMap_evalEval, ← map_pow] exact valuation_algebraMap_eq_one W K P hP (pow_ne_zero 3 hψ) rw [mulPull_eq W K hgood] exact valuation_pointPull_le W K _ _ _ hP hnP hx hy h k hh end Transport end WeierstrassCurve.Affine
Statements phrased using this module (10)
- Invariant function with divisor on an [n]-fibre forces T=0
WeierstrassCurve.Affine.eq_zero_of_forall_transEquiv_eq13 below · depth 8 - Valuations along the multiplication-by-n pull-back of functions
WeierstrassCurve.Affine.valuation_mulPull_le_of_ne_zero4 below · depth 8 - Maximality of the point ideal at an affine point
WeierstrassCurve.Affine.CoordinateRing.XYIdeal_isMaximal0 below · depth 9 - Nonzero primes of a Weierstrass coordinate ring are points
WeierstrassCurve.Affine.CoordinateRing.exists_eq_XYIdeal0 below · depth 9 - Pull-back by [n] has index at most n²
WeierstrassCurve.Affine.finrank_fieldRange_mulPull_le8 below · depth 9 - No nonzero multiple of the generic point is constant
WeierstrassCurve.Affine.zsmul_genericPoint_good1 below · depth 9 - Translation by S moves the place at infinity to -S
WeierstrassCurve.Affine.valuation_placeOf_neg_transEquiv_algebraMap2 below · depth 10 - Galois equivariance of the valuations v_P on K(E)
WeierstrassCurve.Affine.valuation_placeOf_smul_of_algEquiv0 below · depth 10 - Translation pull-back does not decrease order of vanishing
WeierstrassCurve.Affine.valuation_transEquiv_le0 below · depth 10 - Translation pull-back carries vanishing at 2S to S
WeierstrassCurve.Affine.valuation_transEquiv_le_self0 below · depth 10